diff --git a/src/backend/Simulator.java b/src/backend/Simulator.java index 305837d..babb297 100644 --- a/src/backend/Simulator.java +++ b/src/backend/Simulator.java @@ -29,15 +29,13 @@ public class Simulator extends Thread { private int clickActionFlag; private int loopDelay = 150; private int[][] world; - //private int[] survivalRulesArray; - //private int[] birthRulesArray; private int[] birthRulesArrays = new int[0]; +//this will allow us to store the different rules about the birth of new cells private int[] surviveRulesArrays = new int[0]; - - //TODO : add missing attribute(s) +//this will allow us to store the different rules about the survival of new cells + private int stepCount; - public Simulator(MyInterface mjfParam) { mjf = mjfParam; //stopFlag=false; //not necessary since i set the state when pressing the button start @@ -49,7 +47,7 @@ public class Simulator extends Thread { fieldBirthValues = new ArrayList(); fieldSurviveValues = new ArrayList(); world =new int[getWidth()][getHeight()]; - //TODO : add missing attribute initialization +//this allows us to define our world and it's size @@ -68,6 +66,11 @@ public class Simulator extends Thread { return LINE_NUM; } + +//this method gets the value in our CSV files for the rules +//and places them in the right format in the right array +//it ten tells you whether your file is empty, and if there is at least one survival rule +//if the rules are loaded in the array successfully then it tells you "rules loaded successfully" public void loadRule(ArrayList row) { String surviveRulesRow = row.get(0).replace("\"","").trim(); String[] surviveCells = surviveRulesRow.split(";"); @@ -100,39 +103,16 @@ public class Simulator extends Thread { System.out.println("Error parsing rule values: " + e.getMessage()); } } - /*for (int x = 0; x < birthCells.length; x++) { - String[] birthElements = birthCells[x].split(","); - int[] birthRulesArray = new int[birthElements.length]; - for (int y = 0; y < birthElements.length; y++) { - String elem = birthElements[y]; - int value = Integer.parseInt(elem); - birthRulesArray[y] = value; - } - this.birthRulesArrays[x] = birthRulesArray; - System.out.println("birth rule taken into account"); - } - -//determines the number of alive neighboring cells needed to birth, and places them in the birthCells list - for (int x = 0; x < surviveCells.length; x++) { - String[] surviveElements = surviveCells[x].split(","); - int[] surviveArray = new int[surviveElements.length]; - for (int y = 0; y < surviveElements.length; y++) { - String elem = surviveElements[y]; - int value = Integer.parseInt(elem); - surviveArray[y] = value; - } - this.surviveRulesArrays[x] = surviveArray; - System.out.println("survival rule taken into account"); - }*/ -//determines the number of alive neighboring cells needed to survive, and places them in the surviveCells list + } - +//getter for the birth rules public int[] getBirthRulesArray() { return this.birthRulesArrays; } +//getter for the survival rules public int[] getSurvivalRulesArray() { return this.surviveRulesArrays; } @@ -162,13 +142,10 @@ public class Simulator extends Thread { } - /** - * method called at each step of the simulation - * makes all the actions to go from one step to the other - */ - +//method used to calculate the number of neighbors to one cell that are alive, +//and to return this number private int countAliveNeighbors(int x, int y) { int count = 0; int[][] directions = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1}}; @@ -186,13 +163,15 @@ public class Simulator extends Thread { return count; } - +//initiates the world with the right components public void setWorld(int[][] world, int width, int height) { this.world = world; this.COL_NUM = width; this.LINE_NUM = height; } - + +//determines whether or not the studied cell should survive +//depending on the number of alive neighbors and the loaded rules private boolean shouldSurvive(int aliveNeighbors) { for (int value : getSurvivalRulesArray()) { if ( value == aliveNeighbors) { @@ -201,6 +180,8 @@ public class Simulator extends Thread { }return false; } +//determines whether or not the studied cell should become alive +//depending on the number of alive neighbors and the loaded rules private boolean shouldBeBorn(int aliveNeighbors) { for(int value : getBirthRulesArray()) { if (value == aliveNeighbors) { @@ -212,11 +193,9 @@ public class Simulator extends Thread { public void makeStep() { - // agent behaviors first - // only modify if sure of what you do - // to modify agent behavior, see liveTurn method - // in agent classes +//this part is used to make the agents move and +//according to their own rules, go to the next generation for (int i = agents.size() - 1; i >= 0; i--) { Agent agent = agents.get(i); ArrayList neighbors = this.getNeighboringAnimals(agent.getX(), agent.getY(), ANIMAL_AREA_RADIUS); @@ -224,34 +203,10 @@ public class Simulator extends Thread { agents.remove(i); } } - /*ArrayList newAgents = new ArrayList<>(); - for(Agent agent : agents) { - ArrayList neighbors = - this.getNeighboringAnimals( - agent.getX(), - agent.getY(), - ANIMAL_AREA_RADIUS);} - if(!agent.liveTurn( - neighbors, - this)) { - agents.remove(agent); - }*/ - - // Apply Game of Life rules - /*for (int x = 0; x < getWidth(); x++) { - for (int y = 0; y < getHeight(); y++) { - int aliveNeighbors = countAliveNeighbors(x, y); - if (world[x][y] == 1) { - newWorld[x][y] = (aliveNeighbors < 2 || aliveNeighbors > 3) ? 0 : 1; - } else { - newWorld[x][y] = (aliveNeighbors == 3) ? 1 : 0; - } - - } - }*/ - +//this part is used for the cells, in order to make them go to the next generation +//according to the loaded rules, and the agents actions int[][] newWorld = new int[getWidth()][getHeight()]; for (int x = 0; x < getWidth(); x++) { @@ -276,53 +231,29 @@ public class Simulator extends Thread { - //then evolution of the field - // TODO : apply game rule to all cells of the field - /* you should distribute this action in methods/classes - * don't write everything here ! - * - * the idea is first to get the surrounding values - * then count how many are alive - * then check if that number is in the lists of rules - * if the cell is alive - * and the count is in the survive list, - * then the cell stays alive - * if the cell is not alive - * and the count is in the birth list, - * then the cell becomes alive - */ - - - - - /* - * leave this as is - */ public void stopSimu() { stopFlag=true; } + public void startSimu() { // same as stopSimu but will set the stopFlag value as false. stopFlag=false; } - /* - * method called when clicking pause button - */ + public void togglePause() { pauseFlag= ! pauseFlag; // It changes the boolean value associated to pauseFlag (pauseFlag= not pauseFlag) } - /** - * method called when clicking on a cell in the interface - */ + +//method called when clicking on a cell in the interface public void clickCell(int x, int y) { if (clickActionFlag==0) { // cell setCell(x, y, getCell(x, y) == 1 ? 0 : 1); } else if (clickActionFlag==1) { // sheep - ArrayList nearby=getNeighboringAnimals(x,y,1); //look if the cell has an agent + ArrayList nearby=getNeighboringAnimals(x,y,1); //checks if the cell has an agent if (nearby.isEmpty()) { Sheep sheep = new Sheep(x,y); agents.add(sheep); @@ -345,30 +276,20 @@ public class Simulator extends Thread { } - /** - * get cell value in simulated world - * @param x coordinate of cell - * @param y coordinate of cell - * @return value of cell - */ + public int getCell(int x, int y) { return world[x][y]; //get the value (dead or alive) of my cell at x y } - /** - * - * @return list of Animals in simulated world - */ + + +//returns the list of the animals in the world public ArrayList getAnimals(){ return agents; } - /** - * selects Animals in a circular area of simulated world - * @param x center - * @param y center - * @param radius - * @return list of agents in area - */ + + +//gets the list of the agents in the area around our studied agent public ArrayList getNeighboringAnimals(int x, int y, int radius){ ArrayList inArea = new ArrayList(); for(int i=0;i neighbor) { - //ArrayList neighbor =getNeighboringAnimals(x,y,1); Agent agent = neighbor.get(0); if (agent instanceof Wolf) { return "Wolf"; @@ -388,22 +311,15 @@ public class Simulator extends Thread { return "Sheep"; } } - /** - * set value of cell - * @param x coord of cell - * @param y coord of cell - * @param val to set in cell - */ + + +//sets the value of the cell at the coordinates x and y public void setCell(int x, int y, int val) { world [x][y] = val; - } - /** - * - * @return lines of file representing - * the simulated world in its present state - */ + +//stores a world in a CSV files, to be reopened later on public ArrayList getSaveState() { ArrayList saveState = new ArrayList<>(); for (int j = 0; j < getHeight(); j++) { @@ -420,17 +336,11 @@ public class Simulator extends Thread { } - /** - * - * @param lines of file representing saved world state - */ + + +//reads and returns the lines of the CSV files that was saved using getSaveState public void loadSaveState(ArrayList lines) { - /* - * First some checks that the file is usable - * We call early returns in conditions like this - * "Guard clauses", as they guard the method - * against unwanted inputs - */ + if(lines.size()<=0) { return; } @@ -439,10 +349,7 @@ public class Simulator extends Thread { if(firstLineElements.length<=0) { return; } - /* - * now we fill in the world - * with the content of the file - */ + for(int y =0; y getRule() { //to check +//is used to save a rule in a CSV file + public ArrayList getRule() { ArrayList rule = new ArrayList<>(); for (int i = 0; i < getHeight(); i++) { StringBuilder lineState = new StringBuilder(); - for (int j = 0 ; j < getHeight() ; j++) { // je crois qu'il y a un probleme, il fau+t mettre getWidth je crois + for (int j = 0 ; j < getHeight() ; j++) { lineState.append(getCell(i, j)); if (j < getWidth() - 1) { lineState.append(";"); @@ -470,15 +378,10 @@ public class Simulator extends Thread { return rule; } - + +//is used to generate a random world when the game is ran +//or when you click on the random button public void generateRandom(float chanceOfLife) { - /* - * Advice : - * as you should probably have a separate class - * representing the field of cells... - * maybe just make a constructor in there - * and use it here - */ Random rand = new Random(); for (int x = 0; x < COL_NUM; x++) { for (int y = 0; y < LINE_NUM; y++) { @@ -487,10 +390,12 @@ public class Simulator extends Thread { } } +//checks if the border is put as looping public boolean isLoopingBorder() { return loopingBorder; } +//allows to change from looping to not looping border public void toggleLoopingBorder() { if (loopingBorder){ loopingBorder = false; @@ -499,11 +404,14 @@ public class Simulator extends Thread { } } + public void setLoopDelay(int delay) { loopDelay = delay; } + +//changes the object that will be placed using the toggle click button public void toggleClickAction() { if (clickActionFlag < 2) { clickActionFlag ++ ; @@ -512,18 +420,7 @@ public class Simulator extends Thread { } } - /** - * prepare the content of a file saving present ruleSet - * as you might want to save a state, - * initialy written in this class constructor - * as a file for future use - * @return File content as an ArrayList of Lines (String) - * @see loadRule for inverse process - */ - - - - +//stores where and what the agents are on the saved world public ArrayList getAgentsSave() { ArrayList agentsList = new ArrayList(); String sheepLine = "1,"; @@ -545,8 +442,9 @@ public class Simulator extends Thread { return agentsList; } + +//allows to load a predefined set of agents on the world public void loadAgents(ArrayList stringArray) { - //TODO : Same idea as other load methods, but for agent list for(int y =0; y stringArray = new ArrayList(); if (fileName.length()>0) { try { @@ -335,8 +349,7 @@ public class MyInterface extends JFrame { this.repaint(); } } - - + @@ -360,6 +373,8 @@ public class MyInterface extends JFrame { } } + + public void clicLoadAgentsFileButton() { String fileName=SelectFile(); ArrayList stringArray = new ArrayList(); @@ -381,6 +396,7 @@ public class MyInterface extends JFrame { } +//used to read a world and save it as a file in the computer, to be reopened later on public void clicSaveToFileButton() { String fileName=SelectFile(); if (fileName.length()>0) { @@ -390,6 +406,9 @@ public class MyInterface extends JFrame { } } + + + public void clicSaveRuleToFileButton() { String fileName=SelectFile(); if (fileName.length()>0) { @@ -398,6 +417,8 @@ public class MyInterface extends JFrame { writeFile(fileName, strArr); } } + + public void clicSaveAgentsToFileButton() { String fileName=SelectFile(); @@ -408,6 +429,7 @@ public class MyInterface extends JFrame { } } + public String SelectFile() { String s; @@ -424,6 +446,8 @@ public class MyInterface extends JFrame { } return s; } + + public void writeFile(String fileName, String[] content) { FileWriter csvWriter; @@ -439,11 +463,15 @@ public class MyInterface extends JFrame { e.printStackTrace(); } } + + public void update (int stepCount) { this.setStepBanner("Step : "+ stepCount); this.repaint(); } + + public void eraseLabels() { this.setStepBanner("Step : X");