Skip to content

kibyegn's beginner solution

Kibet Yegon edited this page Jul 22, 2016 · 1 revision
class Player
  CRITICAL_HEALTH = 4

  def play_turn(warrior)
    @health ||= warrior.health
    @direction ||= get_start_direction(warrior)
    @reached_wall ||= false

    if safe_to_shoot?(warrior)
      warrior.shoot!
    elsif warrior.feel(@direction).empty?
      if should_rest? warrior
        warrior.rest!
      elsif should_flee? warrior
        @direction = :backward
        warrior.walk! @direction
      else
        if @direction == :backward && @reached_wall
          @direction = :forward
          warrior.walk! @direction
        else
          warrior.walk! @direction
        end
      end
    elsif warrior.feel(@direction).captive?
      warrior.rescue!(@direction)
    elsif warrior.feel(@direction).wall?
      @reached_wall = true
      @direction = :forward
      warrior.pivot!
    else
      warrior.attack! @direction
    end

    @health = warrior.health
  end

  private
    def should_rest?(warrior)
      not_taking_damage?(warrior) && critical_health?(warrior)
    end

    def should_flee?(warrior)
      taking_damage?(warrior) && critical_health?(warrior)
    end

    def critical_health?(warrior)
      warrior.health <= CRITICAL_HEALTH
    end

    def taking_damage?(warrior)
      warrior.health < @health
    end

    def not_taking_damage?(warrior)
      warrior.health >= @health
    end

    def get_start_direction(warrior)
      scout_behind = warrior.look :backward
      if scout_behind.any? {|space| space.captive? == true }
        return :backward
      else
        return :forward
      end
    end

    def safe_to_shoot?(warrior)
      scout_ahead = warrior.look @direction
      enemy_distance = scout_ahead.index {|space| space.enemy? == true } || 3
      captive_distance = scout_ahead.index {|space| space.captive? == true } || 3
      not_taking_damage?(warrior) && enemy_distance < captive_distance
    end
end