From 62a553b71f1f4e5146f0f2f782fbab93bfc1f09e Mon Sep 17 00:00:00 2001 From: Paul Mathy Date: Fri, 31 May 2024 23:33:05 +0200 Subject: [PATCH] Projet_V4 --- - Copie.classpath | 10 + - Copie.project | 17 + .classpath | 10 + .project | 17 + src - Copie/Main.java | 23 ++ src - Copie/backend/Agent.java | 40 ++ src - Copie/backend/Cell.java | 17 + src - Copie/backend/Gride.java | 103 +++++ src - Copie/backend/Rules.java | 49 +++ src - Copie/backend/Sheep.java | 59 +++ src - Copie/backend/Simulator.java | 413 +++++++++++++++++++ src - Copie/windowInterface/JPanelDraw.java | 94 +++++ src - Copie/windowInterface/MyInterface.java | 397 ++++++++++++++++++ src/Main.java | 23 ++ src/backend/Agent.java | 40 ++ src/backend/Cell.java | 17 + src/backend/Gride.java | 103 +++++ src/backend/Rules.java | 49 +++ src/backend/Sheep.java | 59 +++ src/backend/Simulator.java | 413 +++++++++++++++++++ src/windowInterface/JPanelDraw.java | 94 +++++ src/windowInterface/MyInterface.java | 397 ++++++++++++++++++ 22 files changed, 2444 insertions(+) create mode 100644 - Copie.classpath create mode 100644 - Copie.project create mode 100644 .classpath create mode 100644 .project create mode 100644 src - Copie/Main.java create mode 100644 src - Copie/backend/Agent.java create mode 100644 src - Copie/backend/Cell.java create mode 100644 src - Copie/backend/Gride.java create mode 100644 src - Copie/backend/Rules.java create mode 100644 src - Copie/backend/Sheep.java create mode 100644 src - Copie/backend/Simulator.java create mode 100644 src - Copie/windowInterface/JPanelDraw.java create mode 100644 src - Copie/windowInterface/MyInterface.java create mode 100644 src/Main.java create mode 100644 src/backend/Agent.java create mode 100644 src/backend/Cell.java create mode 100644 src/backend/Gride.java create mode 100644 src/backend/Rules.java create mode 100644 src/backend/Sheep.java create mode 100644 src/backend/Simulator.java create mode 100644 src/windowInterface/JPanelDraw.java create mode 100644 src/windowInterface/MyInterface.java diff --git a/- Copie.classpath b/- Copie.classpath new file mode 100644 index 0000000..57bca72 --- /dev/null +++ b/- Copie.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/- Copie.project b/- Copie.project new file mode 100644 index 0000000..7b61216 --- /dev/null +++ b/- Copie.project @@ -0,0 +1,17 @@ + + + OOP + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..57bca72 --- /dev/null +++ b/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..7b61216 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + OOP + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/src - Copie/Main.java b/src - Copie/Main.java new file mode 100644 index 0000000..251f46f --- /dev/null +++ b/src - Copie/Main.java @@ -0,0 +1,23 @@ +/* +public class Main { + + public static void main(String[] args) { + // TODO Auto-generated method stub + System.out.println("toto"); + } + +}*/ + + +import windowInterface.MyInterface; + + +public class Main { + + + public static void main(String[] args) { + MyInterface mjf = new MyInterface(); + mjf.setVisible(true); + } + +} \ No newline at end of file diff --git a/src - Copie/backend/Agent.java b/src - Copie/backend/Agent.java new file mode 100644 index 0000000..9eeef1e --- /dev/null +++ b/src - Copie/backend/Agent.java @@ -0,0 +1,40 @@ +package backend; + +import java.awt.Color; +import java.util.ArrayList; + +public abstract class Agent { + protected int x; + protected int y; + protected Color color; + + protected Agent(int x, int y, Color color) { + this.x = x; + this.y = y; + this.color = color; + } + + public Color getDisplayColor() { + return color; + } + public int getX() { + return x; + } + public int getY() { + return y; + } + public boolean isInArea(int x, int y, int radius) { + int diffX = this.x-x; + int diffY = this.y-y; + int dist = (int) Math.floor(Math.sqrt(diffX*diffX+diffY*diffY)); + return dist neighbors, Simulator world); + + +} diff --git a/src - Copie/backend/Cell.java b/src - Copie/backend/Cell.java new file mode 100644 index 0000000..8151c46 --- /dev/null +++ b/src - Copie/backend/Cell.java @@ -0,0 +1,17 @@ +package backend; + +public class Cell { + private int value; + + public Cell(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} diff --git a/src - Copie/backend/Gride.java b/src - Copie/backend/Gride.java new file mode 100644 index 0000000..a87ff78 --- /dev/null +++ b/src - Copie/backend/Gride.java @@ -0,0 +1,103 @@ +package backend; + +import java.util.ArrayList; + +public class Gride { + private int height; + private int width; + private ArrayList> gride; + private Simulator simulator; + + public Gride(int height, int width, Simulator tempSimulator) { + this.height = height; + this.width = width; + this.simulator = tempSimulator; + + gride = new ArrayList<>(height); + + for (int i = 0; i < height; i++) { + this.gride.add(i, new ArrayList()); + for (int j = 0; j < width; j++) { + this.gride.get(i).add(new Cell(0)); + } + } + } + + public int getheight() { + return this.height; + } + + public int getwidth() { + return this.width; + } + public boolean isLoopingBorder() { + return simulator.isLoopingBorder(); + } + + public Cell getCell(int row,int column) { + return gride.get(row).get(column); + } + + public void setCell(int row, int column, Cell cell){ + this.gride.get(row).set(column, cell); + } + + public int countAround(int row, int column) { + int count = 0; + boolean loopingBorder = isLoopingBorder(); + + for (int i = row - 1; i <= row + 1; i++) { + for (int j = column - 1; j <= column + 1; j++) { + if (i == row && j == column) { + continue; + } + + int x = i; + int y = j; + + if (loopingBorder) { + x = (x + width) % width; + y = (y + height) % height; + } else { + if (x < 0 || x >= width || y < 0 || y >= height) { + continue; + } + } + + count += this.getCell(x, y).getValue(); + } + } + + return count; + } + + + + + //TODO : set agent (x y agent) load an agent to coordinates x,y + + //TODO : set random (density) create a random gride of determined density + public void setRandom(double density) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + double random = Math.random(); + if (random < density) { + gride.get(i).get(j).setValue(1); + } else { + gride.get(i).get(j).setValue(0); + } + } + } + System.out.println("Created a random field"); + } + + public void serialPrint(){ + for (int i = 0; i < height; i++) { + System.out.print("\n"); + for (int j = 0; j < width; j++) { + System.out.print(this.getCell(i, j).getValue() +" "); + } + } + } + +} diff --git a/src - Copie/backend/Rules.java b/src - Copie/backend/Rules.java new file mode 100644 index 0000000..a5f2862 --- /dev/null +++ b/src - Copie/backend/Rules.java @@ -0,0 +1,49 @@ +package backend; + +import java.util.ArrayList; + +import windowInterface.MyInterface; + + + +public class Rules { + + //Attributes + + private ArrayList fieldSurviveValues; + private ArrayList fieldBirthValues; + + + public Rules() { + + fieldSurviveValues = new ArrayList(); + fieldBirthValues = new ArrayList(); + + this.setConwayRules(); + } + + + public void resetRules() { + fieldSurviveValues.clear(); + fieldBirthValues.clear(); + } + + public void setConwayRules() { + this.fieldSurviveValues.clear(); + this.fieldBirthValues.clear(); + + //Set Conway rules + this.fieldSurviveValues.add(2); + this.fieldSurviveValues.add(3); + this.fieldBirthValues.add(3); + } + + public ArrayList getSurviveValues(){ + return fieldSurviveValues; + } + + + public ArrayList getBirthValues(){ + return fieldBirthValues; + } +} diff --git a/src - Copie/backend/Sheep.java b/src - Copie/backend/Sheep.java new file mode 100644 index 0000000..b05d141 --- /dev/null +++ b/src - Copie/backend/Sheep.java @@ -0,0 +1,59 @@ +package backend; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Random; + +// example of basic animal. +// do not hesitate to make it more complex +// and DO add at least another species that interact with it +// for example wolves that eat Sheep +public class Sheep extends Agent { + + int hunger; + Random rand; + + Sheep(int x,int y){ + //first we call the constructor of the superClass(Animal) + //with the values we want. + // here we decide that a Sheep is initially white using this constructor + super(x,y,Color.white); + // we give our sheep a hunger value of zero at birth + hunger = 0; + //we initialize the random number generator we will use to move randomly + rand = new Random(); + } + + /** + * action of the animal + * it can interact with the cells or with other animals + * as you wish + */ + public boolean liveTurn(ArrayList neighbors, Simulator world) { + if(world.getCell(x, y)==1) { + world.setCell(x, y, 0); + } else { + hunger++; + } + this.moveRandom(); + return hunger>10; + } + + private void moveRandom() { + int direction = rand.nextInt(4); + if(direction == 0) { + x+=1; + } + if(direction == 1) { + y+=1; + } + if(direction == 2) { + x-=1; + } + if(direction == 3) { + y-=1; + } + } + + +} diff --git a/src - Copie/backend/Simulator.java b/src - Copie/backend/Simulator.java new file mode 100644 index 0000000..e6f8bef --- /dev/null +++ b/src - Copie/backend/Simulator.java @@ -0,0 +1,413 @@ +package backend; +import java.util.ArrayList; +import java.util.ListIterator; + +import windowInterface.MyInterface; + +public class Simulator extends Thread { + + private MyInterface mjf; + + //Size of the grid + private final int COL_NUM = 100; + private final int LINE_NUM = 100; + private final int LIFE_TYPE_NUM = 4; + private final int LIFE_AREA_RADIUS = 1; + private final int ANIMAL_AREA_RADIUS = 2; + //private ArrayList fieldSurviveValues; + //private ArrayList fieldBirthValues; + + private ArrayList agents; + + private boolean stopFlag; + private boolean pauseFlag; + private boolean loopingBorder; + private boolean clickActionFlag; + private int loopDelay = 150; + + //TODO : add missing attribute(s) + private double randomDansitySlider = 0.5; + private int width; + private int height; + private Gride gride; + + //Step put here to be reset when generate new field + private int stepCount=0; + + private Rules rules; + + public Simulator(MyInterface mjfParam) { + mjf = mjfParam; + stopFlag=false; + pauseFlag=false; + loopingBorder=false; + clickActionFlag=true; + + agents = new ArrayList(); + + //fieldSurviveValues = new ArrayList(); + //fieldBirthValues = new ArrayList(); + + this.width=COL_NUM; + this.height=LINE_NUM; + gride = new Gride(height, width, this); + + //Reset rules to Conway rules + //this.resetRules(); + + rules = new Rules(); + + + } + + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } + + public void run() { + //int stepCount=0; + System.out.println("Step Count: "+ stepCount); + + //Set label when starting + mjf.setClickBanner("click : " + this.clickActionName()); + mjf.setBorderBanner("border : " + (this.isLoopingBorder()?"loop":"closed")); + + while(!stopFlag) { + stepCount++; + makeStep(); + mjf.update(stepCount); + try { + Thread.sleep(loopDelay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + while(pauseFlag && !stopFlag) { + try { + Thread.sleep(loopDelay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + + public void makeStep() { + + ListIterator iter = agents.listIterator(); + + while(iter.hasNext()){ + Agent agent = iter.next(); + + //System.out.println(agent.getX() + "," + agent.getY()); + + ArrayList neighbors = this.getNeighboringAnimals( + agent.getX(), + agent.getY(), + ANIMAL_AREA_RADIUS); + + + if(!agent.liveTurn( + neighbors, + this)) { + iter.remove(); + } + } + /* + for(Agent agent : agents) { + ArrayList neighbors = + this.getNeighboringAnimals( + agent.getX(), + agent.getY(), + ANIMAL_AREA_RADIUS); + if(!agent.liveTurn( + neighbors, + this)) { + agents.remove(agent); + } + } + */ + + + this.applyStep(); + + + } + + public void stopSimu() { + stopFlag=true; + } + + public void togglePause() { + pauseFlag = !pauseFlag; + } + + public void clickCell(int x, int y) { + + int currentCellValue = getCell(x, y); + + if (clickActionFlag == true) { + + int newCellValue = 0; + + if (currentCellValue == 0) { + newCellValue = 1; + } else { + newCellValue = 0; + } + this.setCell(x, y, newCellValue); + } else { + //Apply sheep /agent here + this.agents.add(new Sheep(x, y)); + } + + return; + } + + public int getCell(int x, int y) { + return this.gride.getCell(x,y).getValue(); + } + + public ArrayList getAnimals(){ + return agents; + } + + public ArrayList getNeighboringAnimals(int x, int y, int radius){ + ArrayList inArea = new ArrayList(); + for(int i=0;i getSaveState() { + ArrayList strArrayList = new ArrayList<>(); + String[] strArrayLine = new String[this.width]; + //Store the state of the GRID + for(int x=0 ;x lines) { + if(lines.size()<=0) { + return; + } + String firstLine = lines.get(0); + String[] firstLineElements = firstLine.split(";"); + if(firstLineElements.length<=0) { + return; + } + for(int y =0; y getRule() { + + ArrayList strArrayList = new ArrayList<>(); + + String[] strArrayLine = new String[rules.getSurviveValues().size()]; + + //Add survive values + for(int x=0; x lines) { + if(lines.size()<=0) { + System.out.println("empty rule file"); + return; + } + + + rules.resetRules(); + + String surviveLine = lines.get(0); + String birthLine = lines.get(1); + + String[] surviveElements = surviveLine.split(";"); + + //Load the values to survive + for(int x=0; x getAgentsSave() { + //TODO : Same idea as the other save method, but for agents + + ArrayList strArrayList = new ArrayList<>(); + String[] strArrayLine = new String[this.agents.size()]; + + for(int ii=0;ii stringArray) { + + if(stringArray.size()<=0) { + System.out.println("empty rule file"); + return; + } + + //Get the first line assuming it contains coordinates under format: X1,Y1;X2,Y2;X3,Y3 + String strFirstLine = stringArray.get(0); + + String[] strListCoordinates = strFirstLine.split(";"); + + //Loop on agent's coordinates and create one agent for each X,Y + for(int ii=0; ii stringArray = new ArrayList(); + if (fileName.length()>0) { + try { + BufferedReader fileContent = new BufferedReader(new FileReader(fileName)); + String line = fileContent.readLine(); + while (line != null) { + stringArray.add(line); + line = fileContent.readLine(); + } + fileContent.close(); + } catch (Exception e) { + e.printStackTrace(); + } + if(mySimu != null) { + mySimu.stopSimu(); + this.eraseLabels(); + } + loadedSim.loadSaveState(stringArray); + mySimu = loadedSim; + panelDraw.setSimu(mySimu); + this.repaint(); + } + } + + public void clicLoadRuleFileButton() { + String fileName=SelectFile(); + ArrayList stringArray = new ArrayList(); + if (fileName.length()>0) { + try { + BufferedReader fileContent = new BufferedReader(new FileReader(fileName)); + String line = fileContent.readLine(); + while (line != null) { + stringArray.add(line); + line = fileContent.readLine(); + } + fileContent.close(); + } catch (Exception e) { + e.printStackTrace(); + } + mySimu.loadRule(stringArray); + this.repaint(); + } + } + + public void clicLoadAgentsFileButton() { + String fileName=SelectFile(); + ArrayList stringArray = new ArrayList(); + if (fileName.length()>0) { + try { + BufferedReader fileContent = new BufferedReader(new FileReader(fileName)); + String line = fileContent.readLine(); + while (line != null) { + stringArray.add(line); + line = fileContent.readLine(); + } + fileContent.close(); + } catch (Exception e) { + e.printStackTrace(); + } + mySimu.loadAgents(stringArray); + this.repaint(); + } + } + + + public void clicSaveToFileButton() { + String fileName=SelectFile(); + if (fileName.length()>0) { + ArrayList content = mySimu.getSaveState(); + String[] strArr = Arrays.copyOf(content.toArray(), content.toArray().length, String[].class); + writeFile(fileName, strArr); + } + } + + public void clicSaveRuleToFileButton() { + String fileName=SelectFile(); + if (fileName.length()>0) { + ArrayList content = mySimu.getRule(); + String[] strArr = Arrays.copyOf(content.toArray(), content.toArray().length, String[].class); + writeFile(fileName, strArr); + } + } + + public void clicSaveAgentsToFileButton() { + String fileName=SelectFile(); + if (fileName.length()>0) { + ArrayList content = mySimu.getAgentsSave(); + String[] strArr = Arrays.copyOf(content.toArray(), content.toArray().length, String[].class); + writeFile(fileName, strArr); + } + } + + + public String SelectFile() { + String s; + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new java.io.File(".")); + chooser.setDialogTitle("Choose a file"); + chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + chooser.setAcceptAllFileFilterUsed(true); + if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + s=chooser.getSelectedFile().toString(); + } else { + System.out.println("No Selection "); + s=""; + } + return s; + } + + public void writeFile(String fileName, String[] content) { + FileWriter csvWriter; + try { + csvWriter = new FileWriter(fileName); + for (String row : content) { + csvWriter.append(row); + csvWriter.append("\n"); + } + csvWriter.flush(); + csvWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void update (int stepCount) { + this.setStepBanner("Step : "+ stepCount); + this.repaint(); + } + + public void eraseLabels() { + this.setStepBanner("Step : X"); + this.setBorderBanner("border : X"); + this.setClickBanner("click : X"); + speedSlider.setValue(3); + } + +} diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..251f46f --- /dev/null +++ b/src/Main.java @@ -0,0 +1,23 @@ +/* +public class Main { + + public static void main(String[] args) { + // TODO Auto-generated method stub + System.out.println("toto"); + } + +}*/ + + +import windowInterface.MyInterface; + + +public class Main { + + + public static void main(String[] args) { + MyInterface mjf = new MyInterface(); + mjf.setVisible(true); + } + +} \ No newline at end of file diff --git a/src/backend/Agent.java b/src/backend/Agent.java new file mode 100644 index 0000000..9eeef1e --- /dev/null +++ b/src/backend/Agent.java @@ -0,0 +1,40 @@ +package backend; + +import java.awt.Color; +import java.util.ArrayList; + +public abstract class Agent { + protected int x; + protected int y; + protected Color color; + + protected Agent(int x, int y, Color color) { + this.x = x; + this.y = y; + this.color = color; + } + + public Color getDisplayColor() { + return color; + } + public int getX() { + return x; + } + public int getY() { + return y; + } + public boolean isInArea(int x, int y, int radius) { + int diffX = this.x-x; + int diffY = this.y-y; + int dist = (int) Math.floor(Math.sqrt(diffX*diffX+diffY*diffY)); + return dist neighbors, Simulator world); + + +} diff --git a/src/backend/Cell.java b/src/backend/Cell.java new file mode 100644 index 0000000..8151c46 --- /dev/null +++ b/src/backend/Cell.java @@ -0,0 +1,17 @@ +package backend; + +public class Cell { + private int value; + + public Cell(int value) { + this.value = value; + } + + public int getValue() { + return value; + } + + public void setValue(int value) { + this.value = value; + } +} diff --git a/src/backend/Gride.java b/src/backend/Gride.java new file mode 100644 index 0000000..a87ff78 --- /dev/null +++ b/src/backend/Gride.java @@ -0,0 +1,103 @@ +package backend; + +import java.util.ArrayList; + +public class Gride { + private int height; + private int width; + private ArrayList> gride; + private Simulator simulator; + + public Gride(int height, int width, Simulator tempSimulator) { + this.height = height; + this.width = width; + this.simulator = tempSimulator; + + gride = new ArrayList<>(height); + + for (int i = 0; i < height; i++) { + this.gride.add(i, new ArrayList()); + for (int j = 0; j < width; j++) { + this.gride.get(i).add(new Cell(0)); + } + } + } + + public int getheight() { + return this.height; + } + + public int getwidth() { + return this.width; + } + public boolean isLoopingBorder() { + return simulator.isLoopingBorder(); + } + + public Cell getCell(int row,int column) { + return gride.get(row).get(column); + } + + public void setCell(int row, int column, Cell cell){ + this.gride.get(row).set(column, cell); + } + + public int countAround(int row, int column) { + int count = 0; + boolean loopingBorder = isLoopingBorder(); + + for (int i = row - 1; i <= row + 1; i++) { + for (int j = column - 1; j <= column + 1; j++) { + if (i == row && j == column) { + continue; + } + + int x = i; + int y = j; + + if (loopingBorder) { + x = (x + width) % width; + y = (y + height) % height; + } else { + if (x < 0 || x >= width || y < 0 || y >= height) { + continue; + } + } + + count += this.getCell(x, y).getValue(); + } + } + + return count; + } + + + + + //TODO : set agent (x y agent) load an agent to coordinates x,y + + //TODO : set random (density) create a random gride of determined density + public void setRandom(double density) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + double random = Math.random(); + if (random < density) { + gride.get(i).get(j).setValue(1); + } else { + gride.get(i).get(j).setValue(0); + } + } + } + System.out.println("Created a random field"); + } + + public void serialPrint(){ + for (int i = 0; i < height; i++) { + System.out.print("\n"); + for (int j = 0; j < width; j++) { + System.out.print(this.getCell(i, j).getValue() +" "); + } + } + } + +} diff --git a/src/backend/Rules.java b/src/backend/Rules.java new file mode 100644 index 0000000..a5f2862 --- /dev/null +++ b/src/backend/Rules.java @@ -0,0 +1,49 @@ +package backend; + +import java.util.ArrayList; + +import windowInterface.MyInterface; + + + +public class Rules { + + //Attributes + + private ArrayList fieldSurviveValues; + private ArrayList fieldBirthValues; + + + public Rules() { + + fieldSurviveValues = new ArrayList(); + fieldBirthValues = new ArrayList(); + + this.setConwayRules(); + } + + + public void resetRules() { + fieldSurviveValues.clear(); + fieldBirthValues.clear(); + } + + public void setConwayRules() { + this.fieldSurviveValues.clear(); + this.fieldBirthValues.clear(); + + //Set Conway rules + this.fieldSurviveValues.add(2); + this.fieldSurviveValues.add(3); + this.fieldBirthValues.add(3); + } + + public ArrayList getSurviveValues(){ + return fieldSurviveValues; + } + + + public ArrayList getBirthValues(){ + return fieldBirthValues; + } +} diff --git a/src/backend/Sheep.java b/src/backend/Sheep.java new file mode 100644 index 0000000..b05d141 --- /dev/null +++ b/src/backend/Sheep.java @@ -0,0 +1,59 @@ +package backend; + +import java.awt.Color; +import java.util.ArrayList; +import java.util.Random; + +// example of basic animal. +// do not hesitate to make it more complex +// and DO add at least another species that interact with it +// for example wolves that eat Sheep +public class Sheep extends Agent { + + int hunger; + Random rand; + + Sheep(int x,int y){ + //first we call the constructor of the superClass(Animal) + //with the values we want. + // here we decide that a Sheep is initially white using this constructor + super(x,y,Color.white); + // we give our sheep a hunger value of zero at birth + hunger = 0; + //we initialize the random number generator we will use to move randomly + rand = new Random(); + } + + /** + * action of the animal + * it can interact with the cells or with other animals + * as you wish + */ + public boolean liveTurn(ArrayList neighbors, Simulator world) { + if(world.getCell(x, y)==1) { + world.setCell(x, y, 0); + } else { + hunger++; + } + this.moveRandom(); + return hunger>10; + } + + private void moveRandom() { + int direction = rand.nextInt(4); + if(direction == 0) { + x+=1; + } + if(direction == 1) { + y+=1; + } + if(direction == 2) { + x-=1; + } + if(direction == 3) { + y-=1; + } + } + + +} diff --git a/src/backend/Simulator.java b/src/backend/Simulator.java new file mode 100644 index 0000000..e6f8bef --- /dev/null +++ b/src/backend/Simulator.java @@ -0,0 +1,413 @@ +package backend; +import java.util.ArrayList; +import java.util.ListIterator; + +import windowInterface.MyInterface; + +public class Simulator extends Thread { + + private MyInterface mjf; + + //Size of the grid + private final int COL_NUM = 100; + private final int LINE_NUM = 100; + private final int LIFE_TYPE_NUM = 4; + private final int LIFE_AREA_RADIUS = 1; + private final int ANIMAL_AREA_RADIUS = 2; + //private ArrayList fieldSurviveValues; + //private ArrayList fieldBirthValues; + + private ArrayList agents; + + private boolean stopFlag; + private boolean pauseFlag; + private boolean loopingBorder; + private boolean clickActionFlag; + private int loopDelay = 150; + + //TODO : add missing attribute(s) + private double randomDansitySlider = 0.5; + private int width; + private int height; + private Gride gride; + + //Step put here to be reset when generate new field + private int stepCount=0; + + private Rules rules; + + public Simulator(MyInterface mjfParam) { + mjf = mjfParam; + stopFlag=false; + pauseFlag=false; + loopingBorder=false; + clickActionFlag=true; + + agents = new ArrayList(); + + //fieldSurviveValues = new ArrayList(); + //fieldBirthValues = new ArrayList(); + + this.width=COL_NUM; + this.height=LINE_NUM; + gride = new Gride(height, width, this); + + //Reset rules to Conway rules + //this.resetRules(); + + rules = new Rules(); + + + } + + public int getWidth() { + return this.width; + } + + public int getHeight() { + return this.height; + } + + public void run() { + //int stepCount=0; + System.out.println("Step Count: "+ stepCount); + + //Set label when starting + mjf.setClickBanner("click : " + this.clickActionName()); + mjf.setBorderBanner("border : " + (this.isLoopingBorder()?"loop":"closed")); + + while(!stopFlag) { + stepCount++; + makeStep(); + mjf.update(stepCount); + try { + Thread.sleep(loopDelay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + while(pauseFlag && !stopFlag) { + try { + Thread.sleep(loopDelay); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + } + + + public void makeStep() { + + ListIterator iter = agents.listIterator(); + + while(iter.hasNext()){ + Agent agent = iter.next(); + + //System.out.println(agent.getX() + "," + agent.getY()); + + ArrayList neighbors = this.getNeighboringAnimals( + agent.getX(), + agent.getY(), + ANIMAL_AREA_RADIUS); + + + if(!agent.liveTurn( + neighbors, + this)) { + iter.remove(); + } + } + /* + for(Agent agent : agents) { + ArrayList neighbors = + this.getNeighboringAnimals( + agent.getX(), + agent.getY(), + ANIMAL_AREA_RADIUS); + if(!agent.liveTurn( + neighbors, + this)) { + agents.remove(agent); + } + } + */ + + + this.applyStep(); + + + } + + public void stopSimu() { + stopFlag=true; + } + + public void togglePause() { + pauseFlag = !pauseFlag; + } + + public void clickCell(int x, int y) { + + int currentCellValue = getCell(x, y); + + if (clickActionFlag == true) { + + int newCellValue = 0; + + if (currentCellValue == 0) { + newCellValue = 1; + } else { + newCellValue = 0; + } + this.setCell(x, y, newCellValue); + } else { + //Apply sheep /agent here + this.agents.add(new Sheep(x, y)); + } + + return; + } + + public int getCell(int x, int y) { + return this.gride.getCell(x,y).getValue(); + } + + public ArrayList getAnimals(){ + return agents; + } + + public ArrayList getNeighboringAnimals(int x, int y, int radius){ + ArrayList inArea = new ArrayList(); + for(int i=0;i getSaveState() { + ArrayList strArrayList = new ArrayList<>(); + String[] strArrayLine = new String[this.width]; + //Store the state of the GRID + for(int x=0 ;x lines) { + if(lines.size()<=0) { + return; + } + String firstLine = lines.get(0); + String[] firstLineElements = firstLine.split(";"); + if(firstLineElements.length<=0) { + return; + } + for(int y =0; y getRule() { + + ArrayList strArrayList = new ArrayList<>(); + + String[] strArrayLine = new String[rules.getSurviveValues().size()]; + + //Add survive values + for(int x=0; x lines) { + if(lines.size()<=0) { + System.out.println("empty rule file"); + return; + } + + + rules.resetRules(); + + String surviveLine = lines.get(0); + String birthLine = lines.get(1); + + String[] surviveElements = surviveLine.split(";"); + + //Load the values to survive + for(int x=0; x getAgentsSave() { + //TODO : Same idea as the other save method, but for agents + + ArrayList strArrayList = new ArrayList<>(); + String[] strArrayLine = new String[this.agents.size()]; + + for(int ii=0;ii stringArray) { + + if(stringArray.size()<=0) { + System.out.println("empty rule file"); + return; + } + + //Get the first line assuming it contains coordinates under format: X1,Y1;X2,Y2;X3,Y3 + String strFirstLine = stringArray.get(0); + + String[] strListCoordinates = strFirstLine.split(";"); + + //Loop on agent's coordinates and create one agent for each X,Y + for(int ii=0; ii stringArray = new ArrayList(); + if (fileName.length()>0) { + try { + BufferedReader fileContent = new BufferedReader(new FileReader(fileName)); + String line = fileContent.readLine(); + while (line != null) { + stringArray.add(line); + line = fileContent.readLine(); + } + fileContent.close(); + } catch (Exception e) { + e.printStackTrace(); + } + if(mySimu != null) { + mySimu.stopSimu(); + this.eraseLabels(); + } + loadedSim.loadSaveState(stringArray); + mySimu = loadedSim; + panelDraw.setSimu(mySimu); + this.repaint(); + } + } + + public void clicLoadRuleFileButton() { + String fileName=SelectFile(); + ArrayList stringArray = new ArrayList(); + if (fileName.length()>0) { + try { + BufferedReader fileContent = new BufferedReader(new FileReader(fileName)); + String line = fileContent.readLine(); + while (line != null) { + stringArray.add(line); + line = fileContent.readLine(); + } + fileContent.close(); + } catch (Exception e) { + e.printStackTrace(); + } + mySimu.loadRule(stringArray); + this.repaint(); + } + } + + public void clicLoadAgentsFileButton() { + String fileName=SelectFile(); + ArrayList stringArray = new ArrayList(); + if (fileName.length()>0) { + try { + BufferedReader fileContent = new BufferedReader(new FileReader(fileName)); + String line = fileContent.readLine(); + while (line != null) { + stringArray.add(line); + line = fileContent.readLine(); + } + fileContent.close(); + } catch (Exception e) { + e.printStackTrace(); + } + mySimu.loadAgents(stringArray); + this.repaint(); + } + } + + + public void clicSaveToFileButton() { + String fileName=SelectFile(); + if (fileName.length()>0) { + ArrayList content = mySimu.getSaveState(); + String[] strArr = Arrays.copyOf(content.toArray(), content.toArray().length, String[].class); + writeFile(fileName, strArr); + } + } + + public void clicSaveRuleToFileButton() { + String fileName=SelectFile(); + if (fileName.length()>0) { + ArrayList content = mySimu.getRule(); + String[] strArr = Arrays.copyOf(content.toArray(), content.toArray().length, String[].class); + writeFile(fileName, strArr); + } + } + + public void clicSaveAgentsToFileButton() { + String fileName=SelectFile(); + if (fileName.length()>0) { + ArrayList content = mySimu.getAgentsSave(); + String[] strArr = Arrays.copyOf(content.toArray(), content.toArray().length, String[].class); + writeFile(fileName, strArr); + } + } + + + public String SelectFile() { + String s; + JFileChooser chooser = new JFileChooser(); + chooser.setCurrentDirectory(new java.io.File(".")); + chooser.setDialogTitle("Choose a file"); + chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); + chooser.setAcceptAllFileFilterUsed(true); + if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { + s=chooser.getSelectedFile().toString(); + } else { + System.out.println("No Selection "); + s=""; + } + return s; + } + + public void writeFile(String fileName, String[] content) { + FileWriter csvWriter; + try { + csvWriter = new FileWriter(fileName); + for (String row : content) { + csvWriter.append(row); + csvWriter.append("\n"); + } + csvWriter.flush(); + csvWriter.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public void update (int stepCount) { + this.setStepBanner("Step : "+ stepCount); + this.repaint(); + } + + public void eraseLabels() { + this.setStepBanner("Step : X"); + this.setBorderBanner("border : X"); + this.setClickBanner("click : X"); + speedSlider.setValue(3); + } + +}