We have learned Object Oriented Programming and Prototypal inheritance with JavaScript. Now we will work with our Viking friends applying all the concepts we just learned today. Let's start with the exercise.
- Fork this repo
- Clone this repo into your
~/code/labs - Make sure you use objects and prototypal inheritance during the exercise.
- We should follow good object oriented principals.
- Upon completion, run the following commands
git add .
git commit -m "done"
git push origin master
- Navigate to your repo and create a Pull Request
Yes! Best way to know how our code is doing is to work with tests. Go ahead and open the SpecRunner.html!
Run the tests
We've got a test suite for our constructor functions and their methods but there are no tests currently being executed. We have to uncomment each it() inside of tests/VikingSpec.js and implement the code in src/viking.js to make each test pass.
If you open tests/VikingSpec.js and take a look at lines 10-20. You should see some it() functions (tests) that are commented out. Let's start by uncommenting lines 10-12:
describe("constructor function", function () {
it("should receive 2 arguments (health & strength)", function () {
expect(Soldier.length).toEqual(2);
});
// it("should receive the health property as its 1st argument", function () {
// expect(soldier.health).toEqual(health);
// });
// it("should receive the strength property as its 2nd argument", function () {
// expect(soldier.strength).toEqual(strength);
// });
});Now that particular test (should receive 2 arguments (health & strength)) is failing!
Write the code
Now we have to write the correct code in the src/viking.js file to make the test pass. The starter code you will find in the file is the following:
// Soldier
class Soldier {}
// Viking
class Viking {}
// Saxon
class Saxon {}
// War
class War {}In this case, the test says that Soldier constructor function should receive 2 arguments (health & strength), so we have to write the correct code that passes this test. Let's make the Soldier constructor function receive two arguments:
// Soldier
class Soldier {
constructor(healthArg, strengthArg) {}
}
// Viking
class Viking {}
// Saxon
class Saxon {}
// War
class War {}Execute all the tests
Now that we are passing the first test, the next step is to uncomment the next test. To do that, we have to remove the comments from lines 15-17 in the spec/VikingSpec.js file, and refresh the page to see what we have to implement next:
Once we have checked out that the test is failing, we can implement the code to make it pass.
Modify the Soldier constructor function and add 2 methods to its prototype: attack(), and receiveDamage().
- should receive 2 arguments (health & strength)
- should receive the
healthproperty as its 1st argument - should receive the
strengthproperty as its 2nd argument
- should be a function
- should receive 0 arguments
- should return the
strengthproperty of theSoldier
- should be a function
- should receive 1 argument (the damage)
- should remove the received damage from the
healthproperty - shouldn't return anything
A Viking is a Soldier with an additional property, their name. They also have a different receiveDamage() method and new method, battleCry().
Modify the Viking constructor function, have it inherit from Soldier, reimplement the receiveDamage() method for Viking, and add a new battleCry() method.
Vikingshould inherit fromSoldier
- should receive 3 arguments (name, health & strength)
- should receive the
nameproperty as its 1st argument - should receive the
healthproperty as its 2nd argument - should receive the
strengthproperty as its 3rd argument
(This method should be inherited from Soldier, no need to reimplement it.)
- should be a function
- should receive 0 arguments
- should return the
strengthproperty of theViking
(This method needs to be reimplemented for Viking because the Viking version needs to have different return values.)
- should be a function
- should receive 1 argument (the damage)
- should remove the received damage from the
healthproperty - if the
Vikingis still alive, it should return "NAME has received DAMAGE points of damage" - if the
Vikingdies, it should return "NAME has died in act of combat"
Learn more about battle cries.
- should be a function
- should receive 0 arguments
- should return "Odin Owns You All!"
A Saxon is a weaker kind of Soldier. Unlike a Viking, a Saxon has no name. Their receiveDamage() method will also be different than the original Soldier version.
Modify the Saxon, constructor function, have it inherit from Soldier and reimplement the receiveDamage() method for Saxon.
Saxonshould inherit fromSoldier
- should receive 2 arguments (health & strength)
- should receive the
healthproperty as its 1st argument - should receive the
strengthproperty as its 2nd argument
(This method should be inherited from Soldier, no need to reimplement it.)
- should be a function
- should receive 0 arguments
- should return the
strengthproperty of theSaxon
(This method needs to be reimplemented for Saxon because the Saxon version needs to have different return values.)
- should be a function
- should receive 1 argument (the damage)
- should remove the received damage from the
healthproperty - if the Saxon is still alive, it should return "A Saxon has received DAMAGE points of damage"
- if the Saxon dies, it should return "A Saxon has died in combat"
Now we get to the good stuff: WAR! Our War constructor function will allow us to have a Viking army and a Saxon army that battle each other.
Modify the War constructor and add 5 methods to its prototype:
addViking()addSaxon()vikingAttack()saxonAttack()showStatus()
When we first create a War, the armies should be empty. We will add soldiers to the armies later.
- should receive 0 arguments
- should assign an empty array to the
vikingArmyproperty - should assign an empty array to the
saxonArmyproperty
Adds 1 Viking to the vikingArmy. If you want a 10 Viking army, you need to call this 10 times.
- should be a function
- should receive 1 argument (a
Vikingobject) - should add the received
Vikingto the army - shouldn't return anything
The Saxon version of addViking().
- should be a function
- should receive 1 argument (a
Saxonobject) - should add the received
Saxonto the army - shouldn't return anything
A Saxon (chosen at random) has their receiveDamage() method called with the damage equal to the strength of a Viking (also chosen at random). This should only perform a single attack and the Saxon doesn't get to attack back.
- should be a function
- should receive 0 arguments
- should make a
SaxonreceiveDamage()equal to thestrengthof aViking - should remove dead saxons from the army
- should return result of calling
receiveDamage()of aSaxonwith thestrengthof aViking
The Saxon version of vikingAttack(). A Viking receives the damage equal to the strength of a Saxon.
- should be a function
- should receive 0 arguments
- should make a
VikingreceiveDamage()equal to thestrengthof aSaxon - should remove dead vikings from the army
- should return result of calling
receiveDamage()of aVikingwith thestrengthof aSaxon
Returns the current status of the War based on the size of the armies.
- should be a function
- should receive 0 arguments
- if the
Saxonarray is empty, should return "Vikings have won the war of the century!" - if the
Vikingarray is empty, should return "Saxons have fought for their lives and survive another day..." - if there are at least 1
Vikingand 1Saxon, should return "Vikings and Saxons are still in the thick of battle."
//Happy Coding!!




