0

I made two function factories, one for zombies, one for humans. I want to have a function that takes the difference between the total zombie health versus total human attack. It works with one each, but I cant wrap my head around how to do multiple humans versus zombies. I have tried pushing the human objects to an array so that I could sum all the attack(i would repeat for zombies), but no luck...

//Create a Human spawning object
var humanArr = [];
const humanSpawns = (attack) => {
    let human = {
        attack: attack
    };
    humanArr.push(human);
};


//Create a Zombie spawning object
const zombieSpawns = (health) => {
    return {
        health: health
    }
};


//Create function to have humans and zombies fight
function fight() {
   var result = humanOne.attack - zombieOne.health;
   if(result > 0) {
       document.write('Live to see another day.');
   } else {
       document.write('The zombies are taking over!');
   }
}

const zombieOne = zombieSpawns(12);
const humanOne = humanSpawns(11);
fight();
Joe cool
  • 51
  • 6

1 Answers1

2

Try something similar to my snippet, what you really need is a method to create units. I used plain objects, but if you want to return casualties let's say, you would need to return an array of humanoids per main object, and splice them in battle based on the incoming damage. Take it easy, you'll get to see your armies fight!

The logic i pursued:

  1. I need an army !

    1.1. To create an army, first i need some units, so i build createHumanoid (should have renamed this to createArmy)

    1.2. createHumanoid will help set some properties for the units and how many of them will be in my army.

  2. Create an armies array, where i will create my armies using createHumanoid

  3. I needed to know how strong is the army so i build getArmyPower that returns the name and power of an army, this will be used in 4.2. .

  4. The battle begins ! (favoriteArmy = 'humans')

    4.1. fight method is being created and takes two parameters, first is armies, second is favoriteArmy

    4.2. Using .map method i apply getArmyPower to each of my armies(elements of the array) to know their power

    4.3. Then i use .sort to sort them descending by the army.power

    4.4. let victorious = armies[0]; will get me the first element from the sorted array. The one with the highest power. Or you can use destructuring and write it like let [victorious] = armies; (that represents the first element from the array)

    4.5. I compare the victorious.name with favoriteArmy to check if the army i'm interested in had won or lost.

/**
 * A function to create units
 */
const createHumanoid = (race, howMany, stats) => {

  return {
    name: race,
    armySize: howMany,
    unitStats: stats
  }

};

/**
 * Register the armies into battle
 */
let armies = [

  createHumanoid('humans', 12, {
    health: 10,
    attack: 12
  }),
  createHumanoid('zombies', 5, {
    health: 30,
    attack: 12
  }),

]

/**
 * Get the max power of each army - you can adjust the algorithm
 */
const getArmyPower = (army) => {
  return {
    name: army.name,
    power: +army.armySize * (+army.unitStats.health + +army.unitStats.attack)
  }

}

/**
 * Let them fight and see what your favorite army did in the battle
 */
function fight(armies, favoriteArmy) {

  armies = armies
    .map(army => getArmyPower(army))
    .sort((a, b) => b.power - a.power);

  let victorious = armies[0];

  if (victorious.name.toLowerCase() === favoriteArmy.toLowerCase()) {
    document.write('Live to see another day.');
  } else {
    document.write('The zombies are taking over!');
  }
}

fight(armies, 'humans');
darklightcode
  • 2,738
  • 1
  • 14
  • 17
  • This is awesome! Your code is so much smoother than mine lol. I do have a few questions since im not as advanced as this. 1. What is `power` achieving? I have never seen + before a variable like that. 2. Why do you have to add `name: army.name`, it doenst look like it is doing anything. 3. I know what .map and .sort do in theory, but I am not sure how they are applied here. – Joe cool Oct 09 '18 at 01:15
  • 1
    ‘Power’ returns a number based on army status, ‘howManyUnits * ( unit.health + unit.attack )’. In the ‘map’ method, the ‘armies’ array is formatted by applying ‘getArmyPower’ method on each item from ‘armies’, then i ‘sort’ the newly formated array ‘descending by power’, so the army with the biggest ‘power’ will be first, then i retrieve the first item of the array in ‘victorious’ variable. – darklightcode Oct 09 '18 at 03:29
  • 1
    The ‘+’ converts a string into a number, it’s a habbit of mine of making sure they’re numbers, as you can see, beside the ‘name’ every prop is a number :) – darklightcode Oct 09 '18 at 03:46
  • hey sorry one more thing... in `.map(army => getArmyPower(army))`, you said it runs the method on each item from 'armies', but the parameter there is 'army', not 'armies'. Why is that? And then `favoriteArmy` is a parameter but I dont see where it is assigned any value for the if statement. Where is the argument for it? [Sorry again, I'm still super new to coding and really just want to make sure I understand all the small things, or else I will never learn] – Joe cool Oct 09 '18 at 05:19
  • 1
    `.map(army => getArmyPower(army))` -> `army` is the item being looped, i could have written `.map( i => getArmyPower(i))` , it's just an alias for the item being processed. `favoriteArmy` is used as a parameter for `fight(armies, favoriteArmy)` method. I use it in the same function in the `if` condition. `favoriteArmy` is the army name that i'm interested to see "what it did" in the battle, change it to "zombies", you'll get the "The zombies are taking over!" answer. Use `console.log` on each methods/variables to see their structure/order of being outputed – darklightcode Oct 09 '18 at 06:03
  • Try to google methods that you don't understand, for example checkout `.map` method https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map the example here is very simple and basic. Read about destructuring, it will come in handy when you start looping objects/arrays to make your code more readable and simple – darklightcode Oct 09 '18 at 06:08
  • 1
    I have updated my answer so you can follow upon the development of the above script. – darklightcode Oct 09 '18 at 06:44
  • hey last thing sorry. how would i print the health of humans for example? because its an object in an array right? but its not assigned to any const, so i dont get how to actually get to the information, i keep getting [object, Object] or undefined. I found another post, "Access / process (nested) objects, arrays or JSON" which has great info, but I cant quite get it. – Joe cool Oct 10 '18 at 21:20
  • `armies[0].name` are the 'humans'. But you should build a method like to `getArmyByName(armyName, armiesArray)` and use `.filter` or `.forEach` with an `if` into it to match keys. My example was meant to provide you with the starting steps, those being `what you need`, `how to split your code` and `how to use it`. As for your help, i thank you, an accepted answer and a vote is enough, you don't need to like comments. Try and replicate my code, by hand, from top to bottom for a better understanding. Play with javascript methods/arrays/objects a bit more before diving into this. – darklightcode Oct 11 '18 at 06:19
  • good idea, im going to study more before diving into that. do you mind helping me understand #2 from my first comment? i spent all day on it, i think im just missing something. `const getArmyPower = (army) =>` the 'army' parameter somehow gets the zombie and human objects from 'armies'... I cannot for the LIFE of me figure out how. Where is the connection? Since parameters are scoped locally, how is this possible? I promise I have searched a lot, but i feel like it is a simple fix... – Joe cool Oct 11 '18 at 07:37
  • Indeed, it is a simple fix, i explained it on this fiddle https://jsfiddle.net/1vmw9yr2/ – darklightcode Oct 11 '18 at 08:21
  • And checkout this post about loops https://stackoverflow.com/questions/9329446/for-each-over-an-array-in-javascript , it's very descriptive, and at the bottom i wrote recently about destructuring in loops, and how to access deep properties in objects. Have a read on the accepted answer, is very good. – darklightcode Oct 11 '18 at 08:30