414 lines
9.2 KiB
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";
|
|
}
|
|
|
|
}
|
|
|
|
}
|