Created
August 17, 2021 17:56
-
-
Save navt/917d94048d47254bf2032b4336a8b6da to your computer and use it in GitHub Desktop.
cli-приложение Крестики-Нолики
This file contains 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
<?php | |
class CrossZero { | |
private $size; | |
private $table; | |
public const EMPTY = "-"; | |
public const X = "x"; | |
public const O = "o"; | |
public function __construct(int $size = 3) { | |
$this->size = $size; | |
$this->initTable(); | |
} | |
private function initTable(): void { | |
for ($i = 0; $i < $this->size; $i++) { | |
for ($j = 0; $j < $this->size; $j++) { | |
$this->table[$i][$j] = self::EMPTY; | |
} | |
} | |
} | |
public function printTable(): void { | |
for ($i = 0; $i < $this->size; $i++) { | |
$s = ""; | |
for ($j = 0; $j < $this->size; $j++) { | |
$s.= sprintf(" %s", $this->table[$i][$j]); | |
} | |
$s.= "\n"; | |
echo $s; | |
} | |
echo "\n"; | |
} | |
public function setSimbol(int $row, int $col, string $simbol): bool { | |
if ($this->table[$row][$col] != self::EMPTY) return false; | |
$this->table[$row][$col] = $simbol; | |
return true; | |
} | |
private function checkRows(string $simbol): bool { | |
for ($row = 0; $row < $this->size; $row++) { | |
$count = 0; | |
for ($col = 0; $col < $this->size; $col++) { | |
if ($this->table[$row][$col] == $simbol) $count++; | |
} | |
if ($count == $this->size) return true; | |
} | |
return false; | |
} | |
private function checkColumns(string $simbol): bool { | |
for ($col = 0; $col < $this->size; $col++) { | |
$count = 0; | |
for ($row = 0; $row < $this->size; $row++) { | |
if ($this->table[$row][$col] == $simbol) $count++; | |
} | |
if ($count == $this->size) return true; | |
} | |
return false; | |
} | |
private function checkDiagonal(string $simbol): bool { | |
$count = 0; | |
for ($i = 0; $i < $this->size; $i++) { | |
if ($this->table[$i][$i] == $simbol) $count++; | |
} | |
if ($count == $this->size) return true; | |
return false; | |
} | |
private function check2Diagonal(string $simbol): bool { | |
$count = 0; | |
for ($i = 0; $i < $this->size; $i++) { | |
if ($this->table[$this->size - $i -1][$i] == $simbol) $count++; | |
} | |
if ($count == $this->size) return true; | |
return false; | |
} | |
public function checkWin(string $simbol): bool { | |
if ($this->checkRows($simbol) === true) return true; | |
if ($this->checkColumns($simbol) === true) return true; | |
if ($this->checkDiagonal($simbol) === true) return true; | |
if ($this->check2Diagonal($simbol) === true) return true; | |
return false; | |
} | |
public function tableIsFull(): bool { | |
for ($i = 0; $i < $this->size; $i++) { | |
for ($j = 0; $j < $this->size; $j++) { | |
if ($this->table[$i][$j] === self::EMPTY) return false; | |
} | |
} | |
return true; | |
} | |
} | |
class Helper { | |
public static function readNumber(int $min, int $max): int { | |
while (true) { | |
$line = trim(fgets(STDIN)); | |
if (is_numeric($line) === false) { | |
echo "Должно быть введено число. Снова :"; | |
continue; | |
} | |
$number = (int)$line; | |
if ($number < $min || $number > $max) { | |
echo "Число не принадлежит нужному диапазону. Снова :"; | |
continue; | |
} else { | |
break; | |
} | |
} | |
return $number; | |
} | |
} | |
$ts = 3; // table size - размер таблицы | |
$xo = new CrossZero($ts); | |
while (true) { | |
// ход человека | |
do { | |
echo "Введите номер строки :"; | |
$row = Helper::readNumber(1, $ts); | |
echo "Введите номер столбца :"; | |
$col = Helper::readNumber(1, $ts); | |
} while ($xo->setSimbol($row - 1, $col - 1, CrossZero::X) === false); | |
$xo->printTable(); | |
// человек выиграл? | |
if ($xo->checkWin(CrossZero::X) === true) { | |
echo "Вы выиграли!\n"; | |
break; | |
} | |
// таблица заполнена полностью? | |
if ($xo->tableIsFull() === true) { | |
echo "Таблица заполнена полностью.\n"; | |
break; | |
} | |
// ход компьютера | |
do { | |
$row = random_int(0, $ts - 1); | |
$col = random_int(0, $ts - 1); | |
} while ($xo->setSimbol($row, $col, CrossZero::O) === false); | |
$xo->printTable(); | |
// компьютер выиграл? | |
if ($xo->checkWin(CrossZero::O) === true) { | |
echo "Компьютер выиграл!\n"; | |
break; | |
} | |
// таблица заполнена полностью? | |
if ($xo->tableIsFull() === true) { | |
echo "Таблица заполнена полностью.\n"; | |
break; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment