Skip to content

Instantly share code, notes, and snippets.

@elazar
Created May 17, 2020 12:26
Show Gist options
  • Save elazar/b30446f8ead6170c9ef888234dba6776 to your computer and use it in GitHub Desktop.
Save elazar/b30446f8ead6170c9ef888234dba6776 to your computer and use it in GitHub Desktop.
Conway's Game of Life
<?php
$height = 20;
$width = 40;
$live_seeds = 20;
$delay = 1000000;
$empty_grid = fn(): array => array_fill(0, $height, array_fill(0, $width, false));
$random_percent = fn(): float => rand(0, 100) / 100;
$seed_cell = fn(float $x_seed, float $y_seed): array => [ floor($x_seed * $height), floor($y_seed * $width) ];
$seed_pairs = function (int $max_seeds, array $seeds = []) use ($seed_cell, $random_percent, &$seed_pairs): array {
if (count($seeds) === $max_seeds) {
return $seeds;
}
do {
$cell = $seed_cell($random_percent(), $random_percent());
} while (in_array($cell, $seeds));
return $seed_pairs($max_seeds, [ ...$seeds, $cell ]);
};
$populate_grid = function (array $grid, array $pairs) use (&$populate_grid): array {
if (empty($pairs)) {
return $grid;
}
$pair = array_slice($pairs, 0, 1)[0];
$pairs = array_slice($pairs, 1);
[ $x, $y ] = $pair;
$grid[$x][$y] = true;
return $populate_grid($grid, $pairs);
};
$initialize_grid = fn(): array => $populate_grid($empty_grid(), $seed_pairs($live_seeds));
$print_cell = fn(bool $cell): string => $cell ? 'O' : '-';
$print_grid = function (array $grid) use ($print_cell): void {
foreach ($grid as $row) {
foreach ($row as $cell) {
echo $print_cell($cell);
}
echo PHP_EOL;
}
};
$next_cell = function (int $x, int $y) use ($height, $width): ?array {
if ($x < $height) {
return [ $x + 1, $y ];
}
$y++;
if ($y < $width) {
return [ 0, $y ];
}
return null;
};
$live_neighbors = function (array $grid, int $x, int $y): int {
$xmo = $x - 1;
$xpo = $x + 1;
$ymo = $y - 1;
$ypo = $y + 1;
$cell = fn(int $cx, int $cy): ?bool => $grid[$cx][$cy] ?? null;
return count(array_filter([
$cell($xmo, $ymo),
$cell($x, $ymo),
$cell($xpo, $ymo),
$cell($xmo, $y),
$cell($x, $y),
$cell($xpo, $y),
$cell($xmo, $ypo),
$cell($x, $ypo),
$cell($xpo, $ypo),
]));
};
$iterate_cell = function (array $grid, int $x, int $y) use ($live_neighbors): bool {
$neighbors = $live_neighbors($grid, $x, $y);
return $neighbors === 2 || $neighbors === 3;
};
$iterate_grid = function (array $grid, array $cell = [ 0, 0 ]) use ($next_cell, $iterate_cell, &$iterate_grid): array {
[ $x, $y ] = $cell;
$grid[$x][$y] = $iterate_cell($grid, $x, $y);
$cell = $next_cell($x, $y);
return $cell ? $iterate_grid($grid, $cell) : $grid;
};
$grid = $initialize_grid();
while (true) {
echo shell_exec('clear');
$print_grid($grid);
$grid = $iterate_grid($grid);
usleep($delay);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment