class Player
def play_turn(warrior)
@warrior = warrior
bind? || rest_before_detonation? || detonate? || rescue_ticking? ||
find_ticking? || attack? || rest? || rescue? || find_captive? ||
find_enemy? || walk_ahead!
end
def bind?
dirs = enemy_dirs
dirs.size > 1 && (bind!(dirs[0]) || true)
end
def rest_before_detonation?
health < 15 &&
enemy_dirs.empty? &&
directions.any? {|dir| look(dir).last(2).all?(&:enemy?) } &&
(rest! || true)
end
def detonate?
return if listen.any? {|space| space.ticking? && distance_of(space) < 3 }
dir = directions.find {|d| look(d).first(2).all?(&:enemy?) }
dir && (detonate!(dir) || true)
end
def rescue?
dir = captive_dirs[0]
dir && (rescue!(dir) || true)
end
def attack?
dir = enemy_dirs[0]
dir && (attack!(dir) || true)
end
def rescue_ticking?
dir = ticking_dirs[0]
dir && (rescue!(dir) || true)
end
def rest?
health < 16 && !listen.empty? && (rest! || true)
end
def walk_ahead!
walk! direction_of_stairs
end
def directions
%i(left right forward backward)
end
around_dirs = lambda do |proc|
-> { directions.select {|dir| proc.(feel(dir)) } }
end
all_dirs = lambda do |proc|
-> { listen.select(&proc).map {|space| direction_of(space) } }
end
find = lambda do |sym|
lambda do
dir = send(sym)[0]
ok_dirs = empty_dirs
ok_dirs.delete(:backward) if sym == :tickings
dir = ok_dirs[0] if dir && !ok_dirs.include?(dir)
dir && (walk!(dir) || true)
end
end
define_method(:enemies, &all_dirs.(:enemy?.to_proc))
define_method(:captives, &all_dirs.(:captive?.to_proc))
define_method(:tickings, &all_dirs.(:ticking?.to_proc))
define_method(:enemy_dirs, &around_dirs.(:enemy?.to_proc))
define_method(:captive_dirs, &around_dirs.(:captive?.to_proc))
define_method(:ticking_dirs, &around_dirs.(:ticking?.to_proc))
empty = ->(space) { space.empty? && !space.stairs? }
define_method(:empty_dirs, &around_dirs.(empty))
define_method(:find_enemy?, &find.(:enemies))
define_method(:find_captive?, &find.(:captives))
define_method(:find_ticking?, &find.(:tickings))
def method_missing(sym, *args)
@warrior.respond_to?(sym) ? @warrior.send(sym, *args) : super
end
end