Search⌘ K
AI Features

Solution: Sunflower vs. Zombies Game Simulation

Understand the object-oriented principles behind the Sunflower vs. Zombies game simulation in Ruby. Learn how classes, methods, and class variables control game mechanics such as movement, damage calculation, and tracking remaining zombies during the simulation.

We'll cover the following...

Solution

ZOMBIES_COUNT = 15
DISTANCE = 10

class Sunflower
  attr_accessor :health

  def initialize
    @health = 100
  end

  def exchange_fire(zombie)
    
    if zombie.in_touch_distance? 
      @health -= 5
    else
      @health -= (rand(2) + 1)
    end
    
    if @health <= 0 
      @health = 0
    end
    
    zombie.health -= (rand(31) + 10) # between 10 to 40 damage    
    zombie.die if zombie.health <= 0
  end
  
end


class Zombie
  @@live_count = 0
  attr_accessor :health, :steps
  attr_accessor :moving_speed
  
  def initialize
    @@live_count += 1     
    @health = 100
    @steps = 0
    @moving_speed = rand(10) >= 8  ?  2 : 1 # 80% are jumping zombies
  end
  
  def self.remaining_lives
    @@live_count
  end
  
  def die
    @health = 0
    @@live_count -= 1
  end
  
  def is_dead?
    @health <= 0
  end
  
  def in_touch_distance? 
    @steps == DISTANCE
  end
  
  def move_forward
    @steps += @moving_speed
    if @steps >= DISTANCE
      @steps = DISTANCE
    end
  end
end

print "\nF(100)  ___ ___ ___ ___ ___ ___ ___ ___ ___ ___"

sunflower = Sunflower.new
zombies = []
ZOMBIES_COUNT.times do 
  zombies << Zombie.new
end

active_zombie = nil

while (sunflower.health > 0) do 
  sleep 0.1  # adjust game speed, smaller number, faster
  
  if active_zombie.nil? || active_zombie.is_dead?
    active_zombie = zombies.shift unless zombies.empty?
  end
  
  break if zombies.empty? && (active_zombie.nil? || active_zombie.is_dead?) # no more zombies

  sunflower.exchange_fire(active_zombie)
  active_zombie.move_forward unless active_zombie.is_dead?

  # now print the latest battle field
  flower_health_str = sunflower.health.to_s.rjust(3, " ")
  print "\r"
  print "F(#{flower_health_str})  "
  
  zombie_pos = "Z#{active_zombie.health.to_s.rjust(2, '0')}"
  field = 10.times.collect {|x| 
    if active_zombie.steps == (10 - x)
      zombie_pos
    else
     "___"
    end    
  }.join(" ")
  print field
end

if sunflower.health > 0 
  puts "\n\nYou Win! Flower survived attacks from #{ZOMBIES_COUNT} zombies"
else
  puts "\n\nGame Over! #{Zombie.remaining_lives} zombies left"
end
Implementing sunflower vs zombies simulation

Explanation

  • Lines 1–2: We initialize the constants, ZOMBIES_COUNT and DISTANCE, to represent the total number of zombies and the field's distance in the simulation, respectively.

  • Lines 4–27: The Sunflower class is defined. It has the exchange_fire method (lines 11–25), which calculates the damage received by the sunflowers ...