last version
This commit is contained in:
parent
74596e4dac
commit
96b2ea03f0
Binary file not shown.
Binary file not shown.
|
|
@ -1 +0,0 @@
|
|||
10,10;11,11;9,11;12,10
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
8;12
|
||||
9;3
|
||||
78;5
|
||||
64;39
|
||||
29;41
|
||||
2;54
|
||||
55;87
|
||||
92;4
|
||||
|
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,2 @@
|
|||
1;2;3;4;5
|
||||
3;;;;
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
2;3
|
||||
3;
|
||||
2;
|
||||
|
Binary file not shown.
|
Can't render this file because it contains an unexpected character in line 1 and column 82.
|
|
|
@ -30,6 +30,8 @@ public abstract class Agent {
|
|||
return dist<radius;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Does whatever the agent does during a step
|
||||
// then returns a boolean
|
||||
// if false, agent dies at end of turn
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
package backend;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class AgentRules {
|
||||
private ArrayList<Integer> sheepSurviveValues;
|
||||
private ArrayList<Integer> sheepBirthValues;
|
||||
|
||||
public AgentRules() {
|
||||
sheepSurviveValues = new ArrayList<>();
|
||||
sheepBirthValues = new ArrayList<>();
|
||||
|
||||
sheepBirthValues.addAll(Arrays.asList(2)); // Sheeps are born with 2 or more neighbors
|
||||
}
|
||||
|
||||
public boolean shouldBirth(int numberOfNeighbors) {
|
||||
return sheepBirthValues.contains(numberOfNeighbors);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package backend;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class Grid {
|
||||
|
||||
|
||||
private final int COL_NUM = 100;
|
||||
private final int LINE_NUM = 100;
|
||||
private int[][] worldGrid; // The grid
|
||||
|
||||
|
||||
|
||||
|
||||
// Constructor to create a grid ang give its size
|
||||
public Grid() {
|
||||
worldGrid = new int[COL_NUM][LINE_NUM];
|
||||
}
|
||||
|
||||
// Method to initialize the grid with all zeros
|
||||
public void iniGrid() {
|
||||
for (int i = 0; i < COL_NUM; i++) {
|
||||
for (int j = 0; j < LINE_NUM; j++) {
|
||||
worldGrid[i][j] = 0; // Set each cell to 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Method to get the width of the grid
|
||||
public int getWidth() {
|
||||
return COL_NUM;
|
||||
}
|
||||
|
||||
// Method to get the height of the grid
|
||||
public int getHeight() {
|
||||
return LINE_NUM;
|
||||
}
|
||||
|
||||
// method to access a cell in the grid
|
||||
public int getCell(int x, int y) {
|
||||
return worldGrid[x][y]; // Get the value at cell (x, y)
|
||||
}
|
||||
// method to set the value of a cell in the grid
|
||||
public void setCell(int x, int y, int val) {
|
||||
|
||||
worldGrid[x][y] = val; // Set the value at cell (x, y)
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int[][] getGrid() {
|
||||
return worldGrid;
|
||||
}
|
||||
|
||||
public int countNeighbors(int x, int y) {
|
||||
int count = 0;
|
||||
|
||||
// Check all nine cells around the given cell
|
||||
for (int i = -1; i <= 1; i++) {
|
||||
for (int j = -1; j <= 1; j++) {
|
||||
int nx = x + i;
|
||||
int ny = y + j;
|
||||
|
||||
// Skip checking the cell itself
|
||||
if (i == 0 && j == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Count how many cells are alive around the given cell
|
||||
if (nx >= 0 && nx < getWidth() && ny >= 0 && ny < getHeight()) {
|
||||
if (getCell(nx,ny) == 1) { // 1 represents alive
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
package backend;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
|
||||
public class Rules {
|
||||
private ArrayList<Integer> fieldSurviveValues;
|
||||
private ArrayList<Integer> fieldBirthValues;
|
||||
|
||||
private int zombieProbability;
|
||||
Random rand;
|
||||
|
||||
public int zombieProbability() {
|
||||
return zombieProbability;
|
||||
}
|
||||
|
||||
|
||||
public Rules() {
|
||||
// create lists of survival and birth rules
|
||||
fieldSurviveValues = new ArrayList<>();
|
||||
fieldBirthValues = new ArrayList<>();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// define if cell should die or survive
|
||||
public boolean shouldSurvive(int numberOfNeighbors) {
|
||||
return fieldSurviveValues.contains(numberOfNeighbors);
|
||||
}
|
||||
|
||||
// define if cell should birth
|
||||
public boolean shouldBirth(int numberOfNeighbors) {
|
||||
return fieldBirthValues.contains(numberOfNeighbors);
|
||||
}
|
||||
|
||||
// define if cell should become zombie
|
||||
public boolean shouldBecomeZombie(int zombieProbability) {
|
||||
this.rand = new Random();
|
||||
int zombie = rand.nextInt(99);
|
||||
|
||||
return zombie < zombieProbability ;
|
||||
}
|
||||
|
||||
|
||||
//method to load rules from a file
|
||||
public void loadRule(ArrayList<String> lines) {
|
||||
if(lines.size()<=0) {
|
||||
System.out.println("empty rule file");
|
||||
return;
|
||||
}
|
||||
//DONE TODO : remove previous rule (=emptying lists)
|
||||
fieldSurviveValues.clear();
|
||||
fieldBirthValues.clear();
|
||||
|
||||
String surviveLine = lines.get(0);
|
||||
String birthLine = lines.get(1);
|
||||
|
||||
String[] surviveElements = surviveLine.split(";");
|
||||
System.out.println("Survival rules are:");
|
||||
for(int x=0; x<surviveElements.length;x++) {
|
||||
String elem = surviveElements[x];
|
||||
int surviveValue = Integer.parseInt(elem);
|
||||
|
||||
System.out.println(surviveValue);
|
||||
//DONE TODO : add value to possible survive values
|
||||
fieldSurviveValues.add(surviveValue);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
String[] birthElements = birthLine.split(";");
|
||||
System.out.println("Birth Rules rules are:");
|
||||
for(int x=0; x<birthElements.length;x++) {
|
||||
String elem = birthElements[x];
|
||||
int birthValue = Integer.parseInt(elem);
|
||||
//DONE TODO : add value to possible birth values
|
||||
System.out.println(birthValue);
|
||||
fieldBirthValues.add(birthValue);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
//method called if a rules file has 3 lines, to give the probability value of a zombie appearing once a cell die
|
||||
public int loadZombieRule(ArrayList<String> lines) {
|
||||
String zombieLine = lines.get(2);
|
||||
System.out.println("dying cells are becoming zombies");
|
||||
String[] zombieElement = zombieLine.split(";");
|
||||
for (int x = 0; x < zombieElement.length; x++) {
|
||||
String elem = zombieElement[x];
|
||||
zombieProbability = Integer.parseInt(elem);
|
||||
}
|
||||
return zombieProbability;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -11,6 +11,8 @@ import java.util.Random;
|
|||
public class Sheep extends Agent {
|
||||
|
||||
int hunger;
|
||||
boolean eaten;
|
||||
boolean isEaten;
|
||||
Random rand;
|
||||
|
||||
Sheep(int x,int y){
|
||||
|
|
@ -31,29 +33,64 @@ public class Sheep extends Agent {
|
|||
*/
|
||||
public boolean liveTurn(ArrayList<Agent> neighbors, Simulator world) {
|
||||
if(world.getCell(x, y)==1) {
|
||||
world.setCell(x, y, 0);
|
||||
world.setCell(x, y, 0); //sheep eats green cell it's on
|
||||
} else {
|
||||
hunger++;
|
||||
}
|
||||
|
||||
eaten = this.eatenSheep(neighbors, world); // true if sheep is eaten by wolf, false if not
|
||||
this.moveRandom();
|
||||
return hunger>10;
|
||||
|
||||
// next steps will make a sheep live or die
|
||||
|
||||
if (hunger<2) { // is sheep doesn't die of hunger
|
||||
return !eaten ; // either it dies eaten or it lives
|
||||
}
|
||||
else
|
||||
return hunger<2;// sheep dies of hunger
|
||||
}
|
||||
|
||||
public boolean eatenSheep(ArrayList<Agent> neighbors, Simulator world) {
|
||||
isEaten = false;
|
||||
|
||||
for (Agent agent : neighbors) {
|
||||
if (agent instanceof Wolf) {
|
||||
if (Math.abs(agent.getX() - this.x) <= 1 && Math.abs(agent.getY() - this.y) <= 1) { //sheep is eaten if wolf in 1 cell radius
|
||||
|
||||
isEaten = true; // Indicate that a sheep has been eaten
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
return isEaten;
|
||||
}
|
||||
|
||||
public boolean eatSheep() {
|
||||
return isEaten;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void moveRandom() {
|
||||
int direction = rand.nextInt(4);
|
||||
if(direction == 0) {
|
||||
if(direction == 0 && x<99) {
|
||||
x+=1;
|
||||
}
|
||||
if(direction == 1) {
|
||||
if(direction == 1 && y<99) {
|
||||
y+=1;
|
||||
}
|
||||
if(direction == 2) {
|
||||
if(direction == 2 && x>0) {
|
||||
x-=1;
|
||||
}
|
||||
if(direction == 3) {
|
||||
if(direction == 3 && y>0) {
|
||||
y-=1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,17 @@
|
|||
package backend;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.Iterator;
|
||||
import windowInterface.MyInterface;
|
||||
|
||||
|
||||
public class Simulator extends Thread {
|
||||
|
||||
private MyInterface mjf;
|
||||
|
||||
private final int COL_NUM = 100;
|
||||
private final int LINE_NUM = 100;
|
||||
|
||||
// COL_NUM and LINE_NUM moved to Grid
|
||||
private final int LIFE_TYPE_NUM = 4;
|
||||
//Conway Radius : 1
|
||||
private final int LIFE_AREA_RADIUS = 1;
|
||||
|
|
@ -24,8 +27,13 @@ public class Simulator extends Thread {
|
|||
private boolean loopingBorder;
|
||||
private boolean clickActionFlag;
|
||||
private int loopDelay = 150;
|
||||
private int stepCounter = 0;
|
||||
|
||||
//TODO : add missing attribute(s)
|
||||
//DONETODO : add missing attribute(s)
|
||||
private Grid worldGrid;
|
||||
private Rules rules = new Rules();
|
||||
Random rand;
|
||||
|
||||
|
||||
public Simulator(MyInterface mjfParam) {
|
||||
mjf = mjfParam;
|
||||
|
|
@ -38,8 +46,11 @@ public class Simulator extends Thread {
|
|||
fieldBirthValues = new ArrayList<Integer>();
|
||||
fieldSurviveValues = new ArrayList<Integer>();
|
||||
|
||||
//TODO : add missing attribute initialization
|
||||
//DONETODO : add missing attribute initialization
|
||||
worldGrid = new Grid();
|
||||
worldGrid.iniGrid();
|
||||
|
||||
|
||||
|
||||
|
||||
//Default rule : Survive always, birth never
|
||||
|
|
@ -48,15 +59,17 @@ public class Simulator extends Thread {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
public int getWidth() {
|
||||
//TODO : replace with proper return
|
||||
return 0;
|
||||
//DONETODO : replace with proper return
|
||||
return worldGrid.getWidth(); // the width is the number of columns
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
//TODO : replace with proper return
|
||||
return 0;
|
||||
//DONETODO : replace with proper return
|
||||
return worldGrid.getHeight(); // the height is the number of rows
|
||||
}
|
||||
|
||||
//Should probably stay as is
|
||||
|
|
@ -91,6 +104,7 @@ public class Simulator extends Thread {
|
|||
// only modify if sure of what you do
|
||||
// to modify agent behavior, see liveTurn method
|
||||
// in agent classes
|
||||
/*
|
||||
for(Agent agent : agents) {
|
||||
ArrayList<Agent> neighbors =
|
||||
this.getNeighboringAnimals(
|
||||
|
|
@ -103,14 +117,141 @@ public class Simulator extends Thread {
|
|||
agents.remove(agent);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// The code above gave us an error, we replaced it with this one, using an iterator
|
||||
Iterator<Agent> iterator = agents.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
Agent agent = iterator.next();
|
||||
ArrayList<Agent> neighbors =
|
||||
this.getNeighboringAnimals(agent.getX(), agent.getY(), ANIMAL_AREA_RADIUS);
|
||||
if (!agent.liveTurn(neighbors, this)) {
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
List<Agent> newAgents = new ArrayList<>();
|
||||
|
||||
// reproduction of agents
|
||||
|
||||
for (int x = 0; x < worldGrid.getWidth(); x++) {
|
||||
for (int y = 0; y < worldGrid.getHeight(); y++) {
|
||||
if (isCellEmpty(x, y) && countNeighboringSheep(x, y) == 2) {
|
||||
newAgents.add(new Sheep(x, y)); // add sheep in cell that doesn't contain any agent if there are exactly 2 neighboring sheeps.
|
||||
}
|
||||
}
|
||||
}
|
||||
agents.addAll(newAgents);
|
||||
|
||||
//then evolution of the field
|
||||
// TODO : apply game rule to all cells of the field
|
||||
|
||||
|
||||
for (int x = 0; x < worldGrid.getWidth(); x++) {
|
||||
|
||||
for (int y = 0; y < worldGrid.getHeight(); y++) {
|
||||
|
||||
|
||||
int neighbor = worldGrid.countNeighbors(x, y); // Calculate number of neighbors
|
||||
|
||||
// Determine if cell should die, survive or birth.
|
||||
boolean survives = rules.shouldSurvive(neighbor);
|
||||
boolean born = rules.shouldBirth(neighbor);
|
||||
|
||||
// Determine if cell should become a zombie.
|
||||
boolean zombie = rules.shouldBecomeZombie(rules.zombieProbability());
|
||||
|
||||
if (getCell(x, y) == 1 && !survives && zombie) {
|
||||
setCell(x, y, 2); // Cell becomes zombie
|
||||
|
||||
|
||||
} else if (getCell(x, y) == 1 && !survives) {
|
||||
setCell(x, y, 0); // Cell dies
|
||||
|
||||
} else if (getCell(x, y) == 0 && born) {
|
||||
setCell(x, y, 1); // New cell is born
|
||||
} else if (getCell(x,y)==2) {
|
||||
|
||||
this.contaminateCell(x,y);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Check if there are more than 20 sheeps
|
||||
if (countSheep() > 20) {
|
||||
addWolfRandomly(); // Add a wolf if there are more than 20 sheeps on the grid.
|
||||
}
|
||||
}
|
||||
|
||||
// Method that add a Wolf to a random location
|
||||
public void addWolfRandomly() {
|
||||
Random rand = new Random();
|
||||
int x = rand.nextInt(getWidth()); // Assume getWidth() gives the grid width
|
||||
int y = rand.nextInt(getHeight()); // Assume getHeight() gives the grid height
|
||||
agents.add(new Wolf(x, y)); // Add a new Wolf to the list
|
||||
}
|
||||
|
||||
// Method that allows a zombie to randomly contaminate a cell around it
|
||||
public void contaminateCell(int x, int y) {
|
||||
rand = new Random();
|
||||
int direction = rand.nextInt(4);
|
||||
if(direction == 0 && x<99) {
|
||||
x+=1;
|
||||
}
|
||||
if(direction == 1 && y<99) {
|
||||
y+=1;
|
||||
}
|
||||
if(direction == 2 && x>0) {
|
||||
x-=1;
|
||||
}
|
||||
if(direction == 3 && y>0) {
|
||||
y-=1;
|
||||
}
|
||||
int contaminationProbability = rand.nextInt(4); // zombie has a 25% change of contaminating a cell.
|
||||
|
||||
if (getCell(x,y)==1 && contaminationProbability == 0) {
|
||||
this.setCell(x, y,2); // cell becomes zombie if contaminated
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private boolean isCellEmpty(int x, int y) {
|
||||
return agents.stream().noneMatch(agent -> agent.getX() == x && agent.getY() == y);
|
||||
}
|
||||
|
||||
// method that count the number of Neighboring Sheep to a precise cell.
|
||||
private int countNeighboringSheep(int x, int y) {
|
||||
int count = 0;
|
||||
for (Agent agent : agents) { // go through whole list of agents
|
||||
if (agent instanceof Sheep) { //only count sheeps
|
||||
if (Math.abs(agent.getX() - x) <= 1 && Math.abs(agent.getY() - y) <= 1 && !(agent.getX() == x && agent.getY() == y)) {// in a radius of 1 case around the case, without counting the case itself
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
// Method that counts the total number of sheeps on the grid
|
||||
public int countSheep() {
|
||||
int sheepCount = 0;
|
||||
for (Agent agent : agents) {
|
||||
if (agent instanceof Sheep) {
|
||||
sheepCount++; // Increment count if the agent is a Sheep
|
||||
}
|
||||
}
|
||||
return sheepCount;
|
||||
}
|
||||
|
||||
// DONETODO : apply game rule to all cells of the field
|
||||
//see method countNeighboring, makeStep and class Rules
|
||||
|
||||
/* 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 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,
|
||||
|
|
@ -119,11 +260,15 @@ public class Simulator extends Thread {
|
|||
* and the count is in the birth list,
|
||||
* then the cell becomes alive
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* leave this as is
|
||||
|
|
@ -136,14 +281,25 @@ public class Simulator extends Thread {
|
|||
* method called when clicking pause button
|
||||
*/
|
||||
public void togglePause() {
|
||||
// TODO : actually toggle the corresponding flag
|
||||
// DONETODO : actually toggle the corresponding flag
|
||||
pauseFlag = !pauseFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* method called when clicking on a cell in the interface
|
||||
*/
|
||||
public void clickCell(int x, int y) {
|
||||
//TODO : complete method
|
||||
if (clickActionFlag) {
|
||||
// Assuming different types of actions based on flag
|
||||
// E.g., toggling cell state
|
||||
int currentVal = worldGrid.getCell(x, y);
|
||||
int newVal = 1 - currentVal;
|
||||
setCell(x, y, newVal); // Toggle between 0 and 1
|
||||
|
||||
} else {
|
||||
// Assuming adding an agent if not toggling
|
||||
agents.add(new Sheep(x, y)); // Default health for new agents
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -153,9 +309,14 @@ public class Simulator extends Thread {
|
|||
* @return value of cell
|
||||
*/
|
||||
public int getCell(int x, int y) {
|
||||
//TODO : complete method with proper return
|
||||
return 0;
|
||||
//DONETODO : complete method with proper return
|
||||
return worldGrid.getCell(x,y);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return list of Animals in simulated world
|
||||
|
|
@ -170,6 +331,7 @@ public class Simulator extends Thread {
|
|||
* @param radius
|
||||
* @return list of agents in area
|
||||
*/
|
||||
|
||||
public ArrayList<Agent> getNeighboringAnimals(int x, int y, int radius){
|
||||
ArrayList<Agent> inArea = new ArrayList<Agent>();
|
||||
for(int i=0;i<agents.size();i++) {
|
||||
|
|
@ -180,16 +342,23 @@ public class Simulator extends Thread {
|
|||
}
|
||||
return inArea;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
/*
|
||||
* set value of cell
|
||||
* @param x coord of cell
|
||||
* @param y coord of cell
|
||||
* @param val to set in cell
|
||||
*/
|
||||
public void setCell(int x, int y, int val) {
|
||||
//TODO : complete method
|
||||
//DONETODO : complete method
|
||||
|
||||
worldGrid.setCell(x,y,val);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -197,13 +366,28 @@ public class Simulator extends Thread {
|
|||
* the simulated world in its present state
|
||||
*/
|
||||
public ArrayList<String> getSaveState() {
|
||||
//TODO : complete method with proper return
|
||||
return null;
|
||||
//DONETODO : complete method with proper return
|
||||
int[][] gridData = worldGrid.getGrid(); // Get the grid
|
||||
ArrayList<String> saveState = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < worldGrid.getHeight(); i++) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int j = 0; j < worldGrid.getWidth(); j++) {
|
||||
sb.append(gridData[i][j]);
|
||||
if (j < worldGrid.getWidth() - 1) {
|
||||
sb.append(";"); // Append a semicolon after each cell except the last in the row
|
||||
}
|
||||
}
|
||||
saveState.add(sb.toString()); // Add the string for this row to the list
|
||||
}
|
||||
|
||||
return saveState;
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param lines of file representing saved world state
|
||||
*/
|
||||
|
||||
public void loadSaveState(ArrayList<String> lines) {
|
||||
/*
|
||||
* First some checks that the file is usable
|
||||
|
|
@ -211,6 +395,7 @@ public class Simulator extends Thread {
|
|||
* "Guard clauses", as they guard the method
|
||||
* against unwanted inputs
|
||||
*/
|
||||
|
||||
if(lines.size()<=0) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -219,10 +404,12 @@ 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<lines.size();y++) {
|
||||
String line = lines.get(y);
|
||||
String[] lineElements = line.split(";");
|
||||
|
|
@ -234,6 +421,9 @@ public class Simulator extends Thread {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* called by button, with slider providing the argument
|
||||
* makes a new world state with random cell states
|
||||
|
|
@ -241,32 +431,41 @@ public class Simulator extends Thread {
|
|||
* to be alive in new state
|
||||
*/
|
||||
public void generateRandom(float chanceOfLife) {
|
||||
//TODO : complete method
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
//DONETODO : complete method
|
||||
|
||||
|
||||
for (int i = 0; i < worldGrid.getHeight(); i++) {
|
||||
for (int j = 0; j < worldGrid.getWidth(); j++) {
|
||||
// Generate a random float and compare with the chance of life
|
||||
Random randGenerator = new Random();
|
||||
if (randGenerator.nextFloat() < chanceOfLife) {
|
||||
worldGrid.setCell(i, j, 1); // Set cell as alive
|
||||
} else {
|
||||
worldGrid.setCell(i, j, 0); // Set cell as dead
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public boolean isLoopingBorder() {
|
||||
//TODO : complete method with proper return
|
||||
return false;
|
||||
//DONETODO : complete method with proper return
|
||||
return loopingBorder ;
|
||||
}
|
||||
|
||||
public void toggleLoopingBorder() {
|
||||
//TODO : complete method
|
||||
//DONETODO : complete method
|
||||
loopingBorder = !loopingBorder;
|
||||
|
||||
}
|
||||
|
||||
public void setLoopDelay(int delay) {
|
||||
//TODO : complete method
|
||||
loopDelay = delay;
|
||||
}
|
||||
|
||||
public void toggleClickAction() {
|
||||
//TODO : complete method
|
||||
//DONETODO : complete method
|
||||
clickActionFlag = !clickActionFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -278,44 +477,64 @@ public class Simulator extends Thread {
|
|||
* @see loadRule for inverse process
|
||||
*/
|
||||
public ArrayList<String> getRule() {
|
||||
//TODO : complete method with proper return
|
||||
|
||||
return null;
|
||||
}
|
||||
ArrayList<String> rules = new ArrayList<>();
|
||||
StringBuilder sbSurvive = new StringBuilder("Survive:");
|
||||
for (Integer val : fieldSurviveValues) {
|
||||
sbSurvive.append(val).append(";");
|
||||
}
|
||||
if (!fieldSurviveValues.isEmpty()) sbSurvive.deleteCharAt(sbSurvive.length() - 1);
|
||||
|
||||
public void loadRule(ArrayList<String> 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<surviveElements.length;x++) {
|
||||
String elem = surviveElements[x];
|
||||
int value = Integer.parseInt(elem);
|
||||
//TODO : add value to possible survive values
|
||||
|
||||
}
|
||||
String[] birthElements = birthLine.split(";");
|
||||
for(int x=0; x<birthElements.length;x++) {
|
||||
String elem = birthElements[x];
|
||||
int value = Integer.parseInt(elem);
|
||||
//TODO : add value to possible birth values
|
||||
|
||||
}
|
||||
StringBuilder sbBirth = new StringBuilder("Birth:");
|
||||
for (Integer val : fieldBirthValues) {
|
||||
sbBirth.append(val).append(";");
|
||||
}
|
||||
if (!fieldBirthValues.isEmpty()) sbBirth.deleteCharAt(sbBirth.length() - 1);
|
||||
|
||||
rules.add(sbSurvive.toString());
|
||||
rules.add(sbBirth.toString());
|
||||
return rules;
|
||||
}
|
||||
|
||||
public ArrayList<String> getAgentsSave() {
|
||||
//TODO : Same idea as the other save method, but for agents
|
||||
return null;
|
||||
//load rules from file
|
||||
|
||||
public void loadRule(ArrayList<String> lines) {
|
||||
rules.loadRule(lines);
|
||||
if(lines.size()>=3) {
|
||||
rules.loadZombieRule(lines) ;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void loadAgents(ArrayList<String> stringArray) {
|
||||
//TODO : Same idea as other load methods, but for agent list
|
||||
|
||||
//method that return a string of agents
|
||||
|
||||
public ArrayList<String> getAgentsSave() {
|
||||
ArrayList<String> agentStates = new ArrayList<>();
|
||||
for (Agent agent : agents) {
|
||||
agentStates.add(agent.toString());
|
||||
}
|
||||
return agentStates;
|
||||
|
||||
}
|
||||
|
||||
//method that allows to load a file containing agent coordinates.
|
||||
|
||||
public void loadAgents(ArrayList<String> lines) {
|
||||
|
||||
|
||||
for (String line : lines) {
|
||||
String[] coordinates = line.split(";");
|
||||
int x = Integer.parseInt(coordinates[0]);
|
||||
int y = Integer.parseInt(coordinates[1]);
|
||||
if (Integer.parseInt(coordinates[2])==0) {
|
||||
agents.add(new Sheep(x, y));
|
||||
}
|
||||
if (Integer.parseInt(coordinates[2])==1) {
|
||||
agents.add(new Wolf(x, y));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -324,9 +543,14 @@ public class Simulator extends Thread {
|
|||
* @return String representation of click action
|
||||
*/
|
||||
public String clickActionName() {
|
||||
// TODO : initially return "sheep" or "cell"
|
||||
// depending on clickActionFlag
|
||||
return "";
|
||||
// Check the state of clickActionFlag
|
||||
// Assuming true means we're placing an agent (e.g., Sheep)
|
||||
// and false means we're toggling the state of a cell
|
||||
if (clickActionFlag) {
|
||||
return "cell"; // When flag is true, clicking adds a sheep
|
||||
} else {
|
||||
return "sheep"; // When flag is false, clicking toggles cell state
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,73 @@
|
|||
package backend;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
|
||||
public class Wolf extends Agent {
|
||||
private int loneliness; // this variable will be used to track how many steps since wolf found a friend
|
||||
ArrayList<Agent> neighbors = new ArrayList<>();
|
||||
|
||||
|
||||
public Wolf(int x, int y) {
|
||||
super(x, y,Color.black);
|
||||
this.loneliness = 0; // Initialize loneliness to 0
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public boolean liveTurn(ArrayList<Agent> neighbors, Simulator world) {
|
||||
|
||||
|
||||
moveRandomly(world);
|
||||
|
||||
loneliness = lonelyWolf(neighbors);
|
||||
return loneliness < 5; // Wolf dies if he didn't find another neighboring agent for 5 steps
|
||||
}
|
||||
|
||||
public int lonelyWolf(ArrayList<Agent> allAgents) {
|
||||
// Check if there are no neighboring agents around
|
||||
neighbors = findNeighbors(allAgents,1);
|
||||
if (neighbors.isEmpty()) {
|
||||
loneliness++; // Increase loneliness if there are no neighbors
|
||||
} else {
|
||||
loneliness = 0; // Reset loneliness if there are neighbors
|
||||
}
|
||||
return loneliness;
|
||||
}
|
||||
|
||||
//method to find every agent near the wolf
|
||||
private ArrayList<Agent> findNeighbors(ArrayList<Agent> allAgents, int radius) {
|
||||
|
||||
for (Agent agent : allAgents) {
|
||||
if (agent != this && this.isInArea(agent.getX(), agent.getY(), radius)) {
|
||||
neighbors.add(agent);
|
||||
}
|
||||
}
|
||||
return neighbors;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//method that makes a wolf move randomly
|
||||
private void moveRandomly(Simulator world) {
|
||||
Random rand = new Random();
|
||||
// Move randomly by one cell in any direction (including staying in the same place)
|
||||
int newX = Math.max(0, Math.min(world.getWidth() - 1, getX() + rand.nextInt(3) - 1));
|
||||
int newY = Math.max(0, Math.min(world.getHeight() - 1, getY() + rand.nextInt(3) - 1));
|
||||
setPosition(newX, newY);
|
||||
}
|
||||
|
||||
// set position of wolf
|
||||
private void setPosition(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
|
|
@ -43,12 +43,12 @@ public class JPanelDraw extends JPanel {
|
|||
@Override
|
||||
protected void paintComponent(Graphics g) {
|
||||
super.paintComponent(g);
|
||||
this.setBackground(Color.black);
|
||||
this.setBackground(Color.gray);
|
||||
if (mySimu != null) {
|
||||
// Draw Interface from state of simulator
|
||||
float cellWidth = (float)this.getWidth()/(float)mySimu.getWidth();
|
||||
float cellHeight = (float)this.getHeight()/(float)mySimu.getHeight();
|
||||
g.setColor(Color.gray);
|
||||
g.setColor(Color.black);
|
||||
for(int x=0; x<mySimu.getWidth();x++) {
|
||||
int graphX = Math.round(x*cellWidth);
|
||||
g.drawLine(graphX, 0, graphX, this.getHeight());
|
||||
|
|
|
|||
Loading…
Reference in New Issue