fix: King can not castle out of check

This commit is contained in:
overflowerror 2024-01-07 12:39:42 +01:00
parent ebda02a121
commit 5c1bab71df
2 changed files with 63 additions and 6 deletions

View file

@ -45,6 +45,9 @@ class King extends Piece {
if ($this->hasMoved || $rook->hasMoved) {
return false;
}
if ($threatened->has($this->position)) {
return false;
}
$increment = $rook->position->file <=> $this->position->file;
for ($file = $this->position->file + $increment; $file != $rook->position->file; $file += $increment) {

View file

@ -121,6 +121,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertTrue($king->canCastle(
@ -142,16 +143,23 @@ final class KingTest extends TestCase {
Side::WHITE,
);
$maximumMap =
$maximumOccupiedMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(6, 0),
new Position(5, 0),
new Position(6, 0),
]))->invert());
$maximumThreatenedMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(4, 0),
new Position(5, 0),
new Position(6, 0),
]))->invert());
$this->assertTrue($king->canCastle(
$maximumMap,
$maximumMap,
$maximumMap,
$maximumOccupiedMap,
$maximumOccupiedMap,
$maximumThreatenedMap,
$rook,
));
}
@ -182,6 +190,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -217,6 +226,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -253,6 +263,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -289,6 +300,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -325,6 +337,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -361,6 +374,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -397,6 +411,7 @@ final class KingTest extends TestCase {
$maximumThreatenedMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -433,6 +448,7 @@ final class KingTest extends TestCase {
$maximumThreatenedMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -471,6 +487,7 @@ final class KingTest extends TestCase {
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
@ -486,7 +503,6 @@ final class KingTest extends TestCase {
new Position(4, 0),
Side::WHITE,
);
$king->move(new Position(4, 0));
$rook = new Rook(
new Position(0, 0),
@ -494,6 +510,44 @@ final class KingTest extends TestCase {
true,
);
$maximumOccupiedMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(1, 0),
new Position(2, 0),
new Position(3, 0),
]))->invert());
$maximumCaptureableMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(1, 0),
new Position(2, 0),
new Position(3, 0),
]))->invert());
$maximumThreatenedMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(2, 0),
new Position(3, 0),
new Position(4, 0),
]))->invert());
$this->assertFalse($king->canCastle(
$maximumOccupiedMap,
$maximumCaptureableMap,
$maximumThreatenedMap,
$rook,
));
}
public function testCanCastle_long_kingInCheck() {
$king = new King(
new Position(4, 0),
Side::WHITE,
);
$rook = new Rook(
new Position(0, 0),
Side::WHITE,
);
$maximumOccupiedMap =
FieldBitMap::full()->intersect((new FieldBitMap([
new Position(1, 0),