Created
October 9, 2020 11:58
-
-
Save rexim/6eca064ba5b05677415ca86bfcfea3f5 to your computer and use it in GitHub Desktop.
Game of Life in D
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import std.stdio; | |
import std.traits; | |
import core.thread.osthread; | |
import core.time; | |
enum Cell { | |
Dead = 0, | |
Alive | |
} | |
T modulo(T)(T a, T b) if (isIntegral!T) | |
{ | |
return ((a % b) + b) % b; | |
} | |
struct Board(int W, int H) { | |
Cell[H][W] cells; | |
void clear() | |
{ | |
write("\033[", H, "A"); | |
write("\033[", W, "D"); | |
} | |
void render() | |
{ | |
foreach(row; cells) { | |
foreach(cell; row) { | |
final switch (cell) { | |
case Cell.Dead: | |
write("."); | |
break; | |
case Cell.Alive: | |
write("#"); | |
break; | |
} | |
} | |
writeln(); | |
} | |
} | |
void put_glider_at(int y, int x) | |
{ | |
// .#. | |
// ..# | |
// ### | |
cells[y + 0][x + 1] = Cell.Alive; | |
cells[y + 1][x + 2] = Cell.Alive; | |
cells[y + 2][x + 0] = Cell.Alive; | |
cells[y + 2][x + 1] = Cell.Alive; | |
cells[y + 2][x + 2] = Cell.Alive; | |
} | |
int count_nbors(int y0, int x0) | |
{ | |
// ... | |
// .#. | |
// ... | |
int result = 0; | |
for (int dy = -1; dy <= 1; ++dy) { | |
for (int dx = -1; dx <= 1; ++dx) { | |
if (dx != 0 || dy != 0) { | |
auto x = modulo(x0 + dx, W); | |
auto y = modulo(y0 + dy, H); | |
if (cells[y][x] == Cell.Alive) { | |
result += 1; | |
} | |
} | |
} | |
} | |
return result; | |
} | |
void next_generation(ref Board!(W, H) board) | |
{ | |
for (int y = 0; y < H; ++y) { | |
for (int x = 0; x < W; ++x) { | |
auto nbors = count_nbors(y, x); | |
final switch (cells[y][x]) { | |
case Cell.Alive: | |
board.cells[y][x] = nbors == 2 || nbors == 3 ? Cell.Alive : Cell.Dead; | |
break; | |
case Cell.Dead: | |
board.cells[y][x] = nbors == 3 ? Cell.Alive : Cell.Dead; | |
break; | |
} | |
} | |
} | |
} | |
} | |
void main() | |
{ | |
int fg = 0; | |
Board!(20, 20)[2] board; | |
for (int i = 0; i < 5; ++i) { | |
board[fg].put_glider_at(4 * i, 4 * i); | |
} | |
while (true) { | |
board[fg].render(); | |
Thread.sleep(dur!("msecs")(100)); | |
int bg = 1 - fg; | |
board[fg].next_generation(board[bg]); | |
board[fg].clear(); | |
fg = bg; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment