Thomas Papendieck
2 years ago
7 changed files with 303 additions and 0 deletions
-
12src/main/java/de/hsfulda/pmuw/CgolLauncher.java
-
73src/main/java/de/hsfulda/pmuw/oop/CellCreator.java
-
59src/main/java/de/hsfulda/pmuw/oop/CgolBoardOop.java
-
51src/main/java/de/hsfulda/pmuw/oop/CgolCell.java
-
24src/main/java/de/hsfulda/pmuw/oop/NeighborPosition.java
-
4src/main/java/de/hsfulda/pmuw/oop/StateChangeListener.java
-
80src/main/java/de/hsfulda/pmuw/procedural/CgolBoardProcedural.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); |
|||
} |
|||
|
|||
} |
@ -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); |
|||
} |
|||
} |
|||
|
|||
} |
@ -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)); |
|||
} |
|||
|
|||
} |
@ -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; |
|||
} |
|||
|
|||
} |
@ -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); |
|||
} |
|||
} |
@ -0,0 +1,4 @@ |
|||
package de.hsfulda.pmuw.oop; |
|||
interface StateChangeListener<T> { |
|||
void addActiveCell(T cell); |
|||
} |
@ -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)); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue