mirror of
https://github.com/sigmasternchen/php-chess
synced 2025-03-14 23:58:53 +00:00
feat: Correctly apply castles
This commit is contained in:
parent
11d9e04f07
commit
90077fdb37
2 changed files with 65 additions and 11 deletions
|
@ -19,7 +19,15 @@ class Game {
|
|||
$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);
|
||||
}
|
||||
|
||||
|
@ -267,18 +275,30 @@ class Game {
|
|||
public function applyInPlace(Move $move): void {
|
||||
$this->tick();
|
||||
|
||||
if ($move->captures) {
|
||||
$this->removePiece($move->captures);
|
||||
}
|
||||
if ($move->promoteTo) {
|
||||
$this->removePiece($move->piece);
|
||||
if ($move->castleWith) {
|
||||
$king = $this->findPiece($move->piece);
|
||||
$rook = $this->findPiece($move->castleWith);
|
||||
|
||||
$promoted = $move->piece->promote($move->promoteTo);
|
||||
$promoted->move($move->target);
|
||||
$this->pieces[] = $promoted;
|
||||
// move rook first to avoid temporary variable
|
||||
$rook->move(new Position(
|
||||
($king->getPosition()->file + $move->target->file) / 2,
|
||||
$rook->getPosition()->rank,
|
||||
));
|
||||
$king->move($move->target);
|
||||
} else {
|
||||
$piece = $this->findPiece($move->piece);
|
||||
$piece->move($move->target);
|
||||
if ($move->captures) {
|
||||
$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();
|
||||
|
|
|
@ -448,4 +448,38 @@ final class GameTest extends TestCase {
|
|||
new Rook(new Position(7, 1), Side::BLACK),
|
||||
), $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
|
||||
);
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue