OOP_D8_Project/src - Copie/backend/Simulator.java

414 lines
9.2 KiB
Java

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<Integer> fieldSurviveValues;
//private ArrayList<Integer> fieldBirthValues;
private ArrayList<Agent> 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<Agent>();
//fieldSurviveValues = new ArrayList<Integer>();
//fieldBirthValues = new ArrayList<Integer>();
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<Agent> iter = agents.listIterator();
while(iter.hasNext()){
Agent agent = iter.next();
//System.out.println(agent.getX() + "," + agent.getY());
ArrayList<Agent> neighbors = this.getNeighboringAnimals(
agent.getX(),
agent.getY(),
ANIMAL_AREA_RADIUS);
if(!agent.liveTurn(
neighbors,
this)) {
iter.remove();
}
}
/*
for(Agent agent : agents) {
ArrayList<Agent> 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<Agent> getAnimals(){
return agents;
}
public ArrayList<Agent> getNeighboringAnimals(int x, int y, int radius){
ArrayList<Agent> inArea = new ArrayList<Agent>();
for(int i=0;i<agents.size();i++) {
Agent agent = agents.get(i);
if(agent.isInArea(x,y,radius)) {
inArea.add(agent);
}
}
return inArea;
}
public void setCell(int x, int y, int val) {
this.gride.getCell(x, y).setValue(val);
}
public void countAround(int x, int y) {
this.gride.countAround(x, y);
}
public ArrayList<String> getSaveState() {
ArrayList<String> strArrayList = new ArrayList<>();
String[] strArrayLine = new String[this.width];
//Store the state of the GRID
for(int x=0 ;x<this.width; x++) {
for(int y=0 ;y<this.width; y++) {
strArrayLine[y] = Integer.toString(getCell(y, x));
}
System.out.println(String.join(";", strArrayLine));
strArrayList.add(String.join(";", strArrayLine));
}
return strArrayList;
}
// Load a grid from file
public void loadSaveState(ArrayList<String> 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<lines.size();y++) {
String line = lines.get(y);
String[] lineElements = line.split(";");
for(int x=0; x<lineElements.length;x++) {
String elem = lineElements[x];
int value = Integer.parseInt(elem);
setCell(x, y, value);
}
}
//Reset rules
rules.setConwayRules();
//Reset Agents
this.agents.clear();
}
private void resetRules() {
rules.resetRules();
}
public void generateRandom(float chanceOfLife) {
this.gride.setRandom(chanceOfLife);
//Reset the steps
stepCount = 0;
this.mjf.update(stepCount);
}
public boolean isLoopingBorder() {
return loopingBorder;
}
public void toggleLoopingBorder() {
loopingBorder = !loopingBorder;
}
public void setLoopDelay(int delay) {
loopDelay = delay;
}
public void toggleClickAction() {
clickActionFlag = !clickActionFlag;
}
public ArrayList<String> getRule() {
ArrayList<String> strArrayList = new ArrayList<>();
String[] strArrayLine = new String[rules.getSurviveValues().size()];
//Add survive values
for(int x=0; x<rules.getSurviveValues().size();x++) {
strArrayLine[x] = Integer.toString(rules.getSurviveValues().get(x));
}
strArrayList.add(String.join(";", strArrayLine));
//New array for Birth values
strArrayLine = new String[rules.getBirthValues().size()];
//Add born values
for(int x=0; x<rules.getBirthValues().size();x++) {
strArrayLine[x] = Integer.toString(rules.getBirthValues().get(x));
}
strArrayList.add(String.join(";", strArrayLine));
return strArrayList;
}
public void loadRule(ArrayList<String> 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<surviveElements.length;x++) {
String elem = surviveElements[x];
int value = Integer.parseInt(elem);
rules.getSurviveValues().add(value);
}
//Load the values given birth
String[] birthElements = birthLine.split(";");
for(int x=0; x<birthElements.length;x++) {
String elem = birthElements[x];
int value = Integer.parseInt(elem);
rules.getBirthValues().add(value);
}
}
public void applyStep() {
Gride newGrideUpdated = new Gride(this.height, this.width, this);
//System.out.println("New Iteration");
for (int i = 0; i < this.height; i++) {
for (int j = 0; j < this.width; j++) {
int cellValue = this.gride.getCell(i, j).getValue();
int newCellValue = cellValue;
int count = this.gride.countAround(i, j);
if (cellValue == 1) {
//Check that count is one of the value making survive the cell
if (rules.getSurviveValues().contains(count)) {
newCellValue = 1;
} else {
newCellValue = 0;
}
} else {
//Check that count is one of the value making generate a cell
if (rules.getBirthValues().contains(count)) {
newCellValue = 1;
}
}
newGrideUpdated.setCell(i, j, new Cell(newCellValue));
//System.out.println("applyStep called : " + newGrideUpdated.getCell(i, j).getValue() + " at " + i + " " + j);
}
}
gride = newGrideUpdated;
}
public ArrayList<String> getAgentsSave() {
//TODO : Same idea as the other save method, but for agents
ArrayList<String> strArrayList = new ArrayList<>();
String[] strArrayLine = new String[this.agents.size()];
for(int ii=0;ii<this.agents.size();ii++) {
strArrayLine[ii] = this.agents.get(ii).getX() + "," + this.agents.get(ii).getY();
}
strArrayList.add(String.join(";", strArrayLine));
return strArrayList;
}
public void loadAgents(ArrayList<String> 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<strListCoordinates.length;ii++) {
String coordinate = strListCoordinates[ii];
int commaPosition = coordinate.indexOf(",");
int x = Integer.parseInt(coordinate.substring(0,commaPosition));
int y = Integer.parseInt(coordinate.substring(commaPosition+1));
//Add an agent to the lista at x,y position
agents.add(new Sheep(x, y));
}
}
/**
* 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
if (clickActionFlag) {
return "cell";
} else {
return "sheep";
}
}
}