From c5ea73338a988f92695420c44e91e2b605cbd0fa Mon Sep 17 00:00:00 2001
From: "guillaume.garbay" <guillaume.garbay>
Date: Fri, 5 Jun 2015 07:55:08 +0000
Subject: [PATCH] Initial import.

---
 .classpath                                    |   6 +
 .project                                      |  17 ++
 .settings/org.eclipse.core.resources.prefs    |   2 +
 .settings/org.eclipse.jdt.core.prefs          |  11 +
 data/input/fish.xml                           |  31 +++
 data/input/fishLight.xml                      |  26 +++
 data/input/grid.xml                           |  11 +
 data/input/observersBatch.xml                 |  14 ++
 data/input/observersCharts.xml                |  28 +++
 src/main/java/pikelake/Cell.java              |  78 +++++++
 src/main/java/pikelake/Grid.java              |  81 +++++++
 src/main/java/pikelake/GridObserver.java      | 204 ++++++++++++++++++
 src/main/java/pikelake/Individual.java        |  51 +++++
 src/main/java/pikelake/pikes/Pike.java        |  45 ++++
 .../pikelake/pikes/PikeGrowthProcess.java     |  25 +++
 .../java/pikelake/pikes/PikeHuntProcess.java  |  89 ++++++++
 .../pikelake/pikes/PikeMortalityProcess.java  |  26 +++
 .../java/pikelake/pikes/PikeMovement.java     |  60 ++++++
 .../pikes/PikeObservationProcess.java         |  13 ++
 .../java/pikelake/pikes/PikePlopProcess.java  |  18 ++
 .../pikes/PikeReproductionProcess.java        |  72 +++++++
 src/main/java/pikelake/pikes/PikesGroup.java  |  64 ++++++
 .../pikelake/pikes/PikesPopulateProcess.java  |  33 +++
 23 files changed, 1005 insertions(+)
 create mode 100644 .classpath
 create mode 100644 .project
 create mode 100644 .settings/org.eclipse.core.resources.prefs
 create mode 100644 .settings/org.eclipse.jdt.core.prefs
 create mode 100644 data/input/fish.xml
 create mode 100644 data/input/fishLight.xml
 create mode 100644 data/input/grid.xml
 create mode 100644 data/input/observersBatch.xml
 create mode 100644 data/input/observersCharts.xml
 create mode 100644 src/main/java/pikelake/Cell.java
 create mode 100644 src/main/java/pikelake/Grid.java
 create mode 100644 src/main/java/pikelake/GridObserver.java
 create mode 100644 src/main/java/pikelake/Individual.java
 create mode 100644 src/main/java/pikelake/pikes/Pike.java
 create mode 100644 src/main/java/pikelake/pikes/PikeGrowthProcess.java
 create mode 100644 src/main/java/pikelake/pikes/PikeHuntProcess.java
 create mode 100644 src/main/java/pikelake/pikes/PikeMortalityProcess.java
 create mode 100644 src/main/java/pikelake/pikes/PikeMovement.java
 create mode 100644 src/main/java/pikelake/pikes/PikeObservationProcess.java
 create mode 100644 src/main/java/pikelake/pikes/PikePlopProcess.java
 create mode 100644 src/main/java/pikelake/pikes/PikeReproductionProcess.java
 create mode 100644 src/main/java/pikelake/pikes/PikesGroup.java
 create mode 100644 src/main/java/pikelake/pikes/PikesPopulateProcess.java

diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..9aa3736
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="lib" path="C:/Users/guillaume.garbay/workspace/Lib/SimAquaLife/simaqualife-2.0.jar"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/.project b/.project
new file mode 100644
index 0000000..9dd8a95
--- /dev/null
+++ b/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>PikeLake</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..e532d98
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding//data/input=ISO-8859-1
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..bb35fa0
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,11 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.debug.lineNumber=generate
+org.eclipse.jdt.core.compiler.debug.localVariable=generate
+org.eclipse.jdt.core.compiler.debug.sourceFile=generate
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/data/input/fish.xml b/data/input/fish.xml
new file mode 100644
index 0000000..1be074a
--- /dev/null
+++ b/data/input/fish.xml
@@ -0,0 +1,31 @@
+<list>
+  <pikelake.pikes.PikesGroup>
+    <weightAtAgeThreshold>5.0</weightAtAgeThreshold>
+    <monthOfBirth>6</monthOfBirth>
+    <processes>
+      <processesAtBegin>
+        <pikelake.pikes.PikesPopulateProcess>
+          <initialNumberOfPikes>5</initialNumberOfPikes>
+        </pikelake.pikes.PikesPopulateProcess>
+      </processesAtBegin>
+      <processesEachStep>
+        <pikelake.pikes.PikeMovement/>
+        <pikelake.pikes.PikeHuntProcess>
+          <satiety>0.5</satiety>
+        </pikelake.pikes.PikeHuntProcess>
+        <pikelake.pikes.PikeGrowthProcess>
+          <convertionFactor>0.25</convertionFactor>
+          <slimRate>0.9</slimRate>
+        </pikelake.pikes.PikeGrowthProcess>
+        <pikelake.pikes.PikeMortalityProcess/>
+        <pikelake.pikes.PikeReproductionProcess>
+        		<ageAtFirstReproduction>5</ageAtFirstReproduction>
+        		<pikeFertility>1.3</pikeFertility>
+        </pikelake.pikes.PikeReproductionProcess>        
+        <pikelake.pikes.PikeObservationProcess/>
+        <fr.cemagref.simaqualife.kernel.processes.FireAquaNismsChangesToObservers/>
+       </processesEachStep>
+    </processes>
+    <useCemetery>false</useCemetery>
+  </pikelake.pikes.PikesGroup>
+</list>
\ No newline at end of file
diff --git a/data/input/fishLight.xml b/data/input/fishLight.xml
new file mode 100644
index 0000000..0ce26be
--- /dev/null
+++ b/data/input/fishLight.xml
@@ -0,0 +1,26 @@
+<list>
+  <pikelake.pikes.PikesGroup>
+    <weightAtAgeThreshold>5.0</weightAtAgeThreshold>
+    <monthOfBirth>6</monthOfBirth>
+    <processes>
+      <processesAtBegin>
+        <pikelake.pikes.PikesPopulateProcess>
+          <initialNumberOfPikes>1</initialNumberOfPikes>
+        </pikelake.pikes.PikesPopulateProcess>
+      </processesAtBegin>
+      <processesEachStep>
+        <pikelake.pikes.PikeMovement/>
+        <pikelake.pikes.PikeHuntProcess>
+          <satiety>0.5</satiety>
+        </pikelake.pikes.PikeHuntProcess>
+        <pikelake.pikes.PikeGrowthProcess>
+          <convertionFactor>0.25</convertionFactor>
+          <slimRate>0.9</slimRate>
+        </pikelake.pikes.PikeGrowthProcess>
+        <pikelake.pikes.PikeObservationProcess/>
+        <fr.cemagref.simaqualife.kernel.processes.FireAquaNismsChangesToObservers/>
+       </processesEachStep>
+    </processes>
+    <useCemetery>false</useCemetery>
+  </pikelake.pikes.PikesGroup>
+</list>
\ No newline at end of file
diff --git a/data/input/grid.xml b/data/input/grid.xml
new file mode 100644
index 0000000..5ca1d3d
--- /dev/null
+++ b/data/input/grid.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="ISO-8859-1"?> 
+<pikelake.Grid>
+	<torusType>BOTH</torusType>
+	<neighborsType>NEIGHBORHOOD_VON_NEUMANN</neighborsType>
+  <preyCarryingCapacity>50</preyCarryingCapacity>
+  <gridWidth>10</gridWidth>
+  <gridHeight>10</gridHeight>
+  <habitatValue0>0.25</habitatValue0>
+  <habitatValue1>0.5</habitatValue1>
+  <habitatValue2>1</habitatValue2>
+</pikelake.Grid>
\ No newline at end of file
diff --git a/data/input/observersBatch.xml b/data/input/observersBatch.xml
new file mode 100644
index 0000000..54ed95b
--- /dev/null
+++ b/data/input/observersBatch.xml
@@ -0,0 +1,14 @@
+<hashtable>
+  <entry>
+    <java-class>pikeprey.pikes.PikesGroup</java-class>
+    <fr.cemagref.observation.kernel.ObservablesHandler>
+      <observers>
+      	<fr.cemagref.observation.observers.CSVObserver>
+          <separator>;</separator>
+          <sysout>false</sysout>
+          <outputFile>data/pikes.txt</outputFile>
+        </fr.cemagref.observation.observers.CSVObserver>
+      </observers>
+    </fr.cemagref.observation.kernel.ObservablesHandler>
+  </entry>
+</hashtable>
diff --git a/data/input/observersCharts.xml b/data/input/observersCharts.xml
new file mode 100644
index 0000000..d838176
--- /dev/null
+++ b/data/input/observersCharts.xml
@@ -0,0 +1,28 @@
+<hashtable>
+  <entry>
+    <java-class>pikelake.pikes.PikesGroup</java-class>
+    <fr.cemagref.observation.kernel.ObservablesHandler>
+      <observers>
+      	<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
+      		<graphType>LINE</graphType>
+      		<title>Observation of pikes biomass</title>
+      		<xAxisLabel>Time (month)</xAxisLabel>
+      		<yAxisLabel>pikes biomass</yAxisLabel>
+    	</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
+      </observers>
+    </fr.cemagref.observation.kernel.ObservablesHandler>
+  </entry>
+  <entry>
+    <java-class>pikelake.pikes.Pike</java-class>
+    <fr.cemagref.observation.kernel.ObservablesHandler>
+      <observers>
+      	<fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
+      		<graphType>LINE</graphType>
+      		<title>Observation of pikes</title>
+      		<xAxisLabel>Time (month)</xAxisLabel>
+      		<yAxisLabel></yAxisLabel>
+    	</fr.cemagref.observation.observers.jfreechart.TemporalSerieChart>
+      </observers>
+    </fr.cemagref.observation.kernel.ObservablesHandler>
+  </entry>
+</hashtable>
diff --git a/src/main/java/pikelake/Cell.java b/src/main/java/pikelake/Cell.java
new file mode 100644
index 0000000..95fbff0
--- /dev/null
+++ b/src/main/java/pikelake/Cell.java
@@ -0,0 +1,78 @@
+package pikelake;
+
+import fr.cemagref.simaqualife.extensions.spatial2D.Grid2D;
+import fr.cemagref.simaqualife.extensions.spatial2D.IndexedCell;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import pikelake.pikes.Pike;
+// import predatorprey.preys.Prey;	/////////////////////////////////////////////////////////////////
+
+public class Cell extends IndexedCell {
+
+    /**
+     * <code>preyCarryingCapacity</code> number of preys that this place can
+     * support
+     */
+//    private int preyCarryingCapacity;	/////////////////////////////////////////////////////////////////
+
+    /**
+     * <code>habitatQuality</code> The quality of this place (pike point of
+     * view). A high value means that preys are vulnerable for the pikes
+     */
+    private double habitatQuality;
+
+    /**
+     * <code>preys</code> The list of preys in this place
+     */
+//    private transient List<Prey> preys;	/////////////////////////////////////////////////////////////////
+
+    /**
+     * <code>pikes</code> The list of pikes in this place
+     */
+    private transient List<Pike> pikes;
+
+    public Cell(int index, double habitatQuality) { //	, int preyCarryingCapacity) {	//////////////////////
+        super(index);
+        this.habitatQuality = habitatQuality;
+//        this.preyCarryingCapacity = preyCarryingCapacity;	/////////////////////////////////////////////////////////////////
+
+//        preys = new ArrayList<Prey>();	/////////////////////////////////////////////////////////////////
+        pikes = new ArrayList<Pike>();
+    }
+
+//    public List<Prey> getPreys() {	/////////////////////////////////////////////////////////////////
+//        return preys;	/////////////////////////////////////////////////////////////////
+//    }	/////////////////////////////////////////////////////////////////
+
+    public List<Pike> getPikes() {
+        return pikes;
+    }
+
+//    public boolean addPrey(Prey prey) {	/////////////////////////////////////////////////////////////////
+//        return preys.add(prey);	/////////////////////////////////////////////////////////////////
+//    }	/////////////////////////////////////////////////////////////////
+
+//    public boolean removePrey(Prey prey) {	/////////////////////////////////////////////////////////////////
+//        return preys.remove(prey);	/////////////////////////////////////////////////////////////////
+//    }	/////////////////////////////////////////////////////////////////
+
+    public boolean addPike(Pike pike) {
+        return pikes.add(pike);
+    }
+
+    public boolean removePike(Pike pike) {
+        return pikes.remove(pike);
+    }
+
+    public double getHabitatQuality() {
+        return habitatQuality;
+    }
+
+//    public int getPreyCarryingCapacity() {	/////////////////////////////////////////////////////////////////
+//        return preyCarryingCapacity;	/////////////////////////////////////////////////////////////////
+//    }	/////////////////////////////////////////////////////////////////
+
+}
diff --git a/src/main/java/pikelake/Grid.java b/src/main/java/pikelake/Grid.java
new file mode 100644
index 0000000..82bb128
--- /dev/null
+++ b/src/main/java/pikelake/Grid.java
@@ -0,0 +1,81 @@
+package pikelake;
+
+import fr.cemagref.simaqualife.extensions.spatial2D.Grid2D;
+import fr.cemagref.simaqualife.extensions.spatial2D.Grid2D.NeighborsType;
+import fr.cemagref.simaqualife.kernel.AquaNismsGroup;
+import fr.cemagref.simaqualife.kernel.util.TransientParameters.InitTransientParameters;
+import fr.cemagref.simaqualife.pilot.Pilot;
+import pikelake.pikes.Pike;
+//import predatorprey.preys.Prey;
+import umontreal.iro.lecuyer.probdist.UniformDist;
+import umontreal.iro.lecuyer.randvar.UniformGen;
+
+public class Grid extends Grid2D<Cell, Individual> {
+
+    public Grid(int gridWidth, int gridHeight, NeighborsType neighborsType) {
+        super(gridWidth, gridHeight, neighborsType);
+        // TODO Auto-generated constructor stub
+    }
+
+    /**
+     * <code>preyCarryingCapacity</code> number of preys that a cell can support
+     */
+//    private int preyCarryingCapacity;
+    private double habitatValue0 = .25;
+    private double habitatValue1 = .5;
+    private double habitatValue2 = 1;
+
+    transient private UniformGen uniformGen;
+    transient private double[] habitatValues;
+
+    @InitTransientParameters
+    public void initTransientParameters(Pilot pilot) {
+
+        this.pos = neighborsType.getPos();
+
+        habitatValues = new double[3];
+        habitatValues[0] = habitatValue0;
+        habitatValues[1] = habitatValue1;
+        habitatValues[2] = habitatValue2;
+
+        UniformGen uniformGen = new UniformGen(pilot.getRandomStream(), new UniformDist(0, habitatValues.length - 1));
+
+        grid = new Cell[gridWidth * gridHeight];
+        for (int i = 0; i < grid.length; i++) {
+            double hab = habitatValues[(int) Math.round(uniformGen.nextDouble())];
+            grid[i] = new Cell(i, hab); // , preyCarryingCapacity); 	/////////////////////////////////////////////////////////////////
+        }
+    }
+
+    @Override
+    public void addAquaNism(Individual ind, AquaNismsGroup group) {
+        super.addAquaNism(ind, group);
+//        if (ind instanceof Prey) {	/////////////////////////////////////////////////////////////////
+//            ind.getPosition().addPrey((Prey) ind);	/////////////////////////////////////////////////////////////////
+//        } else {	/////////////////////////////////////////////////////////////////
+            ind.getPosition().addPike((Pike) ind);
+//        }	/////////////////////////////////////////////////////////////////
+    }
+
+    @Override
+    public void moveAquaNism(Individual ind, AquaNismsGroup group, Cell dest) {
+        super.moveAquaNism(ind, group, dest);
+        this.removeAquaNism(ind, group);
+//        if (ind instanceof Prey) {	/////////////////////////////////////////////////////////////////
+//            dest.addPrey((Prey) ind);	/////////////////////////////////////////////////////////////////
+//        } else {	/////////////////////////////////////////////////////////////////
+            dest.addPike((Pike) ind);
+//        }	/////////////////////////////////////////////////////////////////
+    }
+
+    @Override
+    public void removeAquaNism(Individual ind, AquaNismsGroup group) {
+        super.removeAquaNism(ind, group);
+//        if (ind instanceof Prey) {	/////////////////////////////////////////////////////////////////
+//            ind.getPosition().removePrey((Prey) ind);	/////////////////////////////////////////////////////////////////
+//        } else {	/////////////////////////////////////////////////////////////////
+            ind.getPosition().removePike((Pike) ind);
+//        }	/////////////////////////////////////////////////////////////////
+    }
+
+}
diff --git a/src/main/java/pikelake/GridObserver.java b/src/main/java/pikelake/GridObserver.java
new file mode 100644
index 0000000..ab6b9cb
--- /dev/null
+++ b/src/main/java/pikelake/GridObserver.java
@@ -0,0 +1,204 @@
+package pikelake;
+
+import java.awt.BasicStroke;
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Shape;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import java.awt.geom.Rectangle2D;
+
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+
+import fr.cemagref.observation.gui.Configurable;
+import fr.cemagref.observation.gui.Drawable;
+import fr.cemagref.observation.kernel.ObservablesHandler;
+import fr.cemagref.observation.kernel.ObserverListener;
+import fr.cemagref.ohoui.annotations.Description;
+import fr.cemagref.ohoui.annotations.NoRecursive;
+import fr.cemagref.ohoui.filters.NoTransientField;
+import fr.cemagref.ohoui.swing.OhOUI;
+import fr.cemagref.ohoui.swing.OhOUIDialog;
+import fr.cemagref.simaqualife.kernel.util.TransientParameters;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+@SuppressWarnings("serial")
+@NoRecursive
+public class GridObserver extends ObserverListener implements Configurable, Drawable, MouseMotionListener {
+
+    private transient JComponent display;
+    private transient JLabel label;
+    private transient Grid grid;
+    
+    private String title;
+    
+    private Color envColor = Color.GREEN;
+    private Color preyColor = Color.BLUE;
+    private Color pikeColor = Color.RED;
+    @Description (name="Background color",tooltip="Background color")
+    private Color bgColor = Color.WHITE;
+    
+    private transient int displayWidthBak,displayHeightBak;
+    private transient double cellSizeX, cellSizeY;
+    private transient int[] cellsAlpha;
+    
+    public String getTitle() {
+        return title;
+    }
+
+    public JComponent getDisplay() {
+        return display;
+    }
+    
+    public void valueChanged(ObservablesHandler clObservable, Object instance, long t) {
+        display.repaint();
+    }
+    
+    @TransientParameters.InitTransientParameters
+    public void init(Pilot pilot) {
+    	// init display component
+        display = new JPanel(new BorderLayout());
+        DisplayComponent displayComponent = new DisplayComponent();
+        displayComponent.addMouseMotionListener(this);
+        displayComponent.setVisible(true);
+        displayComponent.setDoubleBuffered(true);
+        label = new JLabel("");
+        display.add(displayComponent,BorderLayout.CENTER);
+        display.add(label,BorderLayout.PAGE_START);
+        grid = (Grid)pilot.getAquaticWorld().getEnvironment();
+
+        // init display variables
+        displayWidthBak = 0;
+        displayHeightBak = 0;
+        // compute HabitatQuality colors
+    	double cellsHabitatQualityMin = 0;
+        double cellsHabitatQualityMax = 0;
+    	cellsAlpha = new int[grid.getCells().length];
+    	if (grid.getCells().length > 0) {
+	    	cellsHabitatQualityMin = grid.getCells()[0].getHabitatQuality();
+	    	cellsHabitatQualityMax = grid.getCells()[0].getHabitatQuality();
+	    	for (int i = 1; i < grid.getCells().length; i++) {
+	    		if (grid.getCells()[i].getHabitatQuality() < cellsHabitatQualityMin)
+	    			cellsHabitatQualityMin = grid.getCells()[i].getHabitatQuality();
+	    		else if (grid.getCells()[i].getHabitatQuality() > cellsHabitatQualityMax)
+	    			cellsHabitatQualityMax = grid.getCells()[i].getHabitatQuality();
+	    	}
+    	}
+    	if (Double.compare(cellsHabitatQualityMax,cellsHabitatQualityMin) == 0) {
+    		for (int i = 0; i < grid.getCells().length; i++) {
+	    		cellsAlpha[i] = 255;
+	    	}
+    	} else {
+	    	for (int i = 0; i < grid.getCells().length; i++) {
+	    		cellsAlpha[i] = (int)(155 + 100*(grid.getCells()[i].getHabitatQuality() - cellsHabitatQualityMin)/(cellsHabitatQualityMax - cellsHabitatQualityMin));
+	    	}
+    	}
+    	// show the result
+        display.repaint();
+    }
+    
+    public void disable() {
+        display.setVisible(false);
+    }
+    
+    public static interface AsShapeConvertible {
+        public Shape getShape();
+    }
+
+    public void configure() {
+        OhOUIDialog dialog = OhOUI.getDialog(null,this,new NoTransientField());
+        dialog.setSize(new Dimension(500, 600));
+        dialog.setVisible(true);
+        display.repaint();
+    }
+
+    @Override
+    public void addObservable(ObservablesHandler classObservable) {
+    	// nothing to do
+    }
+
+    @Override
+    public void init() {
+        // nothing to do
+    }
+
+    @Override
+    public void close() {
+        // nothing to do
+    }
+    
+    private class DisplayComponent extends JComponent {
+        
+        @Override
+        protected synchronized void paintComponent(Graphics g) {
+            super.paintComponents(g);
+            Graphics2D g2d = (Graphics2D)g;
+            // determine if generalPath must be rescaled
+            if ( (this.getWidth() != displayWidthBak) || (this.getHeight() != displayHeightBak) ) {
+                // backup for comparaison in the next loop
+                displayWidthBak = this.getWidth();
+                displayHeightBak = this.getHeight();
+                cellSizeX = displayWidthBak/grid.getGridWidth();
+                cellSizeY = displayHeightBak/grid.getGridHeight();
+            }
+            // Draw Background
+            g.setColor(bgColor);
+            g2d.setStroke(new BasicStroke(3));
+            g.fillRect(0, 0, getWidth(), getHeight());
+            Rectangle2D.Double cellRect = null;
+            Rectangle2D.Double pikeRect = null;
+            double preyDiameterX, preyDiameterY, pikeWidth, pikeHeight;
+            // draw each cell
+            for (int i = 0; i < grid.getCells().length; i++) {
+            	// the bounds of a cell
+            	cellRect = new Rectangle2D.Double((int)cellSizeX*(i%grid.getGridWidth()), (int)cellSizeY*(i/grid.getGridHeight()), (int)cellSizeX, (int)cellSizeY);
+            	// filling the cell with a color corresponding to the habitat level
+            	g.setColor(new Color(envColor.getRed(),envColor.getGreen(),envColor.getBlue(),cellsAlpha[i]));
+            	g2d.fill(cellRect);
+            	// drawing preys
+            	if (grid.getCells()[i].getPreys().size() > 0) {
+            	    g.setColor(preyColor);
+            	    preyDiameterX = cellRect.width*(double)grid.getCells()[i].getPreys().size()/grid.getCells()[i].getPreyCarryingCapacity();
+            	    preyDiameterY = cellRect.height*(double)grid.getCells()[i].getPreys().size()/grid.getCells()[i].getPreyCarryingCapacity();
+            	    g.fillOval((int)(cellRect.x + (cellRect.width - preyDiameterX)/2), (int)(cellRect.y + (cellRect.height - preyDiameterY)/2), (int)preyDiameterX, (int)preyDiameterY);
+            	    // represention as pie ... not very pretty
+            	    /*g2d.fill(new Arc2D.Double(cellRect,90,-360*((double)grid.getCells()[i].getPreys().size()/grid.getCells()[i].getPreyCarryingCapacity()),Arc2D.PIE));
+                    g2d.draw(new Arc2D.Double(cellRect,90,360,Arc2D.OPEN));*/
+                }
+            	// drawing pikes presence
+                if (grid.getCells()[i].getPikes().size() > 0) {
+                    g.setColor(pikeColor);
+                    pikeWidth = cellRect.width / 3;
+                    pikeHeight = cellRect.height / 3;
+                	pikeRect = new Rectangle2D.Double(cellRect.x + (cellRect.width - pikeWidth)/2, cellRect.y + (cellRect.height - pikeHeight)/2, pikeWidth, pikeHeight);
+                	g2d.draw(pikeRect);
+                	g2d.drawString(""+grid.getCells()[i].getPikes().size(), (float)(cellRect.x + cellRect.width/2 - 5), (float)pikeRect.y+(float)pikeRect.height-1);
+                }
+            }
+        }
+    }
+    
+    public void mouseDragged(MouseEvent e) {}
+
+    public void mouseMoved(MouseEvent e) {
+        int y = (int)(e.getY()/cellSizeY);
+        int x = (int)(e.getX()/cellSizeX);
+        Cell cell = grid.getCells()[grid.getGridWidth()*Math.min(y,grid.getGridHeight()-1) + Math.min(x,grid.getGridWidth()-1)];
+        label.setText("( "+x+" , "+y+" ) : habitat value = "+cell.getHabitatQuality()+" / "+cell.getPreys().size() + " preys ( max = "+cell.getPreyCarryingCapacity()+") and " + cell.getPikes().size()+ " pikes.");
+    }
+
+    public static void main (String [] args){
+    	System.out.println((new XStream(new DomDriver())).toXML(new GridObserver()));
+    }
+
+
+
+}
diff --git a/src/main/java/pikelake/Individual.java b/src/main/java/pikelake/Individual.java
new file mode 100644
index 0000000..693ce30
--- /dev/null
+++ b/src/main/java/pikelake/Individual.java
@@ -0,0 +1,51 @@
+package pikelake;
+
+import fr.cemagref.observation.kernel.Observable;
+import fr.cemagref.simaqualife.kernel.AquaNism;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+public abstract class Individual extends AquaNism<Cell,Grid> implements Comparable<Individual> {
+    
+    /**
+     * <code>age</code> age of the individual in months
+     */
+    protected int age;
+    
+    /**
+     * <code>weight</code> weight of the individual in grams
+     */
+   @Observable(description = "weight (g)")
+   protected double weight;
+    
+    public Individual(Pilot pilot, Cell position) {
+        super(pilot, position);
+        this.age = 0;
+    }
+    
+    public Individual(Pilot pilot, Cell position, double weight) {
+        this(pilot, position);
+        this.weight = weight;
+    }
+
+    public final double getWeight() {
+        return weight;
+    }
+
+    public final void setWeight(double weight) {
+        this.weight = weight;
+    }
+
+    public final int getAge() {
+        return age;
+    }
+
+    public final void incAge() {
+        age++;
+    }
+  
+    public int compareTo (Individual ind){
+    	return (int) Math.signum(this.weight - ind.weight);
+    }
+    
+
+}
diff --git a/src/main/java/pikelake/pikes/Pike.java b/src/main/java/pikelake/pikes/Pike.java
new file mode 100644
index 0000000..2a787f1
--- /dev/null
+++ b/src/main/java/pikelake/pikes/Pike.java
@@ -0,0 +1,45 @@
+package pikelake.pikes;
+
+import fr.cemagref.simaqualife.pilot.Pilot;
+import Pike.Cell;
+import Pike.Individual;
+
+public class Pike extends Individual {
+
+	private double ingestedFood=0.;
+	
+    public Pike(Pilot pilot, Cell cell) {
+    	//TODO fix weight according to the weightAtAgeThreshold
+        // Default value of weight at birth
+    	this(pilot, cell, 0, 10.);
+    }
+    
+    public Pike(Pilot pilot, Cell cell, int age, double weight) {
+        super(pilot, cell);
+        this.age =age;
+        this.weight = weight;
+    }
+    
+
+	public double getIngestedFood() {
+		return ingestedFood;
+	}
+
+	public void setIngestedFood(double ingestedFood) {
+		this.ingestedFood = ingestedFood;
+	}
+	public void addIngestedFood(double ingestedFood) {
+		this.ingestedFood += ingestedFood;
+	}
+	
+	public double getSuitabilityForPike(Cell cell){
+		if (cell.getPikes().size()>1)
+			return 0.; // at least an other pike in the cell
+		else
+			return 1.; /////////////////////////////////////////////////////////
+			//return((double) cell.getPreys().size()) * cell.getHabitatQuality(); // number of preys accessible
+	}
+	
+	
+}
+
diff --git a/src/main/java/pikelake/pikes/PikeGrowthProcess.java b/src/main/java/pikelake/pikes/PikeGrowthProcess.java
new file mode 100644
index 0000000..992d1c5
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikeGrowthProcess.java
@@ -0,0 +1,25 @@
+package pikelake.pikes;
+
+import fr.cemagref.simaqualife.kernel.AquaNismsGroup;
+import fr.cemagref.simaqualife.kernel.processes.LoopAquaNismsGroupProcess;
+
+public class PikeGrowthProcess extends LoopAquaNismsGroupProcess<Pike,AquaNismsGroup<Pike,?>> {
+
+	/**
+	 * <code>convertionFactor</code> proportion of the ingested food transformed into pike weight 
+	 */
+	private double convertionFactor = 0.25;
+	private double slimRate = 0.90;
+	
+	@Override
+	protected void doProcess(Pike pike, AquaNismsGroup<Pike, ?> group) {
+		pike.incAge();
+		//System.out.print("  "+ (double) pike.getAge()/12. +"y "+pike.getWeight()+ " " );
+		pike.setWeight( pike.getWeight() * slimRate + pike.getIngestedFood()* convertionFactor);
+		//System.out.print(pike.getIngestedFood() +" " + pike.getWeight());
+		//double ratio = 12* pike.getWeight()/(pike.getAge()+12);
+		//System.out.println("("+ ((double) Math.round(ratio*100))/100 +")");
+		pike.setIngestedFood(0.0);
+	}
+
+}
diff --git a/src/main/java/pikelake/pikes/PikeHuntProcess.java b/src/main/java/pikelake/pikes/PikeHuntProcess.java
new file mode 100644
index 0000000..b2321e2
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikeHuntProcess.java
@@ -0,0 +1,89 @@
+package pikelake.pikes;
+
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import pikelake.Cell;
+//	import predatorprey.preys.Prey;	////////////////////////////////////////////////////////////
+//	import predatorprey.preys.PreysGroup;	////////////////////////////////////////////////////
+import umontreal.iro.lecuyer.probdist.UniformDist;
+import umontreal.iro.lecuyer.randvar.UniformGen;
+import fr.cemagref.simaqualife.kernel.AquaNismsGroup;
+import fr.cemagref.simaqualife.kernel.processes.LoopAquaNismsGroupProcess;
+import fr.cemagref.simaqualife.kernel.util.TransientParameters.InitTransientParameters;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+/**
+ * @author patrick.lambert
+ * 
+ */
+public class PikeHuntProcess extends
+LoopAquaNismsGroupProcess<Pike, AquaNismsGroup<Pike, ?>> {
+
+	/**
+	 * <code>satiety</code> ratio of the pike weigth which stops eating
+	 * preys
+	 */
+	private double satiety = 0.10;
+
+	transient private UniformGen uniformGen;
+
+	@Override
+	protected void doProcess(Pike pike,
+			AquaNismsGroup<Pike, ?> group) {
+		Cell pikeCell = pike.getPosition();
+/*		if (pikeCell.getPreys().size() > 0) {
+			//System.out.print(" " +  pikeCell.getPreys().size() +" preys available in cell ");
+			//System.out.print("("+pikeCell.getX()+","+pikeCell.getY()+")");
+			
+			// sort the preys list according to the weigth
+			List<Prey> sortedPreys = pikeCell.getPreys();
+			Collections.sort(sortedPreys);
+
+			double ratio = pike.getIngestedFood()/pike.getWeight();
+			int idx = 0;
+			int idxMax =  sortedPreys.size();
+			int target=0;
+			int eaten=0;
+			while ((pike.getIngestedFood()/pike.getWeight() < satiety) && (idx < idxMax)) {
+
+				// the probability for a prey to be eaten depends 
+				// on the habitat quality in the cell
+				if (uniformGen.nextDouble() < pikeCell.getHabitatQuality()){
+					// eat the prey
+					Prey eatenPrey = sortedPreys.get(target);
+					pike.addIngestedFood(eatenPrey.getWeight());
+
+					// and the prey dies
+					
+					((PreysGroup)group.getPilot().getAquaticWorld().getAquaNismsGroupsList().get(0)).removeAquaNism(eatenPrey);
+					//this.interAquanism(eatenPrey);
+					pikeCell.removePrey(eatenPrey);
+					eaten ++;
+				}
+				else
+					target ++;
+
+				idx++;
+				ratio = pike.getIngestedFood()/pike.getWeight();
+			}
+			ratio= ((double) Math.round(100*ratio))/100;
+			//System.out.println(", " + eaten + " preys eaten ("+ ratio +" ), still " +  pikeCell.getPreys().size());
+		}	*/
+
+	}
+
+	@InitTransientParameters
+	public void initTransientParameters(Pilot pilot) {
+		sorted = true;
+		comparator = new Comparator<Pike>() {
+			public int compare(Pike o1, Pike o2) {
+				return (int) Math.signum(o2.getWeight() - o1.getWeight());
+			}
+		};
+
+		uniformGen = new UniformGen(pilot.getRandomStream(), new UniformDist());
+	}
+
+}
diff --git a/src/main/java/pikelake/pikes/PikeMortalityProcess.java b/src/main/java/pikelake/pikes/PikeMortalityProcess.java
new file mode 100644
index 0000000..0056803
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikeMortalityProcess.java
@@ -0,0 +1,26 @@
+package pikelake.pikes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
+
+
+public class PikeMortalityProcess extends AquaNismsGroupProcess<Pike, PikesGroup>{
+
+	public void doProcess(PikesGroup group) {
+		List<Pike> deadPike = new ArrayList<Pike>();
+		for (Pike pike: group.getAquaNismsList()){
+			double ratio = (12. * pike.getWeight() / (double) (pike.getAge()+12));
+
+			if (ratio < group.getWeightAtAgeThreshold())
+				deadPike.add(pike);
+		}
+	    // update the pikesGroup
+		for (Pike pike: deadPike){
+			group.getAquaNismsList().remove(pike);
+			//ASK WHY
+			pike.getPosition().removePike(pike);
+		}
+	}
+}
diff --git a/src/main/java/pikelake/pikes/PikeMovement.java b/src/main/java/pikelake/pikes/PikeMovement.java
new file mode 100644
index 0000000..554f5de
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikeMovement.java
@@ -0,0 +1,60 @@
+package pikelake.pikes;
+
+import fr.cemagref.simaqualife.kernel.processes.LoopAquaNismsGroupProcess;
+import fr.cemagref.simaqualife.kernel.util.TransientParameters.InitTransientParameters;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import pikelake.Cell;
+import umontreal.iro.lecuyer.probdist.UniformDist;
+import umontreal.iro.lecuyer.randvar.UniformGen;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+public class PikeMovement extends LoopAquaNismsGroupProcess<Pike, PikesGroup> {
+
+    transient private UniformGen uniformGen;
+
+    public PikeMovement(Pilot pilot) {
+        uniformGen = new UniformGen(pilot.getRandomStream(), new UniformDist());
+    }
+	@InitTransientParameters
+	public void initTransientParameters(Pilot pilot) {
+		uniformGen = new UniformGen(pilot.getRandomStream(), new UniformDist(0,1));
+	}
+    
+    
+    @Override
+    protected void doProcess(Pike pike, PikesGroup group) {
+
+        final List<Cell> surrounding = group.getEnvironment().
+        getNeighbours(pike.getPosition());
+
+        // the first possiblity is the cell where the prey is
+        List<Cell> possibilities = new ArrayList<Cell>();
+        possibilities.add(pike.getPosition());
+        double cellSuitability = pike.getSuitabilityForPike(pike.getPosition());
+
+        // identify the destination possibilities in the neighbouring
+        // with the highest suitability
+        for (Cell cell : surrounding) {
+            double currentCellSuitability = pike.getSuitabilityForPike(cell);
+            if (currentCellSuitability > cellSuitability) {
+                cellSuitability = currentCellSuitability;
+                possibilities.clear();
+                possibilities.add(cell);
+            } else if (currentCellSuitability == cellSuitability) {
+                possibilities.add(cell);
+            }
+        }
+
+        // choose the destination cell
+        int possibilitiesNumber = possibilities.size();
+        if (possibilitiesNumber == 1) {
+            pike.moveTo(group.getPilot(), possibilities.get(0), group);
+        } else {
+            int idx = (int) Math.floor(uniformGen.nextDouble() * (double) possibilitiesNumber);
+            pike.moveTo(group.getPilot(), possibilities.get(idx), group);
+        }
+    }
+}
diff --git a/src/main/java/pikelake/pikes/PikeObservationProcess.java b/src/main/java/pikelake/pikes/PikeObservationProcess.java
new file mode 100644
index 0000000..8d20846
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikeObservationProcess.java
@@ -0,0 +1,13 @@
+package pikelake.pikes;
+
+import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
+
+public class PikeObservationProcess extends AquaNismsGroupProcess<Pike,PikesGroup> {
+
+	public void doProcess(PikesGroup pikesGroup) {
+		pikesGroup.calculatePikesBiomass();
+		pikesGroup.calculatePikesNumber();
+		
+	}
+
+}
diff --git a/src/main/java/pikelake/pikes/PikePlopProcess.java b/src/main/java/pikelake/pikes/PikePlopProcess.java
new file mode 100644
index 0000000..9cb2eac
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikePlopProcess.java
@@ -0,0 +1,18 @@
+package pikelake.pikes;
+
+import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
+
+public class PlopProcess extends AquaNismsGroupProcess<Pike,PikesGroup> {
+
+	private int temporisation = 3000; // in ms
+	
+	public void doProcess(PikesGroup object) {
+    	try {
+			Thread.sleep(temporisation);
+		} catch (InterruptedException e) {
+			e.printStackTrace();
+		}
+		
+	}
+
+}
diff --git a/src/main/java/pikelake/pikes/PikeReproductionProcess.java b/src/main/java/pikelake/pikes/PikeReproductionProcess.java
new file mode 100644
index 0000000..4a2fcca
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikeReproductionProcess.java
@@ -0,0 +1,72 @@
+/**
+ * 
+ */
+package pikelake.pikes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import umontreal.iro.lecuyer.probdist.PoissonDist;
+import umontreal.iro.lecuyer.randvar.PoissonGen;
+
+import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+/**
+ * @author patrick.lambert
+ *
+ */
+public class PikeReproductionProcess extends AquaNismsGroupProcess<Pike,PikesGroup> {
+	
+	/**
+	 * <code>ageAtFirstReproduction</code> age at first reproduction (in year)
+	 */
+	private int ageAtFirstReproduction = 5;
+	
+	/**
+	 * <code>pikeFertility</code> mean number of offsprings per pike
+	 */
+	private double pikeFertility = 1.1;
+	
+	transient private PoissonGen poissonGen;
+
+	
+
+	public void initTransientParameters(Pilot pilot) {
+		poissonGen = new PoissonGen(pilot.getRandomStream(), new PoissonDist(pikeFertility));
+		
+	}
+	
+	public void doProcess(PikesGroup group) {
+		int offspring;
+		if (1+ ((group.getPilot().getCurrentTime()-1) % 12) == group.getMonthOfBirth()){
+			List<Pike> offsprings = new ArrayList<Pike>();
+			List<Pike> deadSpwaners = new ArrayList<Pike>();
+			for (Pike pike: group.getAquaNismsList()){
+				if (Math.floor((double) pike.getAge()/12.) >= ageAtFirstReproduction){
+					// number of offspring
+					offspring = poissonGen.nextInt();
+
+					System.out.println("  offspring #: "+ offspring);
+					for (int i=0; i<offspring ;i++)
+						offsprings.add(new Pike(group.getPilot(), pike.getPosition()));
+					// die after reproduction
+					//if (offspring > 0) // only if reproduce
+						deadSpwaners.add(pike);		
+				}	
+			}
+	    // update the pikesGroup
+		for (Pike pike: deadSpwaners){
+			group.getAquaNismsList().remove(pike);
+			//ASK WHY
+			pike.getPosition().removePike(pike);
+		}
+
+		for (Pike pike: offsprings)
+			group.addAquaNism(pike);
+			
+		}
+	}
+	
+	
+}
diff --git a/src/main/java/pikelake/pikes/PikesGroup.java b/src/main/java/pikelake/pikes/PikesGroup.java
new file mode 100644
index 0000000..c632769
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikesGroup.java
@@ -0,0 +1,64 @@
+package pikelake.pikes;
+
+import pikelake.Grid;
+import fr.cemagref.observation.kernel.Observable;
+import fr.cemagref.simaqualife.kernel.AquaNismsGroup;
+import fr.cemagref.simaqualife.kernel.Processes;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+
+public class PikesGroup extends AquaNismsGroup<Pike,Grid> {
+	
+	/**
+	 * <code>weightAtAgeThreshold</code> threshold of the ratio of  weight (in g) by age (in year)
+	 */
+	private double weightAtAgeThreshold = 5;
+	
+	
+	/**
+	 * <code>monthOfBirth</code> month of reproduction
+	 */
+	private int monthOfBirth = 6;
+	
+	
+	@Observable(description = "Pikes biomass (g)")
+	private transient double pikesBiomass;
+	
+	@Observable(description = "Pikes number")
+	private transient int pikesNumber;
+	
+	
+	
+	public PikesGroup(Pilot pilot, Grid arg0, Processes arg1) {
+		super(pilot, arg0, arg1);
+	}
+	
+	public int calculatePikesNumber(){
+		pikesNumber = this.getAquaNismsList().size();
+		
+		/*int pikesNumber2=0;
+		for (Cell cell: this.getEnvironment().getCells()){
+			pikesNumber2 += cell.getPikes().size();
+		}
+		System.out.println(" pred: "+pikesNumber + " " + pikesNumber2);*/
+		return pikesNumber;
+
+	}
+
+	public double calculatePikesBiomass(){
+		pikesBiomass =0.;
+			for(Pike pike : this.getAquaNismsList())
+				pikesBiomass += pike.getWeight();
+		return pikesBiomass;
+
+	}
+
+
+	public int getMonthOfBirth() {
+		return monthOfBirth;
+	}
+
+	public double getWeightAtAgeThreshold() {
+		return weightAtAgeThreshold;
+	}
+}
diff --git a/src/main/java/pikelake/pikes/PikesPopulateProcess.java b/src/main/java/pikelake/pikes/PikesPopulateProcess.java
new file mode 100644
index 0000000..bf8bacf
--- /dev/null
+++ b/src/main/java/pikelake/pikes/PikesPopulateProcess.java
@@ -0,0 +1,33 @@
+package pikelake.pikes;
+
+import pikelake.Cell;
+import umontreal.iro.lecuyer.probdist.UniformDist;
+import umontreal.iro.lecuyer.randvar.UniformGen;
+import fr.cemagref.simaqualife.kernel.processes.AquaNismsGroupProcess;
+import fr.cemagref.simaqualife.kernel.util.TransientParameters.InitTransientParameters;
+import fr.cemagref.simaqualife.pilot.Pilot;
+
+public class PikesPopulateProcess extends AquaNismsGroupProcess<Pike,PikesGroup> {
+
+	private int initialNumberOfPikes =5 ;
+	
+	transient private UniformGen uniformGen;
+	
+	@InitTransientParameters
+	public void initTransientParameters(Pilot pilot) {
+		double nbCell = (double) this.getGroup().getEnvironment().getCells().length;
+		uniformGen = new UniformGen(pilot.getRandomStream(), new UniformDist(0,nbCell-1));
+	}
+
+	public void doProcess(PikesGroup group) {
+		Cell[] cells = group.getEnvironment().getCells();
+		for (int i=0; i < initialNumberOfPikes ;i++){
+			int ageAtCreation = (int)(12+group.getPilot().getCurrentTime()-group.getMonthOfBirth())%12 +12*(i%5);
+			//int ageAtCreation =(int) (12+Pilot.getCurrentTime()-group.getMonthOfBirth())%12;
+			double weightAtCreation = 2*group.getWeightAtAgeThreshold() * (ageAtCreation+12) / 12;
+			Pike newPike = new Pike(group.getPilot(), cells[(int)Math.round(uniformGen.nextDouble())], 
+					ageAtCreation, weightAtCreation);
+    		group.addAquaNism(newPike);
+		}
+	}
+}
-- 
GitLab