Skip to content

Instantly share code, notes, and snippets.

@rexim
Created October 9, 2020 11:58
Show Gist options
  • Save rexim/6eca064ba5b05677415ca86bfcfea3f5 to your computer and use it in GitHub Desktop.
Save rexim/6eca064ba5b05677415ca86bfcfea3f5 to your computer and use it in GitHub Desktop.
Game of Life in D
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