jm.music.tools.ca.CellularAutomata Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jmusic Show documentation
Show all versions of jmusic Show documentation
JMusic - Java Music Library
The newest version!
/* --------------------
* A mathematical engine for Cellular Automata
* @author Andrew Troedson
* ---------------------
*/
package jm.music.tools.ca;
public class CellularAutomata {
/*--------------------
* CLASS VARIABLES
* --------------------
*/
int xSize; //the width of the grid
int ySize; //the height of the grid
boolean wrapAround; //the grid wrap Around switch
boolean[][] cellStates; //stores the states of each cell in the grid
int[][] cellSurrounds; //stores the number of living cells surrounding each cell in the grid
/*--------------------
* CONSTRUCTORS
* --------------------
*/
//wrapAround defaults to false, seed defaults to 25
public CellularAutomata(int xSize, int ySize) {
this(xSize, ySize, 25, false);
}
//wrapAround defaults to false
public CellularAutomata(int xSize, int ySize, int seed) {
this(xSize, ySize, seed, false);
}
//creates and fills a boolean[][] grid
public CellularAutomata(int xSize, int ySize, int seed, boolean wrapAround) {
this.xSize = xSize;
this.ySize = ySize;
this.wrapAround = wrapAround;
cellStates = new boolean[xSize][ySize];
cellSurrounds = new int[xSize][ySize];
this.setGrid(seed);
}
/*--------------------
* METHODS
* --------------------
*/
/**
* Evolve all the cells according to a set of rules
*/
public void evolve() {
boolean[][] nextCellStates = new boolean[xSize][ySize];
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
//if cell is already alive, it must be surrounded by 3 live cells to stay alive
if (this.getState(i, j)) {
if (this.getSurrounding(i, j) == 2) {
nextCellStates[i][j] = true;
} else {
nextCellStates[i][j] = false;
}
}
//if cell is dead, it must be surrounded by 2 or 3 live cells to come alive
else if (this.getState(i, j) == false) {
if ((this.getSurrounding(i, j) == 2) || (this.getSurrounding(i, j) == 3)) {
nextCellStates[i][j] = true;
}
}
}
}
this.cellStates = nextCellStates;
}
/**
* Return the state of a particular cell
*
* @param xPos the x coordinate
* @param yPos the y coordinate
* @return boolean the state of the cell at the specified coordinate
*/
public boolean getState(int xPos, int yPos) {
return cellStates[xPos][yPos];
}
//get the states of all the cells as a boolean[][]
public boolean[][] getAllStates() {
return cellStates;
}
//counts the number of living cells surrounding the selected cell
public int getSurrounding(int xPos, int yPos) {
int counter = 0; //stores the current count
try {
if (cellStates[xPos - 1][yPos - 1] == true) {//NW
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if ((xPos - 1 < 0) && (yPos - 1 < 0)) {
if (cellStates[xSize - 1][ySize - 1] == true) {
counter++;
}
} else if (xPos - 1 < 0) {
if (cellStates[xSize - 1][yPos - 1] == true) {
counter++;
}
} else if (yPos - 1 < 0) {
if (cellStates[xPos - 1][ySize - 1] == true) {
counter++;
}
}
}
}
try {
if (cellStates[xPos][yPos - 1] == true) {//N
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if (cellStates[xPos][ySize - 1] == true) {
counter++;
}
}
}
try {
if (cellStates[xPos + 1][yPos - 1] == true) {//NE
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if ((xPos + 1 >= xSize) && (yPos - 1 < 0)) {
if (cellStates[0][ySize - 1] == true) {
counter++;
}
} else if (xPos + 1 >= xSize) {
if (cellStates[0][yPos - 1] == true) {
counter++;
}
} else if (yPos - 1 < 0) {
if (cellStates[xPos + 1][ySize - 1] == true) {
counter++;
}
}
}
}
try {
if (cellStates[xPos - 1][yPos] == true) {//W
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if (cellStates[xSize - 1][yPos] == true) {
counter++;
}
}
}
try {
if (cellStates[xPos + 1][yPos] == true) {//E
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if (cellStates[0][yPos] == true) {
counter++;
}
}
}
try {
if (cellStates[xPos - 1][yPos + 1] == true) {//SW
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if ((xPos - 1 < 0) && (yPos + 1 >= ySize)) {
if (cellStates[xSize - 1][0] == true) {
counter++;
}
} else if (xPos - 1 < 0) {
if (cellStates[xSize - 1][yPos + 1] == true) {
counter++;
}
} else if (yPos + 1 >= ySize) {
if (cellStates[xPos - 1][0] == true) {
counter++;
}
}
}
}
try {
if (cellStates[xPos][yPos + 1] == true) {//S
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if (cellStates[xPos][0] == true) {
counter++;
}
}
}
try {
if (cellStates[xPos + 1][yPos + 1] == true) {//SE
counter++;
}
} catch (ArrayIndexOutOfBoundsException e) {
if (wrapAround) {
if ((xPos + 1 >= xSize) && (yPos + 1 >= ySize)) {
if (cellStates[0][0] == true) {
counter++;
}
} else if (xPos + 1 >= xSize) {
if (cellStates[0][yPos + 1] == true) {
counter++;
}
} else if (yPos + 1 >= ySize) {
if (cellStates[xPos + 1][0] == true) {
counter++;
}
}
}
}
return counter;
}
/**
* prints out the current grid
*/
public void print() {
for (int i = 0; i < this.xSize; i++) {
for (int j = 0; j < this.ySize; j++) {
if (this.getState(i, j) == true) {
System.out.print("1");
} else {
System.out.print("0");
}
}
System.out.println("");
}
System.out.println("");
}
/**
* fill the cellStates grid based on the seed probability
*/
public void setGrid(int seed) {
for (int i = 0; i < xSize; i++) {
for (int j = 0; j < ySize; j++) {
cellStates[i][j] = this.trueFalse(seed);
}
}
}
//a method which chooses true or false given a probability
private boolean trueFalse(int seed) {
boolean choice;
int randNum = (int) (java.lang.Math.random() * 100);
if (randNum < seed) {
choice = true;
} else {
choice = false;
}
return choice;
}
}