/*----------------------------------------------------------------------+
|      Title:	Range.java                                              |
|                                                                       |
|      Author:	David E. Joyce                                          |
|           Department of Mathematics and Computer Science              |
|           Clark University                                            |
|           Worcester, MA 01610-1477                                    |
|           U.S.A.                                                      |
|                                                                       |
|           http://aleph0.clarku.edu/~djoyce/                           |
|           djoyce@clarku.edu                                           |
|                                                                       |
|      Date:    May, 2002.                                              |
+----------------------------------------------------------------------*/



import java.awt.*;

public class Range {

  private int population;
  int numberOfHerds;
  int selectedHerd;
  int day;

  Herd herd[];
  Genome L[][], R[][]; // the left- and right-moving bands
  Stats stats[][];

  public Range (int population, int numberOfHerds) {
    this.population = population;
    if (numberOfHerds < 1)
      numberOfHerds = 1;
    this.numberOfHerds = numberOfHerds;
    // initialize the herds and bands
    herd = new Herd[numberOfHerds];
    L = new Genome[numberOfHerds][];
    R = new Genome[numberOfHerds][];
    for (int h=0; h<numberOfHerds; ++h) {
      herd[h] = new Herd(population);
      L[h] = new Genome[population];
      R[h] = new Genome[population];
    }
    stats = new Stats[numberOfHerds][];
    selectedHerd = 0;
    day = 0;
 } // Range constructor

  public void doSimulation(double deathRate, int lengthOfMatch,
                           int payoff[][], double mutationRate, 
                           double mutationSize, double asexualRate) {
    day++;
    for (int h=0; h<numberOfHerds; ++h) {
      herd[h].runMatch(lengthOfMatch, payoff);
      // Now, remove some players due to death, randomly
      herd[h].death(deathRate);
      // Next, select new ones to replace the dead
      herd[h].birth(asexualRate);
      // Finally, mutate some of them
      herd[h].mutate(mutationRate, mutationSize);
    } // for
  } // doSimulation


  public void migrate(int bandSize) {
    // first bands leave the herds
    for (int h=0; h<numberOfHerds; ++h) {
      herd[h].migrateOut(bandSize,L[h]);
      herd[h].migrateOut(bandSize,R[h]);
    }
    // next they join the neighboring herds
    for (int h=0; h<numberOfHerds; ++h) {
      herd[(h+numberOfHerds-1) % numberOfHerds].migrateIn(bandSize,L[h]);
      herd[(h+1) % numberOfHerds].migrateIn(bandSize,R[h]);
    }
  } // migrate

  public void graphUpdate (ColorGraph colorGraph) {
    if (herd == null) return; // herd not initialized
    colorGraph.newData(herd[selectedHerd].getGenomeColor());
  } // graphUpdate

  public void statUpdate() {
    for (int h=0; h<numberOfHerds; ++h)
      stats[h] = herd[h].getStats();
  } // statUpdate

  public void barGraphUpdate (BarGraph barGraph) {
    barGraph.setValues(stats[selectedHerd]);
  } // barGraphUpdate

} // Range.java

