package backend; import java.util.ArrayList; import windowInterface.MyInterface; public class Simulator extends Thread { private MyInterface mjf; private final int COL_NUM = 100; private final int LINE_NUM = 100; private final int LIFE_TYPE_NUM = 4; //Conway Radius : 1 private final int LIFE_AREA_RADIUS = 1; //Animal Neighborhood Radius : 5 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 boolean enableLogs; public Simulator(MyInterface mjfParam) { mjf = mjfParam; stopFlag=false; pauseFlag=false; loopingBorder=false; clickActionFlag=false; agents = new ArrayList(); fieldBirthValues = new ArrayList(); fieldSurviveValues = new ArrayList(); //TODO-COMPLETE: add missing attribute initialization //might want to changes those values later this.width=COL_NUM; this.height=LINE_NUM; enableLogs = true; // for debugging purposes //Default rule : Survive always, birth never for(int i =0; i<9; i++) { fieldSurviveValues.add(i); } } public int getWidth() { //TODO-COMPLETE : replace with proper return return this.width; } public int getHeight() { //TODO-COMPLETE : replace with proper return return this.height; } //Should probably stay as is public void run() { int stepCount=0; 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(); } } } } /** * method called at each step of the simulation * makes all the actions to go from one step to the other */ public void makeStep() { // agent behaviors first // only modify if sure of what you do // to modify agent behavior, see liveTurn method // in agent classes for(Agent agent : agents) { ArrayList neighbors = this.getNeighboringAnimals( agent.getX(), agent.getY(), ANIMAL_AREA_RADIUS); if(!agent.liveTurn( neighbors, this)) { agents.remove(agent); } } //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; } /* * method called when clicking pause button */ public void togglePause() { // TODO-COMPLETE : actually toggle the corresponding flag pauseFlag = !pauseFlag; if (enableLogs) { if (pauseFlag) { System.out.println("togglePause called, Simulation paused"); } else { System.out.println("togglePause called, Simulation unpaused"); } } } /** * method called when clicking on a cell in the interface */ public void clickCell(int x, int y) { if (clickActionFlag) { int currentCellValue = getCell(x, y); int newCellValue; if (currentCellValue == 0) { if (enableLogs) { System.out.println("clickCell Called, cell :" + x + "," + y + " is now alive"); } newCellValue = 1; // If the cell is dead, make it alive } else { if (enableLogs) { System.out.println("clickCell Called, cell :" + x + "," + y + " is now dead"); } newCellValue = 0; // If the cell is alive, make it dead } setCell(x, y, newCellValue); } else { return; } } /** * 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) { //TODO : complete method with proper return return 0; } /** * * @return list of Animals in simulated 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 */ public ArrayList getNeighboringAnimals(int x, int y, int radius){ ArrayList inArea = new ArrayList(); for(int i=0;i getSaveState() { //TODO : complete method with proper return return null; } /** * * @param lines of file representing saved world state */ 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; } String firstLine = lines.get(0); String[] firstLineElements = firstLine.split(";"); if(firstLineElements.length<=0) { return; } /* * now we fill in the world * with the content of the file */ for(int y =0; y getRule() { //TODO : complete method with proper return return null; } public void loadRule(ArrayList lines) { if(lines.size()<=0) { System.out.println("empty rule file"); return; } //TODO : remove previous rule (=emptying lists) String surviveLine = lines.get(0); String birthLine = lines.get(1); String[] surviveElements = surviveLine.split(";"); for(int x=0; x getAgentsSave() { //TODO : Same idea as the other save method, but for agents return null; } public void loadAgents(ArrayList stringArray) { //TODO : Same idea as other load methods, but for agent list } /** * used by label in interface to show the active click action * @return String representation of click action */ public String clickActionName() { // TODO : initially return "sheep" or "cell" // depending on clickActionFlag return ""; } }