Ruby Warrior – Level 1 to 5

Ruby Warrior is a super fun game where you write Ruby code to move your knight character and win levels. After finishing Ruby Monk Primer and Codecademy’s Ruby track, I played the first 5 levels of Ruby Warrior. I’m going to walk through my thought process and code for each level.

Level 1 – Walk

Level - 1 Walk
Level – 1 Walk

Level 1 is pretty simple. There is already a method defined for us called play_turn which takes a warrior as a parameter. We want the knight to walk to the stairs. Every turn, we call the walk method on the warrior. He will walk forward one space at a time until he reaches the stairs.

Level 2 – Sludge!

Level - 2 Sludge!
Level – 2 Sludge!

Level 2 introduces little green sludge monsters. Our knight can only perform one action every turn, so he can either walk or fight. We want to first check whether there is a monster in the next space. If there is, we want to fight. If not, we simply take a step forward.

level-2-code
We use the feel method and see if that returns empty. If the space before us is empty, our warrior walks. If the space is not empty, attack the sludge!

Poor little sludge fades away after 2 attacks.

Level 3 – MORE Sludge

Level 3 - More Sludge!
Level 3 – More Sludge!

Level 3 ups the sludge levels. If we run our code from level 2, our poor warrior runs out of health quickly and we fail the level. Our warrior needs rest to get back his health before fighting more sludge. The warrior can’t rest if there’s sludge in front because he will get attacked (remember we can only perform one action per turn), so the only time he can rest is if there’s no sludge in the space ahead.

There are two questions to ask:
1. Is there an empty space ahead? -> no: fight, yes: move to question 2.
2. Is my health ok? -> no: rest, yes: walk.

Level 3 - My code

I set a constant of 15 for minimum health levels, but it can actually be 7. Each sludge attack is -3 damage. A sludge is killed after 2 warrior attacks, so the maximum damage you get from a sludge is -6. If the space in front is empty, then check if the warrior’s health is at least at minimum health. If so, go on ahead. If the health is less than minimum, the warrior will rest for that turn.

Level 4 – Add Archers!

Level 4 - Archers
Level 4 – Archers

Level 4 introduces these archers with nice and lush hair. Once the sludge is gone and no longer obstructing their view, they start shooting arrows at you! If your warrior is taking damage from the archer, you must charge ahead and not be a standing target.  We want to add on to the logic from above.

The scenario:  there is an empty space in front -> warrior health is not ok. If we run the same code from Level 4, the warrior just rests while the archer attacks. In this level we want to add some code so if the warrior is under attack, we want to walk. If the warrior is not under attack, we can rest. How do we know if we are under attack? We can compare the warrior’s current health level with the previous level to see if there was any damage.

Level 4 - my code
Level 4 – my code

I set an instance variable of health. When it’s the player’s turn, we first set the health variable to the warrior’s health. (Note that line 6 only runs during the very first turn, since from then on @health is not nil.) We set a local variable of under_attack that is a boolean. It returns true if the warrior’s health is less than the stored health variable value.

We use a boolean operator to check two things: whether the warrior’s health is good and if the warrior is under attack. If either one of these is true, the warrior should walk. This of course needs an || (or) operator. If neither of these are true, then the warrior gets to rest. At the end of the turn we store the warrior’s health in the @health variable for reference during the next turn.

Level 5 – Rescue me!

Level 5 - captives
Level 5 – captives

Level 5 introduces some captives locked in small cages. Their eyes look so sad. This was a fairly simple level. If we look at our code, we attack whenever the space in front is not empty. But we don’t want to attack captives! When the space ahead is not empty, we will check if there is a captive. If there is a captive, the warrior will rescue the captive. If not, then attack the enemy! (Lines 16 to 20)

Level 5 - My code
Level 5 – My code

Refactoring
The great thing about Ruby Warrior is that after you successfully clear a level, you can still play around in the editor and rerun your code. This gives you a way to test different things out. I added a private method to determine if the warrior should_walk?, it checks the health and under attack status of the warrior. Both of these values are booleans, and are evaluated with an OR operator.

If should_walk? returns true, warrior walks. If not, warrior rests. The should_walk method accepts a warrior parameter. On line 6 I also changed “if @health.nil?” to “unless @health”. This means that if @health has a value, then the line will not run. “Unless” is equivalent to saying “if not x”.

Screen Shot 2015-08-25 at 9.29.41 PM

Conclusion
Level 1-5 of Ruby Warrior was really fun. I found Level 4 to be the most challenging as I got stuck on getting an error because health was initially nil. Drawing out “yes/no” flow charts on paper really helped me work out the logic! I can’t wait to see what Level 6 will bring.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s