A programming practical exercise to be run as a Dojo.
It is based on Daniel Phelps code using Ruby and Gosu library.
The game consists on a few hunters trying to devour a lot of preys.
Those creatures, hunters and preys, are represented by dots on a window. At first, preys only move randomly across the screen and hunters chase the closest prey; being the target of the dojo to programm smarter classes that make preys to live more time or hunters to eat all preys faster. Hunters eat the preys if the move close enough to each other.
The creatures behavior is controlled by a method called
is the method we should overwrite to make our preys or hunters more clever.
update method we can check for our position, distance to other
creatures, etc; and we can set an acceleration from our actual position
letting preys escape for hunters or hunter to chase preys.
In addition to hunter and preys classes, we can add 'utils' or 'helpers' methods that can be used by creatures later, so we could program a method that calculates how close we are to a wall or the direction that we should take to escape from hunters.
Where to program the behavior and how to apply it is discussed in next section.
Adding helper methods
We can add new helper methods in
lib/assets.rb file like these:
module Assets def distance_to( particle ) Math.sqrt( (self.position[:x] - particle.position[:x]) ** 2 + (self.position[:y] - particle.position[:y]) ** 2 ) end def distance_to_closest_wall() ... end end
Any method defined in
lib/assets.rb is available for preys and hunters
Redefining the creature behavior
First, we have to choose one type of creature, preys or hunters (just to know
what we want to achieve). Once we know what improvement are we going to program,
we create a new file under
enhances/ directory (the name is not important as
it ends in '.rb').
Next step is to create a new module inside the file, named as we want, and inside
that module we overwrite the method
update( hunters, preys ). For example, if
we choose preys to enhance their behavior we can do this:
module NotReallyAnImprovement def update( hunters, preys ) hunter = self.closest( hunters ).first modulus = 1 direction = self.angle_to( hunter ) accelerate( modulus , -1 * direction ) end end
That make our preys accelerate in opposite direction of closest hunter as fast as they can. So, if we want to try this behavior we do the following:
ruby main.rb --preys NotReallyAnImprovement
This command loads the game using our recently created module to modify the
preys behavior. We could use the short option
-p to do the same, or use
-h to change the hunters behavior.
Sadly, once we run the game, we see that this code is not a good example of improvement as it make the preys life shorter but it illustrates well how the creatures behavior is modified.
Things to accomplish to be functional
- Hunters collisions - Done :)
- Successives simulation in order to calculate average lifetime
- Avoid infite loops by setting maximum lifetime for hunters if they don't eat
- Put some informational text on the screen
Every morning in Africa, a Gazelle wakes up and knows that it must run faster than the fastest Lion that day, or it will be killed and eaten. Every morning in Africa, a Lion wakes up and knows that it must run faster than the slowest Gazelle that day, or it will starve to death. It doesn't matter if you are a lion or a gazelle: when the sun comes up, you'd better be running.