Created
August 25, 2013 18:52
-
-
Save kmayer/6335552 to your computer and use it in GitHub Desktop.
RubyWarrior beginner Total Score: 525 + 101 = 626
Your average grade for this tower is: S Level 1: S Level 2: A Level 3: S Level 4: S Level 5: A Level 6: S Level 7: S Level 8: S Level 9: S
This file contains 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
module Heuristics | |
TARGET_PRIORITY = { | |
RubyWarrior::Units::Archer => 1, | |
RubyWarrior::Units::Wizard => 2, | |
RubyWarrior::Units::ThickSludge => 3, | |
RubyWarrior::Units::Sludge => 4, | |
RubyWarrior::Units::Captive => 999, | |
RubyWarrior::Units::Warrior => 999, | |
} | |
def targets(targeter) | |
[:forward, :backward].map{ |direction| self.send(targeter, direction) }.compact.sort_by{|target| priority(target)} | |
end | |
def priority(target) | |
TARGET_PRIORITY.detect(->{[RubyWarrior::Units::Base, 9]}) {|enemy, _| target.unit.is_a?(enemy)}[1] | |
end | |
def sick? | |
warrior.health < 8 | |
end | |
def attacked? | |
warrior.health < health | |
end | |
def should_rest? | |
warrior.health < 20 && ((look(:forward) && look(:forward).enemy?) || (look(:backward) && look(:backward).enemy?)) | |
end | |
def safe_to_rest? | |
!ahead.enemy? && !behind.enemy? | |
end | |
def safe_to_retreat?(direction) | |
return false if !warrior.feel(direction).empty? | |
return false if look(direction) && look(direction).enemy? | |
distance_to_enemy = warrior.look(opposite(direction)).find_index{|space| space.enemy? } | |
return true if distance_to_enemy.nil? | |
farthest_safe_space = 3 - warrior.look(direction).reverse.find_index{|space| space.empty? } | |
distance_to_enemy + farthest_safe_space > 2 | |
end | |
end |
This file contains 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
require "sensing" | |
require "heuristics" | |
class Player | |
attr_reader :warrior, :health | |
include Sensing | |
include Heuristics | |
def initialize | |
@health = 20 | |
end | |
def play_turn(warrior) | |
@warrior = warrior | |
tactics.detect { |action| try(action) } | |
@health = warrior.health | |
end | |
private | |
def tactics | |
[:retreat, :attack, :shoot, :reengage, :search_and_rescue, :rest, :pivot, :walk] | |
end | |
def try(action) | |
self.send(action) && log(action) | |
end | |
def log(action) | |
$stdout.puts "ACTION => #{action}" | |
true | |
end | |
def retreat | |
retreat_to(:backward) || retreat_to(:forward) | |
end | |
def retreat_to(direction) | |
warrior.walk!(direction) if attacked? && sick? && safe_to_retreat?(direction) | |
end | |
def shoot | |
target = targets(:target_toward).first | |
return warrior.shoot!(target.direction) if target | |
end | |
def reengage | |
warrior.walk!(:forward) if attacked? && ahead.empty? | |
end | |
def search_and_rescue | |
rescue_captive(:forward) || rescue_captive(:backward) || search_for_captive(:backward) | |
end | |
def rescue_captive(direction) | |
warrior.rescue!(direction) if warrior.feel(direction).captive? | |
end | |
def search_for_captive(direction) | |
warrior.walk!(direction) if look(direction) && look(direction).captive? | |
end | |
def rest | |
warrior.rest! if ((should_rest? || sick?) && safe_to_rest?) | |
end | |
def attack | |
target = targets(:target_at).first | |
warrior.attack!(target.direction) if target | |
end | |
def pivot | |
warrior.pivot!(:backward) if ahead.wall? | |
end | |
def walk | |
warrior.walk!(:forward) | |
end | |
end |
This file contains 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
module Sensing | |
Target = Struct.new(:unit, :direction) | |
def look(direction) | |
warrior.look(direction).detect{|space| !space.empty?} | |
end | |
def target_toward(direction) | |
lookyloo = look(direction) | |
Target.new(lookyloo.unit, direction) if lookyloo && lookyloo.enemy? | |
end | |
def target_at(direction) | |
unit = warrior.feel(direction) | |
Target.new(unit, direction) if unit.enemy? | |
end | |
def ahead | |
warrior.feel(:forward) | |
end | |
def behind | |
warrior.feel(:backward) | |
end | |
def opposite(direction) | |
{:forward => :backward, :backward => :forward}[direction] | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment