Skip to content

Instantly share code, notes, and snippets.

@navt
Created August 17, 2021 17:56
Show Gist options
  • Save navt/917d94048d47254bf2032b4336a8b6da to your computer and use it in GitHub Desktop.
Save navt/917d94048d47254bf2032b4336a8b6da to your computer and use it in GitHub Desktop.
cli-приложение Крестики-Нолики
<?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