class Board
{
const MARK_0 = 0;
const MARK_X = 1;
/** @var int */
private $sizeX;
/** @var int */
private $sizeY;
/** @var int */
private $requiredMarks;
/** @var array */
private $map = [];
/**
* @param int $sizeX
* @param int $sizeY
*/
public function __construct (int $sizeX = 3, int $sizeY = 3)
{
$this->sizeX = $sizeX;
$this->sizeY = $sizeY;
$this->requiredMarks = $sizeX;
}
/**
* @return int
*/
public function getSizeX() : int
{
return $this->sizeX;
}
/**
* @return int
*/
public function getSizeY() : int
{
return $this->sizeY;
}
/**
* @return int
*/
public function getRequiredMarks() : int
{
return $this->requiredMarks;
}
/**
* @param int $count
*/
public function setRequiredMarks (int $count) : void
{
$this->requiredMarks = $count;
}
/**
* @param int $x
* @param int $y
* @param int $mark
*/
public function setMark (int $x, int $y, int $mark) : void
{
$this->map[$x][$y] = $mark;
}
/**
* @param int $x
* @param int $y
*
* @return int|null
*/
public function getMark (int $x, int $y) : ?int
{
return $this->map[$x][$y] ?? null;
}
/**
* @return int|null
*/
public function checkWin() : ?int
{
foreach([self::MARK_0, self::MARK_X] as $mark)
{
if(/* $this->checkLanes($mark) || */ $this->checkDiagonals($mark))
{
return $mark;
}
}
return null;
}
/**
* @param int $mark
*
* @return bool
*/
private function checkDiagonals (int $mark) : bool
{
$sizeX = $this->getSizeX();
$sizeY = $this->getSizeY();
$required = $this->getRequiredMarks();
$size = max($sizeX, $sizeY);
for($k = $required - $size; $k <= ($size - $required); $k++)
{
$score1 = 0;
$score2 = 0;
$startI = max(0, $k);
$endI = min($size, $size + $k);
for($i = $startI; $i < $endI; $i++)
{
if($this->getMark($i, $k + $i) === $mark)
{
if(++$score1 >= $required)
{
return true;
}
}
else
{
$score1 = 0;
}
if($this->getMark($i, $size - 1 + $k - $i) === $mark)
{
if(++$score2 >= $required)
{
return true;
}
}
else
{
$score2 = 0;
}
}
}
return false;
}
}
$b = new Board (4, 4);
$b->setRequiredMarks(3);
$b->setMark(0, 1, Board::MARK_X);
$b->setMark(1, 2, Board::MARK_X);
$b->setMark(2, 3, Board::MARK_X);
$winner = $b->checkWin();
if($winner === null)
{
$winner = "nobody";
}
elseif($winner === Board::MARK_X)
{
$winner = "X";
}
else
{
$winner = "0";
}
var_dump($winner);
How to fix the function "checkDiagonals", so that the processing of the diagonal as in the photo occurred correctly and returned the correct result?
If do a check on the diagonal, as in the photo, it works correctly.
I can not think of an algorithm for checking diagonals, so I took it from here: https://stackoverflow.com/a/34257658/10261980
The commented function "checkLanes" works correctly, so it is hidden from the code.