Browse Source

procedural and OOP

master
Thomas Papendieck 1 year ago
parent
commit
8d7c46f965
  1. 12
      src/main/java/de/hsfulda/pmuw/CgolLauncher.java
  2. 73
      src/main/java/de/hsfulda/pmuw/oop/CellCreator.java
  3. 59
      src/main/java/de/hsfulda/pmuw/oop/CgolBoardOop.java
  4. 51
      src/main/java/de/hsfulda/pmuw/oop/CgolCell.java
  5. 24
      src/main/java/de/hsfulda/pmuw/oop/NeighborPosition.java
  6. 4
      src/main/java/de/hsfulda/pmuw/oop/StateChangeListener.java
  7. 80
      src/main/java/de/hsfulda/pmuw/procedural/CgolBoardProcedural.java

12
src/main/java/de/hsfulda/pmuw/CgolLauncher.java

@ -0,0 +1,12 @@
package de.hsfulda.pmuw;
import de.hsfulda.pmuw.oop.CgolBoardOop;
import de.hsfulda.pmuw.procedural.CgolBoardProcedural;
public class CgolLauncher {
public static void main(String[] args) {
CgolBoardProcedural.main(null);
CgolBoardOop.main(null);
}
}

73
src/main/java/de/hsfulda/pmuw/oop/CellCreator.java

@ -0,0 +1,73 @@
package de.hsfulda.pmuw.oop;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CellCreator {
/** one alive to X dead */
private static final int ALIVE_CELLS_RATIO = 30;
private static final int BOARD_SIZE = 500;
public static List<Boolean> aliveList = new Random().ints(0, ALIVE_CELLS_RATIO).limit(BOARD_SIZE * BOARD_SIZE)
.mapToObj(Integer::valueOf).map(i -> Boolean.valueOf(i == 0)).collect(Collectors.toList());
int calculateNeighbourIndex(List<CgolCell> allCells, CgolCell cgolCell, NeighborPosition neighborPosition) {
int row = cgolCell.row;
int column = cgolCell.column;
int size = allCells.size();
int index = neighborPosition.getIndex(row, column, BOARD_SIZE);
int finalIndex = (index + size) % size;
return finalIndex;
}
protected void createCells(Collection<CgolCell> activeCells, boolean isOptimized) {
StateChangeListener<CgolCell> changeListener = getChangeListener(activeCells, isOptimized);
List<CgolCell> allCells = createCells(changeListener);
constructGameField(activeCells, isOptimized, allCells);
System.out.println(String.format("active cells: %7s", activeCells.size()));
System.out.println(String.format("alive cells : %7s", allCells.stream().filter(CgolCell::isAlive).count()));
}
private StateChangeListener<CgolCell> getChangeListener(Collection<CgolCell> activeCells, boolean isOptimized) {
StateChangeListener<CgolCell> changeListener = isOptimized ? nc -> activeCells.add(nc) : nc -> {
;
};
return changeListener;
}
private List<CgolCell> createCells(StateChangeListener<CgolCell> changeListener) {
Iterator<Boolean> iterator = aliveList.iterator();
List<CgolCell> allCells = new ArrayList<>();
for (int row = 0; row < BOARD_SIZE; row++)
for (int col = 0; col < BOARD_SIZE; col++)
allCells.add(new CgolCell(row, col, iterator.next(), changeListener));
System.out.println(String.format("cells created: %7s", allCells.size()));
return allCells;
}
private void constructGameField(Collection<CgolCell> activeCells, boolean isOptimized, List<CgolCell> allCells) {
for (CgolCell cgolCell : allCells) {
Set<CgolCell> neighbors = Stream.of(NeighborPosition.values())
.map(np -> calculateNeighbourIndex(allCells, cgolCell, np)).map(allCells::get).collect(Collectors.toSet());
cgolCell.setNeighbors(neighbors);
if (cgolCell.isAlive()) {
if (isOptimized) {
activeCells.add(cgolCell);
activeCells.addAll(neighbors);
}
}
}
if (!isOptimized) {
activeCells.addAll(allCells);
}
}
}

