Skip to content

Instantly share code, notes, and snippets.

@nemilya
Created May 28, 2021 20:44
Show Gist options
  • Save nemilya/bb7d30bd9bd7c4f8b77d6b5f69b24227 to your computer and use it in GitHub Desktop.
Save nemilya/bb7d30bd9bd7c4f8b77d6b5f69b24227 to your computer and use it in GitHub Desktop.
Dart Game of Life
void main() {
var asciiMap = ".*.\n"
".*.\n"
".*.";
var game_of_life = new GameLife();
game_of_life.setWorld(asciiMap);
print(game_of_life.getWorldAsAscii());
game_of_life.step();
print("\n");
print(game_of_life.getWorldAsAscii());
}
// https://github.com/nemilya/game_life_dart
class GameLife{
late World generation;
GameLife(){
generation = new World();
}
void setWorld(String asciiMap){
generation.parse(asciiMap);
}
String getWorldAsAscii(){
return generation.asAscii();
}
// generate next generation
void step(){
World nextGeneration = new World();
nextGeneration.init(rowsCnt: generation.rowsCnt, colsCnt: generation.colsCnt);
for (var r = 0; r < generation.rowsCnt; r++){
for (var c = 0; c < generation.colsCnt; c++){
var curCellState = generation.getCellAt(r, c);
var neighborsCnt = generation.neighborsCntAt(r, c);
var nextCellState = Cell.nextGenerationState(curCellState, neighborsCnt);
nextGeneration.setCell(r, c, nextCellState);
}
}
generation = nextGeneration;
}
}
enum CellState { life, empty }
class Cell{
static const ASCII_EMPTY = '.';
static const ASCII_LIFE = '*';
static CellState asciiToCellState(String asciiCellState){
switch(asciiCellState){
case ASCII_EMPTY:
return CellState.empty;
case ASCII_LIFE:
return CellState.life;
default:
return CellState.empty;
}
}
static String cellStateToAscii(CellState cellState){
switch(cellState){
case CellState.empty:
return ASCII_EMPTY;
case CellState.life:
return ASCII_LIFE;
default:
return ASCII_EMPTY;
}
}
static CellState nextGenerationState(CellState cellState, int neighborsCnt){
switch(cellState){
case CellState.empty:
return
neighborsCnt == 3 ?
CellState.life : CellState.empty;
case CellState.life:
return
(neighborsCnt == 3 || neighborsCnt == 2) ?
CellState.life : CellState.empty;
}
}
}
class World {
late int rowsCnt;
late int colsCnt;
late List<List<CellState>> cells;
void init({required int rowsCnt, required int colsCnt}){
cells = [];
this.rowsCnt = rowsCnt;
this.colsCnt = colsCnt;
for(int r = 0; r < rowsCnt; r++){
cells.add(List.filled(colsCnt, CellState.empty));
}
}
CellState getCellAt(int row, int col){
// test for out of range
if (row > rowsCnt-1 || col > colsCnt-1 || row < 0 || col < 0) return CellState.empty;
return cells[row][col];
}
void setCell(int row, int col, CellState cellState){
cells[row][col] = cellState;
}
void parse(String asciiMap){
List<String> rows = asciiMap.split("\n");
int _rowsCnt = rows.length;
int _colsCnt = rows[0].split('').length;
init(rowsCnt: _rowsCnt, colsCnt: _colsCnt);
var r = 0;
for (var row in rows){
var elements = row.split('');
var c = 0;
for (var asciiCellState in elements){
var cellState = Cell.asciiToCellState(asciiCellState);
setCell(r, c, cellState);
c += 1;
};
r += 1;
}
}
int neighborsCntAt(int row, int col){
int neighborsCnt = 0;
for (var deltaRow in [-1, 0, 1]){
for (var deltaCol in [-1, 0, 1]){
if (deltaRow == 0 && deltaCol == 0){
continue;
};
if (getCellAt(row+deltaRow, col+deltaCol) == CellState.life){
neighborsCnt += 1;
};
}; // for deltaRow
}; // for deltaCol
return neighborsCnt;
}
String asAscii(){
List<String> lines = [];
for (var r = 0; r < rowsCnt; r++){
String line = '';
for (var c = 0; c < colsCnt; c++){
var cellState = getCellAt(r, c);
var asciiCellState = Cell.cellStateToAscii(cellState);
line += asciiCellState;
};
lines.add(line);
};
return lines.join("\n");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment