Skip to content

Instantly share code, notes, and snippets.

@Vratislav
Last active December 29, 2015 16:49
Show Gist options
  • Save Vratislav/7700270 to your computer and use it in GitHub Desktop.
Save Vratislav/7700270 to your computer and use it in GitHub Desktop.
This warrior will pass all the levels in https://www.bloc.io/ruby-warrior#/
class Player
#some dark reflection magic to allow our warrior to work in earlier levels
#where he does not have all the abilities
class DummySpace
def method_missing(name, *arguments)
if(name == :empty?)
return true
else
return false
end
end
end
#some dark reflection magic to allow our warrior to work in earlier levels
#where he does not have all the abilities
class ProxyWarrior
def initialize(warrior)
@warrior = warrior
end
def method_missing(name, *arguments)
if @warrior.respond_to?(name)
return @warrior.send(name,*arguments)
elsif(name.to_s.start_with?("can_") && name.to_s.end_with?("?"))
no_action = @warrior.respond_to?(name.to_s.sub!("can_", "").sub!("?","") )
return no_action if(no_action)
return @warrior.respond_to?(name.to_s.sub!("can_", "").sub!("?","!") )
elsif(name == :feel)
return DummySpace.new
elsif(name == :look)
return [DummySpace.new,DummySpace.new,DummySpace.new]
elsif(name == :health)
return 20
else
return false
end
end
end
def play_turn(warrior)
@warrior = ProxyWarrior.new(warrior)
#set initial direction of move
if(@mode == nil)
if(@warrior.can_pivot?)
@mode = :forward
if(@warrior.feel(:backward).empty?)
@warrior.pivot!
return nil
end
else
@mode ||= (@warrior.can_feel? && @warrior.feel(:backward).empty?) ? :backward : :forward
end
end
#set state variables
@prev_health ||= @warrior.health
@maxed_out ||= :yes
@last_action ||= :none
@explored_wall_to_wall ||= false
#A.I.
#First check if we have just defeated enemy and we are not maxed out
if(@last_action == :attack && @warrior.feel(@mode).empty? && @warrior.health < 20)
@maxed_out = :no
@last_action = :rest
@warrior.rest!
#Then check if we should retreat to max out and somebody is damaging us
#The .can_rescue? is a small hack to determine if the level is right for retreat.
#I don't have any better solution becouse by the time we need to retreat we can't use warrior.look
elsif(@maxed_out == :no && @warrior.can_rescue? && @prev_health > @warrior.health && @warrior.health < 20 && @warrior.feel(reverse_mode(@mode)).empty?)
@warrior.walk! reverse_mode(@mode)
#If we can regenerate in place, do it
elsif(@prev_health <= @warrior.health && @warrior.health < 20 && @warrior.feel.empty?)
@last_action = :rest
@warrior.rest!
#if we can see enemy, shoot it
elsif(first_sight.enemy?)
#@last_action = :attack
@warrior.shoot!
#if we can feel captive, rescue it
elsif(@warrior.feel(@mode).captive? )
@last_action = :rescue
@warrior.rescue! @mode
#if we can feel enemy, attack it
elsif(@warrior.feel(@mode).enemy? )
@last_action = :attack
@warrior.attack! @mode
#walk otherwise
else
@last_action = :walk
#pivot if we are at the stairs and we did not explore the room fully
if(@warrior.can_pivot? && @warrior.feel(@mode).stairs? && !@explored_wall_to_wall)
@warrior.pivot!
#pivot if we are at the wall
elsif(@warrior.can_pivot? && @warrior.feel(@mode).wall?)
@warrior.pivot!
@explored_wall_to_wall = true
#if we cannot pivot, change the walking direction
else
@mode = reverse_mode(@mode) if(@warrior.can_pivot? == false && @warrior.feel(@mode).wall?)
@warrior.walk! @mode
end
end
#indicate max out and record last health
@maxed_out = :yes if (@warrior.health == 20)
@prev_health = @warrior.health
end
#returns the first thing we can see
def first_sight
non_empty = @warrior.look.find { |s| !s.empty?}
non_empty ||= @warrior.look[0]
end
#returns reverse moving direction to the passed direction
def reverse_mode(mode)
if(mode == :backward)
:forward
else
:backward
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment