View Javadoc
1   package org.woehlke.computer.kurzweil.tabs.simulatedevolution;
2   
3   
4   import lombok.EqualsAndHashCode;
5   import lombok.Getter;
6   import lombok.ToString;
7   import lombok.extern.log4j.Log4j2;
8   import org.woehlke.computer.kurzweil.commons.tabs.TabModel;
9   import org.woehlke.computer.kurzweil.commons.model.LatticePoint;
10  import org.woehlke.computer.kurzweil.tabs.simulatedevolution.model.SimulatedEvolutionParameter;
11  import org.woehlke.computer.kurzweil.tabs.simulatedevolution.model.population.SimulatedEvolutionPopulationContainer;
12  import org.woehlke.computer.kurzweil.tabs.simulatedevolution.model.cell.Cell;
13  import org.woehlke.computer.kurzweil.tabs.simulatedevolution.model.SimulatedEvolutionWorldLattice;
14  import org.woehlke.computer.kurzweil.tabs.simulatedevolution.model.population.SimulatedEvolutionPopulation;
15  
16  import java.util.ArrayList;
17  import java.util.List;
18  import java.util.concurrent.ForkJoinTask;
19  
20  /**
21   * The World contains Water, Cells and Food.
22   * It is the Data Model of the Simulation in a MVC Pattern.
23   *
24   * @author Thomas Woehlke
25   * User: thomas
26   * Date: 04.02.2006
27   * Time: 19:06:20
28   * @see Cell
29   * @see SimulatedEvolutionWorldLattice
30   * <p>
31   * Simulated Evolution.
32   * Artificial Life Simulation of Bacteria Motion depending on DNA.
33   * <p>
34   * &copy; 2006 - 2008 Thomas Woehlke.
35   * http://thomas-woehlke.de/p/simulated-evolution/
36   */
37  @Log4j2
38  @Getter
39  @ToString(exclude={"appCtx"})
40  @EqualsAndHashCode(exclude={"appCtx"},callSuper = false)
41  public class SimulatedEvolutionModel extends ForkJoinTask<Void> implements TabModel, SimulatedEvolution {
42  
43      private final SimulatedEvolutionContext appCtx;
44      private final SimulatedEvolutionWorldLattice worldLattice;
45      private final SimulatedEvolutionPopulationContainer populationContainer;
46      private final SimulatedEvolutionParameter simulatedEvolutionParameter;
47      private Boolean running;
48      private SimulatedEvolutionPopulation population;
49  
50    public SimulatedEvolutionModel(
51        SimulatedEvolutionContext appCtx
52    ) {
53        this.appCtx = appCtx;
54        this.worldLattice = new SimulatedEvolutionWorldLattice(  this.appCtx);
55        this.populationContainer = new SimulatedEvolutionPopulationContainer( this.appCtx);
56        this.simulatedEvolutionParameter = new SimulatedEvolutionParameter();
57        this.running = Boolean.FALSE;
58        createNewState();
59    }
60  
61    public boolean hasFood(int x, int y) {
62      return worldLattice.hasFood(x, y);
63    }
64  
65      public void toggleGardenOfEden() {
66          log.info("toggleGardenOfEden");
67          this.worldLattice.toggleGardenOfEden();
68          this.simulatedEvolutionParameter.toggleGardenOfEden();
69      }
70  
71      public void start() {
72          log.info("start");
73          synchronized (running) {
74              running = Boolean.TRUE;
75          }
76          log.info("started "+this.toString());
77      }
78  
79      public void stop() {
80          log.info("stop");
81          synchronized (running) {
82              running = Boolean.FALSE;
83          }
84          log.info("stopped "+this.toString());
85      }
86  
87      public List<Cell> getAllCells() {
88          return populationContainer.getCells();
89      }
90  
91      private void createNewState(){
92          int foodPerDay = this.appCtx.getCtx().getProperties().getSimulatedevolution().getFood().getFoodPerDay();
93          int foodPerDayGardenOfEden = this.appCtx.getCtx().getProperties().getSimulatedevolution().getGardenOfEden().getFoodPerDay();
94          boolean gardenOfEdenEnabled = this.appCtx.getCtx().getProperties().getSimulatedevolution().getGardenOfEden().getGardenOfEdenEnabled();
95          this.simulatedEvolutionParameter.setFoodPerDay(foodPerDay);
96          this.simulatedEvolutionParameter.setFoodPerDayGardenOfEden(foodPerDayGardenOfEden);
97          this.simulatedEvolutionParameter.setGardenOfEdenEnabled(gardenOfEdenEnabled);
98      }
99  
100     public void increaseFoodPerDay() {
101         simulatedEvolutionParameter.increaseFoodPerDay();
102     }
103 
104     public void decreaseFoodPerDay(){
105         simulatedEvolutionParameter.decreaseFoodPerDay();
106     }
107 
108     @Override
109     public boolean cancel(boolean mayInterruptIfRunning) {
110         return false;
111     }
112 
113     @Override
114     public Void getRawResult() {
115         return null;
116     }
117 
118     @Override
119     protected void setRawResult(Void value) {
120 
121     }
122 
123     /**
124      * One Step of Time in the World in which the Population of Bacteria Cell perform Life.
125      * Every Cell moves, eats, dies of hunger, and it has sex. splitting into two children with changed DNA.
126      */
127     @Override
128     protected boolean exec() {
129         log.info("step");
130         boolean step;
131         synchronized (running) {
132             step = running;
133         }
134         if(step) {
135             worldLattice.letFoodGrow();
136             List<Cell> nextPopulation = new ArrayList<>();
137             LatticePoint pos;
138             int food;
139             for (Cell cell : populationContainer.getCells()) {
140                 pos = cell.getPosition();
141                 food = worldLattice.eat(pos);
142                 cell.eat(food);
143                 if (cell.move()) {
144                     pos = cell.getPosition();
145                     food = worldLattice.eat(pos);
146                     cell.eat(food);
147                     if (cell.isAbleForReproduction()) {
148                         Cell child = cell.reproductionByCellDivision();
149                         nextPopulation.add(child);
150                     }
151                 }
152                 if(!cell.died()){
153                     nextPopulation.add(cell);
154                 }
155             }
156             populationContainer.addNextPopulation(nextPopulation);
157             log.info("stepped");
158         } else {
159             log.info("not stepped");
160         }
161         population = populationContainer.getCurrentGeneration();
162         return true;
163     }
164 }