Skip to content

Commit

Permalink
Track HP and location of enemies
Browse files Browse the repository at this point in the history
  • Loading branch information
gabebw committed Sep 26, 2010
1 parent ab0a7dc commit 1567889
Showing 1 changed file with 87 additions and 17 deletions.
104 changes: 87 additions & 17 deletions player.rb
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def play_turn(warrior)
@previous_space ||= current_location @previous_space ||= current_location
# If true, then rest until at max health before continuing # If true, then rest until at max health before continuing
@recuperating ||= false @recuperating ||= false
register_most_recent_enemy


perform_action!(warrior) perform_action!(warrior)


Expand Down Expand Up @@ -69,7 +70,7 @@ def perform_action!(warrior)
warrior.rescue!(direction) warrior.rescue!(direction)
elsif space.enemy? elsif space.enemy?
most_recent_enemy = space.character most_recent_enemy = space.character
warrior.attack!(direction) attack_enemy!(direction)
elsif space.empty? elsif space.empty?
# May have just moved away from an enemy, so check if we should # May have just moved away from an enemy, so check if we should
# re-engage. # re-engage.
Expand Down Expand Up @@ -119,6 +120,14 @@ def mark_safe_location!
@safe_locations << current_location unless @safe_locations.include?(current_location) @safe_locations << current_location unless @safe_locations.include?(current_location)
end end


# A wrapper around warrior.attack!(direction) so we can track an enemy's
# health.
def attack_enemy!(direction)
location = @warrior.feel(direction).location
decrement_most_recent_enemys_health_by(DAMAGE_DEALT)
@warrior.attack!(direction)
end

## TESTERS ## TESTERS


# Is this space safe to rest in? # Is this space safe to rest in?
Expand All @@ -145,6 +154,8 @@ def should_rest?
# Stop recuperating if at max health # Stop recuperating if at max health
@recuperating = @warrior.health < MAX_HEALTH @recuperating = @warrior.health < MAX_HEALTH
return @recuperating return @recuperating
elsif most_recent_enemy
not healthy_enough_to_beat_enemy_at?(get_most_recent_enemy_info[:location])
else else
low_on_health? low_on_health?
end end
Expand Down Expand Up @@ -197,18 +208,19 @@ def location_of_most_recent_enemy=(location)


def most_recent_enemy def most_recent_enemy
@most_recent_enemy ||= nil @most_recent_enemy ||= nil
new_enemy = nil
if taking_damage_from_afar? if taking_damage_from_afar?
@most_recent_enemy = :a new_enemy = :a
elsif next_to_enemy? elsif next_to_enemy?
dir = DIRECTIONS.detect { |d| @warrior.feel(d).enemy? } dir = DIRECTIONS.detect { |d| @warrior.feel(d).enemy? }
@most_recent_enemy = @warrior.feel(dir).character new_enemy = @warrior.feel(dir).character
end
# Update only if we have a new enemy
if new_enemy
@most_recent_enemy = new_enemy
end end
@most_recent_enemy = @most_recent_enemy.to_sym unless @most_recent_enemy.nil? @most_recent_enemy = @most_recent_enemy.to_sym unless @most_recent_enemy.nil?
end @most_recent_enemy

# Pass in a character, e.g. "S" for a thick sludge.
def most_recent_enemy=(enemy)
@most_recent_enemy = enemy.to_sym
end end


# UTILITY # UTILITY
Expand All @@ -219,19 +231,23 @@ def opposite_direction_of(dir)
end end
end end


# Pass in an enemy character, like "S", to determine how many turns it # Pass in an enemy location to determine how many turns it
# will take to kill it once you're next to it. # will take to kill it once you're next to it.
def turns_required_to_beat(enemy) def turns_required_to_beat_enemy_at(enemy_location)
enemy = enemy.to_sym info = get_info_about_enemy_at(enemy_location)
(ENEMY[enemy][:health].to_f / DAMAGE_DEALT).ceil turns = (info[:health].to_f / DAMAGE_DEALT).ceil
turns
end end


# Do we have enough health to engage in battle? # Do we have enough health to engage in battle?
def healthy_enough_to_beat?(enemy) def healthy_enough_to_beat_enemy_at?(enemy_location)
turns = turns_required_to_beat(enemy) turns = turns_required_to_beat_enemy_at(enemy_location)
# Archers attack from a distance of 2 squares enemy_info = get_info_about_enemy_at(enemy_location)
turns += 2 if enemy == :a # Archers attack from a distance of 2 squares, but if we're right next
predicted_damage_taken = turns * ENEMY[enemy][:damage] # to them then we need fewer turns
turns += [2, get_distance_away(enemy_info[:location])].min if enemy_info[:character] == :a
puts "turns reqd: #{turns}"
predicted_damage_taken = turns * enemy_info[:damage]
predicted_damage_taken < current_health predicted_damage_taken < current_health
end end


Expand Down Expand Up @@ -261,4 +277,58 @@ def towards(location)
def away_from(location) def away_from(location)
opposite_direction_of(towards(location)) opposite_direction_of(towards(location))
end end

# Register the most recent enemy. We need to keep track of their health!
def register_most_recent_enemy
# Map a specific enemy to its info
@enemies ||= {}
return if most_recent_enemy.nil?
info = get_most_recent_enemy_info
@enemies[info[:location]] ||= info
end

# Removes most recent enemy from @enemies hash
def unregister_most_recent_enemy!
info = get_most_recent_enemy_info
@enemies.delete(info[:location])
end

# Returns a Hash of info about most recent enemy. Hash is empty if
# no enemies have been encountered yet.
def get_most_recent_enemy_info
return {} if most_recent_enemy.nil?
info = {}
info[:location] = location_of_most_recent_enemy
info[:direction] = towards(info[:location])
info[:character] = most_recent_enemy
info.merge!(ENEMY[info[:character]])

info
end

# Decrement most recent enemy's health, unregistering them if they died.
def decrement_most_recent_enemys_health_by(amount)
register_most_recent_enemy
info = get_most_recent_enemy_info
@enemies[info[:location]][:health] -= amount
if @enemies[info[:location]][:health] <= 0
# Enemy died
unregister_most_recent_enemy!
end
end

# Get info about a specific enemy
def get_info_about_enemy_at(location)
@enemies ||= {}
@enemies[location]
end

# Get number of squares between warrior and given location
def get_distance_away(location)
target_x, target_y = location
current_x, current_y = current_location
distance = (((target_x - current_x).to_f ** 2) + ((target_y - current_y).to_f ** 2)) ** 0.5
distance = distance.ceil
distance - 1
end
end end

0 comments on commit 1567889

Please sign in to comment.