feat: Add rooks to game system

This commit is contained in:
overflowerror 2023-12-30 13:53:33 +01:00
parent 2624fb191a
commit 5b9178b11d
2 changed files with 187 additions and 0 deletions

88
src/Game/Rook.php Normal file
View file

@ -0,0 +1,88 @@
<?php
namespace Game;
class Rook extends Piece {
public function getName(): string {
return "Rook";
}
public function getShort(): string {
return "R";
}
public function getMoveCandidateMap(FieldBitMap $occupied, FieldBitMap $captureable, FieldBitMap $threatened): FieldBitMap {
$result = FieldBitMap::empty();
for ($offset = 1; $offset < 8; $offset++) {
$candidate = new Position($this->position->file, $this->position->rank + $offset);
if (!$candidate->isValid()) {
break;
}
if ($occupied->has($candidate)) {
break;
}
$result->add($candidate);
if ($captureable->has($candidate)) {
break;
}
}
for ($offset = -1; $offset > -8; $offset--) {
$candidate = new Position($this->position->file, $this->position->rank + $offset);
if (!$candidate->isValid()) {
break;
}
if ($occupied->has($candidate)) {
break;
}
$result->add($candidate);
if ($captureable->has($candidate)) {
break;
}
}
for ($offset = 1; $offset < 8; $offset++) {
$candidate = new Position($this->position->file + $offset, $this->position->rank);
if (!$candidate->isValid()) {
break;
}
if ($occupied->has($candidate)) {
break;
}
$result->add($candidate);
if ($captureable->has($candidate)) {
break;
}
}
for ($offset = -1; $offset > -8; $offset--) {
$candidate = new Position($this->position->file + $offset, $this->position->rank);
if (!$candidate->isValid()) {
break;
}
if ($occupied->has($candidate)) {
break;
}
$result->add($candidate);
if ($captureable->has($candidate)) {
break;
}
}
return $result;
}
}

99
tests/Game/RookTest.php Normal file
View file

@ -0,0 +1,99 @@
<?php
declare(strict_types=1);
namespace Game;
use PHPUnit\Framework\TestCase;
final class RookTest extends TestCase {
public function testMoves_unobstructed() {
$subject = new Rook(new Position(
3, 4
), Side::WHITE);
$result = $subject->getMoveCandidateMap(FieldBitMap::empty(), FieldBitMap::empty(), FieldBitMap::empty());
$this->assertTrue(
$result->equals(new FieldBitMap([
new Position(3, 0),
new Position(3, 1),
new Position(3, 2),
new Position(3, 3),
new Position(3, 5),
new Position(3, 6),
new Position(3, 7),
new Position(0, 4),
new Position(1, 4),
new Position(2, 4),
new Position(4, 4),
new Position(5, 4),
new Position(6, 4),
new Position(7, 4),
]))
);
}
public function testMoves_obstructed() {
$subject = new Rook(new Position(
3, 0
), Side::WHITE);
$result = $subject->getMoveCandidateMap(
new FieldBitMap([
new Position(3, 3),
new Position(5, 0)
]),
new FieldBitMap([
new Position(1, 0)
]),
FieldBitMap::empty()
);
$this->assertTrue(
$result->equals(new FieldBitMap([
new Position(3, 1),
new Position(3, 2),
new Position(1, 0),
new Position(2, 0),
new Position(4, 0),
]))
);
}
public function testCaptureable() {
$subject = new Rook(
new Position(5, 6),
Side::WHITE,
);
$this->assertTrue(
$subject->getCaptureableMap(true)->equals(new FieldBitMap([
new Position(5, 6)
]))
);
}
public function testCaptureMap() {
$subject = new Rook(new Position(
5, 2
), Side::WHITE);
$result = $subject->getCaptureMap(
new FieldBitMap([
new Position(4, 2),
new Position(6, 2),
new Position(5, 4),
])
);
$this->assertTrue(
$result->equals(new FieldBitMap([
new Position(5, 0),
new Position(5, 1),
new Position(5, 3),
]))
);
}
}