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