JavaScript Challenge #1 : Splitting an Army
Tags: javascript, tutorial, programming, beginners
Published: 2022-03-30 00:26:59

In this first series of articles I'm writing, I will take any fun challenge that I find anywhere, such as websites, daily life or even video games and try solving them using JavaScript. You can totally try solving them yourself, as I will provide boilerplates for each challenge, and your solution could actually be better than mine. All you need is a basic knowledge in JavaScript and Vue

So in this first challenge, as the title suggests, is splitting an army evenly into two lesser armies. What do you mean by army? It's pretty simple
I was playing a grand strategy game called Victoria II, where you are in charge of the government of a nation during the Victorian era (of course). However, one thing is bothering me. The feature to split the army doesn't work properly!

This single army has 10 infantry regiments, 2 hussar regiments, 2 engineer regiments and 8 artillery regiments

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/353qc75phc6rc9pg7bzd.png)

After I split it, they became this

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kzspr1rkonzwkii174su.png)

one army has two engineer regiments, one less infantry regiments. The other one will be in for a hard time because they cannot make any defenses if the enemy launch an assault against them!

## The Challenge
Let's fix this problem ourselves. We want to make a JavaScript code that will take an object with properties defining the numbers of each regiment and split it evenly. here is the specifics:

1. take and army object 
2. return an array of two objects that resulted from the splitting
3. all regiments should number in integer, we don't want a half strength regiment do we?

## Starter Code
Feel free to copy this code and start solving the problem first. This codes contain barebone UI for inputting and outputting data

## HTML
code for index.html
```html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js" defer></script>
    <script src="./main.js" defer></script>
    <link rel="stylesheet" href="./styles.css">
    <title>Splitter</title>
</head>
<body>
    <div id="app">
        <form @submit.prevent="split()">
            <label for="infantry">Infantry</label>
            <br>
            <input type="number" v-model.number="infantry" id="infantry">
            <br>
            <label for="artillery" >Artillery</label>
            <br>
            <input type="number" name="" v-model.number="artillery" id="artillery">
            <br>
            <label for="engineer">Engineer</label>
            <br>
            <input type="number" name="" v-model.number="engineer" id="engineer">
            <br>
            <label for="hussar">Hussar</label>
            <br>
            <input type="number" name="" v-model.number="hussar" id="hussar">
            <br>
            <input type="submit" value="SPLIT">
        </form>
        <div id="output">
            <div v-for="(army, index) in armies" class="army-card">
                <h4>{{'Army ' + index}}</h4>
                <ul>
                    <li v-for="(val, key) in army"> {{val + ' ' + key}} </li>
                </ul>
            </div>
        </div>
    </div>
</body>
</html>
```

## CSS
code for styles.css
```CSS
* {
    box-sizing: border-box;
}

#output{
    display: flex;
    gap: 16px;
}

.army-card{
    border: 1px solid black;
    padding: 8px;
    text-align: left;
    display: inline;
}
```

## JavaScript
code for main.js
You can just work on the split method, all other functionalities has been taken care of
```javascript
//this is the code for view and submit event
var app =  new Vue({
    el: "#app",
    data: {
        infantry: 0,
        artillery: 0,
        engineer: 0,
        hussar: 0,
        army: null, //use this.army to get the inputted army
        armies: [] //use this.armies to store the result
    },
    methods: {
        
        split: function() {
            this.formArmy()
            //your code here
            
            


        },
        //this is for constructing an army object based on input from the form
        formArmy: function() {
            let infantry = this.infantry;
            let artillery = this.artillery;
            let engineer = this.engineer;
            let hussar = this.hussar;
            this.army = {
                infantry,
                artillery,
                engineer,
                hussar
            }
            console.table(this.army);
        }
    }
})
```
## Solution
There is only three cases we need to take into account. Is the number odd? even? is the army will be empty? and react accordingly. We use object looping to move the regiments between the two new armies
```javascript
split: function() {
            this.formArmy()
            //your code here
            let army1 = {};
            let army2 = {};
            //loop trough each values in object and attempt to divide
            for (key in this.army) {
                let regiments = this.army[key];
                if (regiments < 2) { //if impossible to divide
                    army1[key] = regiments;
                    army2[key] = 0;
                }
                else if (regiments % 2 === 0) { //if a type of regiments are even
                    army1[key] = regiments / 2;
                    army2[key] = regiments / 2;
                }
                else if (regiments % 2 !== 0) { //if the regiments numbered odd
                    
                    army1[key] = (regiments + 1) / 2;
                    army2[key] = (regiments - army1[key]);//army 2 get the remnants
                    
                }
                
            }
            let army2Sum = 0;
            for (key in army2) {
                army2Sum += army2[key];
            }
            this.armies = [army1];
            //push army2 if not all its units is 0
            if (army2Sum !== 0){
                this.armies.push(army2);
            }
```
The result:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cf93wms86cgt4ao16nw2.png)
That's it! GG, now you know how to split an army if you ever decided to make an RTS game or you are in charge of an army. Thanks for reading :)