85 lines
1.9 KiB
PHP
85 lines
1.9 KiB
PHP
<?php
|
|
/*
|
|
* Game of Life in PHP using pure functions
|
|
*
|
|
* Joop Schilder
|
|
*/
|
|
if (version_compare(PHP_VERSION, '7.0') < 1) {
|
|
throw new RuntimeException('PHP>=7.0 required');
|
|
}
|
|
|
|
const BOARDSIZE = 32;
|
|
CONST DELAY_MS = 200;
|
|
const DEAD = 0;
|
|
const ALIVE = 1;
|
|
|
|
function get_neighbours(array $board, int $i, int $j): array
|
|
{
|
|
$neighbours = [];
|
|
for ($ni = $i - 1; $ni <= $i + 1; $ni++) {
|
|
for ($nj = $j - 1; $nj <= $j + 1; $nj++) {
|
|
if (isset($board[$ni][$nj]) && ($ni !== $i || $nj !== $j)) {
|
|
$neighbours[] = $board[$ni][$nj];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $neighbours;
|
|
}
|
|
|
|
function get_next_cell_state(array $board, int $i, int $j): int
|
|
{
|
|
$living_neighbours = count(array_filter(get_neighbours($board, $i, $j), function (int $state): bool {
|
|
return $state === ALIVE;
|
|
}));
|
|
$is_alive = $board[$i][$j] === ALIVE ? ($living_neighbours > 1 && $living_neighbours < 4) : $living_neighbours === 3;
|
|
|
|
return $is_alive ? ALIVE : DEAD;
|
|
}
|
|
|
|
function get_next_board_state(array $board): array
|
|
{
|
|
$next_board = [];
|
|
for ($i = 0; $i < BOARDSIZE; $i++) {
|
|
for ($j = 0; $j < BOARDSIZE; $j++) {
|
|
$next_board[$i][$j] = get_next_cell_state($board, $i, $j);
|
|
}
|
|
}
|
|
|
|
return $next_board;
|
|
}
|
|
|
|
function print_board(array $board): void
|
|
{
|
|
system('WIN' === strtoupper(substr(PHP_OS, 0, 3)) ? 'cls' : 'clear');
|
|
print('┌' . str_repeat('─', 2 * BOARDSIZE) . '┐' . PHP_EOL);
|
|
for ($i = 0; $i < BOARDSIZE; $i++) {
|
|
print('│');
|
|
for ($j = 0; $j < BOARDSIZE; $j++) {
|
|
print($board[$i][$j] === ALIVE ? '██' : '░░');
|
|
}
|
|
print('│' . PHP_EOL);
|
|
}
|
|
print('└' . str_repeat('─', 2 * BOARDSIZE) . '┘' . PHP_EOL);
|
|
}
|
|
|
|
$board = [];
|
|
for ($i = 0; $i < BOARDSIZE; $i++) {
|
|
for ($j = 0; $j < BOARDSIZE; $j++) {
|
|
$board[$i][$j] = DEAD;
|
|
}
|
|
}
|
|
|
|
// Glider
|
|
$board[1][3] = ALIVE;
|
|
$board[2][4] = ALIVE;
|
|
$board[3][2] = ALIVE;
|
|
$board[3][3] = ALIVE;
|
|
$board[3][4] = ALIVE;
|
|
|
|
while (true) {
|
|
print_board($board);
|
|
usleep(DELAY_MS * 1000);
|
|
$board = get_next_board_state($board);
|
|
}
|