Skip to content

Instantly share code, notes, and snippets.

@EdCharbeneau
Last active January 4, 2016 00:49
Show Gist options
  • Save EdCharbeneau/8543913 to your computer and use it in GitHub Desktop.
Save EdCharbeneau/8543913 to your computer and use it in GitHub Desktop.
class Player
def initialize
@max_health = 20
@last_health = 20
@critical_health = 10
@direction = :forward
end
def play_turn(warrior)
@warrior = warrior
if near_wall?
warrior.pivot!
end
queue_commands(create_commands).execute
@last_health = @warrior.health
end
def create_commands
walk = WalkCommand.new(@warrior, @direction)
rescue_captive = RescueCommand.new(@warrior, @direction)
heal = RestCommand.new(@warrior, @direction, taking_damage?)
bow_attack = BowAttackCommand.new(@warrior, @direction, taking_damage?)
attack = AttackCommand.new(@warrior, @direction)
commands = [bow_attack, attack, heal, rescue_captive, walk]
end
def queue_commands(commands)
commands.each_cons(2) {|cmd, succ| cmd.set_successor(succ)}
commands.first
end
def taking_damage?
@warrior.health < @last_health
end
def near_wall?
@warrior.feel(@direction).wall?
end
end
class CommandBase
def initialize(warrior, direction, under_attack = false )
@warrior = warrior
@wdirection = direction
@under_attack = under_attack
end
def set_successor(command)
@successor = command
end
def execute
@warrior.walk!(@wdirection)
end
def can_execute_successor?
@successor != nil
end
end
class AttackCommand < CommandBase
def execute
return @warrior.attack! if can_sword_attack?
@successor.execute if can_execute_successor?
end
def can_sword_attack?
@warrior.feel(@wdirection).enemy?
end
end
class BowAttackCommand < CommandBase
def execute
return @warrior.shoot! if can_attack_from_safety?
@successor.execute if can_execute_successor?
end
def can_attack_from_safety?
can_see_enemy? && !@under_attack
end
def can_see_enemy?
@warrior.look(@wdirection).any? {|space| space.enemy?}
end
end
class RescueCommand < CommandBase
def execute
return @warrior.rescue!(@wdirection) if can_rescue_captive?
@successor.execute if can_execute_successor?
end
def can_rescue_captive?
@warrior.feel(@wdirection).captive?
end
end
class RestCommand < CommandBase
def execute
return @warrior.walk!(:backward) if should_retreat?
return @warrior.rest! if can_heal_safely?
@successor.execute if can_execute_successor?
end
def can_heal_safely?
!@under_attack && is_wounded?
end
def should_retreat?
@took_damage && has_critical_health?
end
def is_wounded?
@warrior.health < 20
end
def has_critical_health?
@warrior.health < 10
end
end
class WalkCommand < CommandBase
def execute
return @warrior.walk!(@wdirection) if can_walk?
@successor.execute if can_execute_successor?
end
def can_walk?
@warrior.feel(@wdirection).empty?
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment