feat: Add queens to game system

This commit is contained in:
overflowerror 2023-12-30 14:19:47 +01:00
parent 5b9178b11d
commit c74f53fce4
2 changed files with 231 additions and 0 deletions

112
src/Game/Queen.php Normal file
View file

@ -0,0 +1,112 @@
<?php
namespace Game;
class Queen extends Piece {
public function getName(): string {
return "Queen";
}
public function getShort(): string {
return "Q";
}
public function getMoveCandidateMap(FieldBitMap $occupied, FieldBitMap $captureable, FieldBitMap $threatened): FieldBitMap {
$result = FieldBitMap::empty();
$directions = [true, true, true, true];
for ($i = 1; $i < 8; $i++) {
for ($d = 0; $d < 4; $d++) {
if ($directions[$d]) {
$candidate = new Position(
$this->position->file + $i * ($d % 2 == 0 ? 1 : -1),
$this->position->rank + $i * ($d < 2 ? 1 : -1)
);
if ($candidate->isValid()) {
if ($captureable->has($candidate)) {
$result->add($candidate);
$directions[$d] = false;
} else if ($occupied->has($candidate)) {
$directions[$d] = false;
} else {
$result->add($candidate);
}
} else {
$directions[$d] = false;
}
}
}
}
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;
}
}

119
tests/Game/QueenTest.php Normal file
View file

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