Red-Green-Refactoring with Ruby Warrior
I'm placing all my solutions in this Gist. Unfortunately, I cannot monkeypatch or mix commands for better refactoring. It's the nature of the game that I must maintain control of the Player object only.
I'm placing all my solutions in this Gist. Unfortunately, I cannot monkeypatch or mix commands for better refactoring. It's the nature of the game that I must maintain control of the Player object only.
# Easy use of the command to beat the level | |
class Player | |
def play_turn(warrior) | |
warrior.walk! | |
end | |
end | |
# Feel around to see if you should attack or walk | |
class Player | |
def play_turn(warrior) | |
if warrior.feel.empty? | |
warrior.walk! | |
else | |
warrior.attack! | |
end | |
end | |
end | |
# Guessing #15 health is best | |
# When it drops below, the warrior rests rather than carries on | |
class Player | |
def play_turn(warrior) | |
# feel infront | |
if warrior.feel.empty? | |
# decide what to do now that we can't be attacked. | |
if warrior.health < 15 | |
warrior.rest! | |
else | |
warrior.walk! | |
end | |
else | |
warrior.attack! | |
end | |
end | |
end | |
# Moving my guess of 15 to the top, so it's easy to find and mess with | |
class Player | |
# Keep value up top to twiddle | |
MIN_HEALTH = 15 | |
def play_turn(warrior) | |
if warrior.feel.empty? | |
if warrior.health < MIN_HEALTH | |
warrior.rest! | |
else | |
warrior.walk! | |
end | |
else | |
warrior.attack! | |
end | |
end | |
end |
# Store the last known health in the instance variable @last_known_health | |
# use this variable to see if we're taking damage | |
class Player | |
MIN_HEALTH = 15 | |
def play_turn(warrior) | |
if warrior.feel.empty? | |
if warrior.health < MIN_HEALTH && (warrior.health >= @last_known_health) | |
warrior.rest! | |
else | |
warrior.walk! | |
end | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
end | |
# Store the last known health in the instance variable @last_known_health | |
# use this variable to see if we're taking damage | |
class Player | |
MIN_HEALTH = 15 | |
def play_turn(warrior) | |
if warrior.feel.empty? | |
if should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! | |
end | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def should_rest? warrior | |
# Don't worry too much about the next line | |
@last_known_health = warrior.health unless @last_known_health | |
safe = warrior.health >= @last_known_health | |
bad_health = warrior.health < MIN_HEALTH | |
safe && bad_health | |
end | |
end |
# Beating level 5 was simple by using a var for the space we inspect | |
class Player | |
MIN_HEALTH = 15 | |
def play_turn(warrior) | |
front_space = warrior.feel | |
if front_space.empty? | |
if should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! | |
end | |
elsif front_space.captive? | |
warrior.rescue! | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def should_rest? warrior | |
# Don't worry too much about the next line | |
@last_known_health = warrior.health unless @last_known_health | |
safe = warrior.health >= @last_known_health | |
bad_health = warrior.health < MIN_HEALTH | |
safe && bad_health | |
end | |
end |
# Level 6 gets tricky, adding need to flee! | |
class Player | |
MIN_HEALTH = 15 | |
def play_turn(warrior) | |
@last_known_health = warrior.health unless @last_known_health | |
front_space = warrior.feel | |
if front_space.empty? | |
if should_flee? warrior | |
warrior.walk! :backward | |
elsif should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! | |
end | |
elsif front_space.captive? | |
warrior.rescue! | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def should_flee? warrior | |
!safe?(warrior) && (warrior.health < 7) | |
end | |
def should_rest? warrior | |
bad_health = warrior.health < MIN_HEALTH | |
safe?(warrior) && bad_health | |
end | |
def safe? warrior | |
warrior.health >= @last_known_health | |
end | |
end |
# Level 6 gets a @direction var to maintain direction in all actions. | |
class Player | |
MIN_HEALTH = 15 | |
FLEE_HEALTH = 7 | |
def play_turn(warrior) | |
# switch to ||= like a good boy | |
@last_known_health ||= warrior.health | |
@direction ||= :forward | |
feel_space = warrior.feel @direction | |
if feel_space.empty? | |
if should_flee? warrior | |
@direction = :backward | |
warrior.walk! @direction | |
elsif should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! @direction | |
end | |
elsif feel_space.captive? | |
warrior.rescue! @direction | |
elsif feel_space.wall? | |
@direction = :forward | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def should_flee? warrior | |
bad_health = warrior.health < FLEE_HEALTH | |
!safe?(warrior) && bad_health | |
end | |
def should_rest? warrior | |
bad_health = warrior.health < MIN_HEALTH | |
safe?(warrior) && bad_health | |
end | |
def safe? warrior | |
warrior.health >= @last_known_health | |
end | |
end |
# Added a single line to the last one, and it works! | |
class Player | |
REST_HEALTH = 15 | |
FLEE_HEALTH = 7 | |
def play_turn(warrior) | |
@last_known_health ||= warrior.health | |
@direction ||= :forward | |
feel_space = warrior.feel @direction | |
if feel_space.empty? | |
if should_flee? warrior | |
@direction = :backward | |
warrior.walk! @direction | |
elsif should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! @direction | |
end | |
elsif feel_space.captive? | |
warrior.rescue! @direction | |
elsif feel_space.wall? | |
@direction = :forward | |
warrior.pivot! | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def should_flee? warrior | |
bad_health = warrior.health < FLEE_HEALTH | |
!safe?(warrior) && bad_health | |
end | |
def should_rest? warrior | |
bad_health = warrior.health < REST_HEALTH | |
safe?(warrior) && bad_health | |
end | |
def safe? warrior | |
warrior.health >= @last_known_health | |
end | |
end |
# Level 8 basic | |
class Player | |
REST_HEALTH = 15 | |
FLEE_HEALTH = 7 | |
def play_turn(warrior) | |
@last_known_health ||= warrior.health | |
@direction ||= :forward | |
feel_space = warrior.feel @direction | |
glance = warrior.look @direction | |
if glance.any? { |space| space.enemy? } | |
warrior.shoot! | |
elsif feel_space.empty? | |
if should_flee? warrior | |
@direction = :backward | |
warrior.walk! @direction | |
elsif should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! @direction | |
end | |
elsif feel_space.captive? | |
warrior.rescue! @direction | |
elsif feel_space.wall? | |
@direction = :forward | |
warrior.pivot! | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def should_flee? warrior | |
bad_health = warrior.health < FLEE_HEALTH | |
!safe?(warrior) && bad_health | |
end | |
def should_rest? warrior | |
bad_health = warrior.health < REST_HEALTH | |
safe?(warrior) && bad_health | |
end | |
def safe? warrior | |
warrior.health >= @last_known_health | |
end | |
end |
# Level 8 with rescue! | |
class Player | |
REST_HEALTH = 15 | |
FLEE_HEALTH = 7 | |
MAX_GLANCE = 4 | |
def play_turn(warrior) | |
@last_known_health ||= warrior.health | |
@direction ||= :forward | |
feel_space = warrior.feel @direction | |
glance = warrior.look @direction | |
if clear_shot? warrior | |
warrior.shoot! | |
elsif feel_space.empty? | |
if should_flee? warrior | |
@direction = :backward | |
warrior.walk! @direction | |
elsif should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! @direction | |
end | |
elsif feel_space.captive? | |
warrior.rescue! @direction | |
elsif feel_space.wall? | |
@direction = :forward | |
warrior.pivot! | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def clear_shot? warrior | |
glance = warrior.look @direction | |
distance_to_enemy = glance.index { |space| space.enemy? == true } || MAX_GLANCE | |
distance_to_captive = glance.index { |space| space.captive? == true } || MAX_GLANCE | |
distance_to_enemy < distance_to_captive | |
end | |
def should_flee? warrior | |
bad_health = warrior.health < FLEE_HEALTH | |
!safe?(warrior) && bad_health | |
end | |
def should_rest? warrior | |
bad_health = warrior.health < REST_HEALTH | |
safe?(warrior) && bad_health | |
end | |
def safe? warrior | |
warrior.health >= @last_known_health | |
end | |
end |
# Everything with rescue! | |
class Player | |
REST_HEALTH = 15 | |
FLEE_HEALTH = 7 | |
MAX_GLANCE = 4 | |
def play_turn(warrior) | |
@last_known_health ||= warrior.health | |
@direction ||= :forward | |
feel_space = warrior.feel @direction | |
if clear_shot? warrior | |
warrior.shoot! | |
elsif feel_space.empty? | |
if should_flee? warrior | |
@direction = :backward | |
warrior.walk! @direction | |
elsif should_rest? warrior | |
warrior.rest! | |
else | |
warrior.walk! @direction | |
end | |
elsif feel_space.captive? | |
warrior.rescue! @direction | |
elsif feel_space.wall? | |
@direction = :forward | |
warrior.pivot! | |
else | |
warrior.attack! | |
end | |
@last_known_health = warrior.health | |
end | |
private | |
def clear_shot? warrior | |
glance = warrior.look @direction | |
distance_to_enemy = glance.index { |space| space.enemy? == true } || MAX_GLANCE | |
distance_to_captive = glance.index { |space| space.captive? == true } || MAX_GLANCE | |
safe?(warrior) && distance_to_enemy < distance_to_captive | |
end | |
def should_flee? warrior | |
bad_health = warrior.health < FLEE_HEALTH | |
!safe?(warrior) && bad_health | |
end | |
def should_rest? warrior | |
bad_health = warrior.health < REST_HEALTH | |
safe?(warrior) && bad_health | |
end | |
def safe? warrior | |
warrior.health >= @last_known_health | |
end | |
end |