mirror of
https://github.com/sigmasternchen/php-chess
synced 2025-03-15 07:58:54 +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));
|
$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();
|
||||||
|
|
|
@ -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
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue