Skip to content

Instantly share code, notes, and snippets.

@fabrizioc1
Forked from hcarvalhoalves/fsm-ruby-warrior.rb
Created July 28, 2013 04:26
Show Gist options
  • Save fabrizioc1/6097369 to your computer and use it in GitHub Desktop.
Save fabrizioc1/6097369 to your computer and use it in GitHub Desktop.
class Player
def initialize
@max_health = 20
@last_health = @max_health
@taking_damage = false
@directions = [:backward, :forward]
@current_direction = :forward
@reached_wall = false
end
def switch!
@current_direction = @current_direction == :forward ? :backward : :forward
end
def hostile_distance(warrior, dir)
if warrior.respond_to?(:look) then
return warrior.look(dir).index {|t| t.enemy?}
end
return -1
end
def captive_distance(warrior, dir)
if warrior.respond_to?(:look) then
return warrior.look(dir).index {|t| t.captive?}
end
return -1
end
def any_hostile?(warrior, dir)
if warrior.respond_to?(:look) then
return warrior.look(dir).any? {|t| t.enemy?}
end
end
def any_captive?(warrior, dir)
if warrior.respond_to?(:look) then
return warrior.look(dir).any? {|t| t.captive?}
end
end
def safe_to_shoot?(warrior, dir)
if any_hostile?(warrior, dir) then
unless any_captive?(warrior, dir) and captive_distance(warrior, dir) < hostile_distance(warrior, dir) then
if hostile_distance(warrior, dir) > 0 and warrior.health < (@max_health / 2) then
return true
elsif hostile_distance(warrior, dir) > 1 then
return true
end
end
end
end
def sense_hostile(warrior)
@directions.each do |dir|
if warrior.respond_to?(:shoot!) and safe_to_shoot?(warrior, dir) then
warrior.shoot!(dir)
return true
elsif warrior.feel(dir).enemy? then
warrior.attack!(dir)
return true
end
end
return false
end
def sense_captive(warrior)
@directions.each do |dir|
if warrior.feel(dir).captive? then
warrior.rescue!(dir)
return true
end
end
return false
end
def sense_stairs(warrior)
if warrior.feel(@current_direction).stairs? and not @reached_wall then
if warrior.respond_to?(:pivot!) then
warrior.pivot!
else
warrior.walk!(switch!)
end
return true
end
return false
end
def sense_wall(warrior)
if warrior.feel(@current_direction).wall? then
@reached_wall = true
if warrior.respond_to?(:pivot!) then
warrior.pivot!
else
warrior.walk!(switch!)
end
return true
end
return false
end
def recover(warrior)
if warrior.health < @max_health and not @taking_damage then
warrior.rest!
return true
end
return false
end
def retreat(warrior)
if warrior.health - @last_damage < @max_health / 3 and @taking_damage then
if warrior.feel(:backward).empty? then
warrior.walk!(:backward)
return true
end
end
return false
end
def advance(warrior)
warrior.walk!(@current_direction)
end
def play_turn(warrior)
@taking_damage = warrior.health < @last_health
@last_damage = @last_health - warrior.health
@last_action = sense_hostile(warrior) ||
sense_captive(warrior) ||
sense_wall(warrior) ||
sense_stairs(warrior) ||
retreat(warrior) ||
recover(warrior) ||
advance(warrior)
@last_health = warrior.health
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment