diff --git a/src/Game/Knight.php b/src/Game/Knight.php new file mode 100644 index 0000000..11ea38d --- /dev/null +++ b/src/Game/Knight.php @@ -0,0 +1,33 @@ +<?php + +namespace Game; + +class Knight extends Piece { + + public function getName(): string { + return "Knight"; + } + + public function getShort(): string { + return "N"; + } + + public function getMoveCandidateMap(FieldBitMap $occupied, FieldBitMap $captureable, FieldBitMap $threatened): FieldBitMap { + $result = FieldBitMap::empty(); + + for ($i = 0; $i < 8; $i++) { + $fileOffset = ($i % 2 + 1) * ($i < 4 ? 1 : -1); + $rankOffset = (($i + 1) % 2 + 1) * (($i & 2) == 0 ? 1 : -1); + + $candidate = new Position( + $this->position->file + $fileOffset, + $this->position->rank + $rankOffset + ); + if ($candidate->isValid() && !$occupied->has($candidate)) { + $result->add($candidate); + } + } + + return $result; + } +} \ No newline at end of file diff --git a/tests/Game/KnightTest.php b/tests/Game/KnightTest.php new file mode 100644 index 0000000..42913bf --- /dev/null +++ b/tests/Game/KnightTest.php @@ -0,0 +1,93 @@ +<?php +declare(strict_types=1); + +namespace Game; + +use PHPUnit\Framework\TestCase; + +final class KnightTest extends TestCase { + + public function testMoves_unobstructed() { + $subject = new Knight(new Position( + 3, 4 + ), Side::WHITE); + + $result = $subject->getMoveCandidateMap(FieldBitMap::empty(), FieldBitMap::empty(), FieldBitMap::empty()); + + $this->assertTrue( + $result->equals(new FieldBitMap([ + new Position(4, 2), + new Position(4, 6), + new Position(2, 2), + new Position(2, 6), + new Position(5, 3), + new Position(5, 5), + new Position(1, 3), + new Position(1, 5), + ])) + ); + } + + public function testMoves_obstructed() { + $subject = new Knight(new Position( + 3, 1 + ), Side::WHITE); + + $result = $subject->getMoveCandidateMap( + new FieldBitMap([ + new Position(2, 3), + new Position(5, 2) + ]), + new FieldBitMap([ + new Position(4, 3) + ]), + FieldBitMap::empty() + ); + + $this->assertTrue( + $result->equals(new FieldBitMap([ + new Position(4, 3), + new Position(1, 2), + new Position(1, 0), + new Position(5, 0) + ])) + ); + } + + public function testCaptureable() { + $subject = new Knight( + new Position(5, 6), + Side::WHITE, + ); + + $this->assertTrue( + $subject->getCaptureableMap(true)->equals(new FieldBitMap([ + new Position(5, 6) + ])) + ); + } + + public function testCaptureMap() { + $subject = new Knight(new Position( + 5, 2 + ), Side::WHITE); + + $result = $subject->getCaptureMap( + new FieldBitMap([ + new Position(6, 4), + new Position(4, 4), + new Position(3, 1), + new Position(7, 1), + ]) + ); + + $this->assertTrue( + $result->equals(new FieldBitMap([ + new Position(3, 3), + new Position(7, 3), + new Position(6, 0), + new Position(4, 0), + ])) + ); + } +} \ No newline at end of file