87. Sharks and Fish

This example solution is fairly long but relatively straightforward, so I won't include its code here. Instead, I'll describe the key features of each of the program's classes.

The Ocean class uses a two-dimensional array named Grid to hold the simulation's Animal objects. The class keeps separate lists of the current sharks and fish so it can loop through them easily. It also stores shark and fish parameters such as the amount of energy a shark loses each turn and the amount of energy a shark gains when it eats a fish.

This Ocean class also defines the following helper methods:

  • MakeFish—Makes a specified number of randomly positioned fish.
  • MakeSharksMakes a specified number of randomly positioned sharks.
  • FreeSpotsReturns a list of spots adjacent to a given position. If the ignoreFish parameter is true, the method includes positions containing fish. (So a shark can move onto a fish and eat it.)
  • PickSpotPicks a random position from a list of free spots.
  • MoveLoops through the fish and sharks and calls their Move methods.

The Animal class defines an empty, virtual Move method. The Shark and Fish classes override that method to take appropriate action. For example, the following code shows the Fish class's Move method:

public override void Move()
{
// Look for a free spot.
List<Point> spots = Ocean.FreeSpots(X, Y, false);
if (spots.Count > 0)
{
// Move.
Ocean.Bitmap.SetPixel(X, Y, Color.Black);
Ocean.Grid[X, Y] = null;

Point moveTo = spots.Random();
X = moveTo.X;
Y = moveTo.Y;
Ocean.Bitmap.SetPixel(X, Y, Fish.Color);
Ocean.Grid[X, Y] = this;
}

// Breed.
Breed();
}

This code calls the Ocean object's FreeSpots method to find a spot where the fish could move. If there are free spots, the fish erases its current position in the ocean's bitmap, moves to a randomly selected free spot, and draws itself on the bitmap in its new position.

The method then calls the following Breed method to see if the fish should breed:

// See if we should breed.
private void Breed()
{
if (--TimeUntilBreeding > 0) return;

// Breed.
TimeUntilBreeding = Ocean.FishBreedingTime;

// Position a child.
List<Point> spots = Ocean.FreeSpots(X, Y, false);
if (spots.Count == 0) return;

Point childSpot = spots.Random();
Ocean.Fishes.Add(new Fish(Ocean, Ocean.FishBreedingTime,
childSpot.X, childSpot.Y));
}

This method decrements the fish's time until breeding. If that time is still greater than zero, the method returns.

If the fish's time until breeding has reached zero, the method resets the time until breeding to its starting value. It then gets a list of free spots adjacent to the fish. If there are no free spots, the method returns without breeding.

Finally, if there are empty spots adjacent to the fish, the method creates a new child fish in one of them.

The Move method of the Shark class is somewhat similar to the version of the Fish class, except it follows the rules for sharks.

Download the SharksAndFish example solution to see additional details.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset