feat: Correctly apply castles

This commit is contained in:
overflowerror 2024-01-07 13:15:13 +01:00
parent 11d9e04f07
commit 90077fdb37
2 changed files with 65 additions and 11 deletions

View file

@ -19,7 +19,15 @@ class Game {
$this->blackKing = current(array_filter($this->pieces, fn($p) => ($p instanceof King) && $p->getSide() == Side::BLACK)); $this->blackKing = current(array_filter($this->pieces, fn($p) => ($p instanceof King) && $p->getSide() == Side::BLACK));
} }
private function getPieces(Side $side): array { public function getCurrentSide(): Side {
return $this->current;
}
public function getAllPieces(): array {
return $this->pieces;
}
public function getPieces(Side $side): array {
return array_filter($this->pieces, fn($p) => $p->getSide() == $side); return array_filter($this->pieces, fn($p) => $p->getSide() == $side);
} }
@ -267,18 +275,30 @@ class Game {
public function applyInPlace(Move $move): void { public function applyInPlace(Move $move): void {
$this->tick(); $this->tick();
if ($move->captures) { if ($move->castleWith) {
$this->removePiece($move->captures); $king = $this->findPiece($move->piece);
} $rook = $this->findPiece($move->castleWith);
if ($move->promoteTo) {
$this->removePiece($move->piece);
$promoted = $move->piece->promote($move->promoteTo); // move rook first to avoid temporary variable
$promoted->move($move->target); $rook->move(new Position(
$this->pieces[] = $promoted; ($king->getPosition()->file + $move->target->file) / 2,
$rook->getPosition()->rank,
));
$king->move($move->target);
} else { } else {
$piece = $this->findPiece($move->piece); if ($move->captures) {
$piece->move($move->target); $this->removePiece($move->captures);
}
if ($move->promoteTo) {
$this->removePiece($move->piece);
$promoted = $move->piece->promote($move->promoteTo);
$promoted->move($move->target);
$this->pieces[] = $promoted;
} else {
$piece = $this->findPiece($move->piece);
$piece->move($move->target);
}
} }
$this->current = $this->current->getNext(); $this->current = $this->current->getNext();

View file

@ -448,4 +448,38 @@ final class GameTest extends TestCase {
new Rook(new Position(7, 1), Side::BLACK), new Rook(new Position(7, 1), Side::BLACK),
), $legalMoves); ), $legalMoves);
} }
public function testApply_castles() {
$subject = new Game(
[
new King(new Position(0, 7), Side::BLACK),
new King(new Position(4, 0), Side::WHITE),
new Rook(new Position(7, 0), Side::WHITE),
],
Side::WHITE
);
$subject->applyInPlace(new Move(
new King(new Position(4, 0), Side::WHITE),
new Position(6, 0),
null,
null,
new Rook(new Position(7, 0), Side::WHITE),
));
$this->assertEquals(Side::BLACK, $subject->getCurrentSide());
$pieces = $subject->getPieces(Side::WHITE);
$this->assertCount(2, $pieces);
$this->assertContainsEqualsOnce(
new King(new Position(6, 0), Side::WHITE),
$pieces
);
$this->assertContainsEqualsOnce(
new Rook(new Position(5, 0), Side::WHITE),
$pieces
);
}
} }