59
src/main/java/de/hsfulda/pmuw/oop/CgolBoardOop.java

@ -0,0 +1,59 @@
package de.hsfulda.pmuw.oop;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
public class CgolBoardOop {
private final Collection<CgolCell> activeCells ;
private final CellCreator cellCreator;
private boolean isOptimized;
CgolBoardOop(CellCreator cellCreator, boolean isOptimized) {
this.cellCreator = cellCreator;
this.isOptimized = isOptimized;
activeCells = isOptimized? new HashSet<>():new ArrayList<>();
}
public void initialize() {
cellCreator.createCells(activeCells, isOptimized);
}
public void nextGen() {
List<CgolCell> currentGeneration = new ArrayList<>(activeCells);
if (isOptimized)
activeCells.clear();
currentGeneration.stream().parallel().forEach(CgolCell::calculateNextGeneration);
currentGeneration.stream().parallel().forEach(CgolCell::switchState);
}
private long countAliveCells() {
return activeCells.stream().filter(CgolCell::isAlive).count();
}
public static void main(String[] args) {
boolean isOptimized = true;
startGame(!isOptimized);
startGame(isOptimized);
}
private static void startGame(boolean isOptimized) {
long start = Calendar.getInstance().getTimeInMillis();
CgolBoardOop cgolBoard = new CgolBoardOop(new CellCreator(), isOptimized);
cgolBoard.initialize();
long end = Calendar.getInstance().getTimeInMillis();
System.out.println(String.format("initializing took: %sms", end - start));
start = Calendar.getInstance().getTimeInMillis();
int iterations = 1000;
for (int i = 0; i < iterations; i++) {
cgolBoard.nextGen();
if (0 == i % (isOptimized? 100:100))
System.out.println(String.format("iteration %6d cells alife: %7s , cells active %7s",i,cgolBoard.countAliveCells(),cgolBoard.activeCells.size()));
}
end = Calendar.getInstance().getTimeInMillis();
System.out.println(
String.format("time spend for %d iterations: %sms, optimized: %s\n\n", iterations, end - start, isOptimized));
}
}

51
src/main/java/de/hsfulda/pmuw/oop/CgolCell.java

@ -0,0 +1,51 @@
package de.hsfulda.pmuw.oop;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import java.util.stream.Collectors;
public class CgolCell {
private final StateChangeListener<CgolCell> listener;
private CgolCell[] neighbors;
private boolean isAlive, nextState;
final int row, column;
public CgolCell(int row, int column, boolean isAlive, StateChangeListener<CgolCell> listener) {
super();
this.row = row;
this.column = column;
this.isAlive = this.nextState = isAlive;
this.listener = listener;
}
public boolean isAlive() {
return isAlive;
}
public void setNeighbors(Set<CgolCell> neighbors) {
this.neighbors = neighbors.toArray(new CgolCell[0]);
// System.out.print(neighbors.stream().map(n -> String.format("(r%d-c%d %s)", n.row, n.column ,n.isAlive?"*":"-"))
// .collect(Collectors.joining("", String.format("cell r%d-c%d:\n ", row, column), "\n")));
}
void calculateNextGeneration() {
int alifeNeigborsCount =0;
for (CgolCell cgolCell : neighbors) {
alifeNeigborsCount+= cgolCell.isAlive?1:0;
}
nextState = 3 == alifeNeigborsCount || (isAlive && (2 == alifeNeigborsCount));
}
void switchState() {
if (isAlive || nextState) {
for (CgolCell cgolCell : neighbors) {
listener.addActiveCell(cgolCell);
}
listener.addActiveCell(this);
}
isAlive = nextState;
}
}

24
src/main/java/de/hsfulda/pmuw/oop/NeighborPosition.java

@ -0,0 +1,24 @@
package de.hsfulda.pmuw.oop;
public enum NeighborPosition {
NORTH(-1, 0),
SOUTH(1, 0),
EAST(0, 1),
WEST(0, -1),
NORTH_EAST(-1, 1),
SOUTH_EAST(1, 1),
SOUTH_WEST(1, -1),
NORTH_WEST(-1, -1);
private final int rowOffset;
private final int columnOffset;
NeighborPosition(int rowOffset, int columnOffset) {
this.rowOffset = rowOffset;
this.columnOffset = columnOffset;
}
int getIndex(int row, int column, int rowSize) {
return (((row + rowOffset) * rowSize) + column + columnOffset);
}
}

4
src/main/java/de/hsfulda/pmuw/oop/StateChangeListener.java

@ -0,0 +1,4 @@
package de.hsfulda.pmuw.oop;
interface StateChangeListener<T> {
void addActiveCell(T cell);
}

80
src/main/java/de/hsfulda/pmuw/procedural/CgolBoardProcedural.java

@ -0,0 +1,80 @@
package de.hsfulda.pmuw.procedural;
import java.util.Calendar;
import java.util.Iterator;
import de.hsfulda.pmuw.oop.CellCreator;
public class CgolBoardProcedural {
/** one alive to X dead */
static final int ALIVE_CELLS_RATIO = 30;
static final int BOARD_SIZE = 500;
private boolean[][] board = new boolean[BOARD_SIZE][BOARD_SIZE];
public void initialize() {
createCells();
System.out.println(String.format("cells created: %7s", BOARD_SIZE*BOARD_SIZE));
System.out.println(String.format("active cells: %7s", BOARD_SIZE*BOARD_SIZE));
System.out.println(String.format("alive cells : %7s", countAliveCells()));
}
private void createCells() {
Iterator<Boolean> iterator = CellCreator.aliveList.iterator();
for (int row = 0; row < board.length; row++)
for (int col = 0; col < board[0].length; col++)
board[row][col] = iterator.next();
}
public void nextGen() {
boolean[][] nextGen = new boolean[BOARD_SIZE][BOARD_SIZE];
for (int row = 0; row < board.length; row++)
for (int col = 0; col < board[0].length; col++)
nextGen[row][col] = newStateOfCell(row, col);
board = nextGen;
}
private boolean newStateOfCell(int row, int col) {
int countAliveNeighbors = countAliveNeighbors(row, col);
return newState(countAliveNeighbors, board[row][col]);
}
private int countAliveNeighbors(int row, int col) {
int aliveNeighbors = 0;
for (int rOffset = -1; rOffset <= 1; rOffset++)
for (int cOffset = -1; cOffset <= 1; cOffset++)
aliveNeighbors += board[(row + rOffset + BOARD_SIZE) % BOARD_SIZE][(col + cOffset + BOARD_SIZE) % BOARD_SIZE]
? 1
: 0;
return aliveNeighbors - (board[row][col] ? 1 : 0);
}
private boolean newState(int aliveNeighbors, boolean isAlive) {
return 3 == aliveNeighbors || (isAlive && 2 == aliveNeighbors);
}
private int countAliveCells() {
int aliveCells = 0;
for (int row = 0; row < board.length; row++)
for (int col = 0; col < board[0].length; col++)
aliveCells += board[row][col] ? 1 : 0;
return aliveCells;
}
public static void main(String[] args) {
long start = Calendar.getInstance().getTimeInMillis();
CgolBoardProcedural cgolBoard = new CgolBoardProcedural();
cgolBoard.initialize();
long end = Calendar.getInstance().getTimeInMillis();
System.out.println(String.format("initializing took: %sms", end - start));
start = Calendar.getInstance().getTimeInMillis();
int iterations = 1000;
for (int i = 0; i < iterations; i++) {
cgolBoard.nextGen();
if (0 == i % 100)
System.out.println(String.format("iteration %6d cells alife: %s , cells active %7s", i, cgolBoard.countAliveCells(),BOARD_SIZE*BOARD_SIZE));
}
end = Calendar.getInstance().getTimeInMillis();
System.out.println(String.format("time spend for %d iterations: %sms\n\n", iterations, end - start));
}
}
Loading…
Cancel
Save