Last active
December 29, 2015 16:49
-
-
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#/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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