diff --git a/src/Game/Queen.php b/src/Game/Queen.php new file mode 100644 index 0000000..a9cdd8e --- /dev/null +++ b/src/Game/Queen.php @@ -0,0 +1,112 @@ +position->file + $i * ($d % 2 == 0 ? 1 : -1), + $this->position->rank + $i * ($d < 2 ? 1 : -1) + ); + if ($candidate->isValid()) { + if ($captureable->has($candidate)) { + $result->add($candidate); + $directions[$d] = false; + } else if ($occupied->has($candidate)) { + $directions[$d] = false; + } else { + $result->add($candidate); + } + } else { + $directions[$d] = false; + } + } + } + } + + for ($offset = 1; $offset < 8; $offset++) { + $candidate = new Position($this->position->file, $this->position->rank + $offset); + if (!$candidate->isValid()) { + break; + } + + if ($occupied->has($candidate)) { + break; + } + + $result->add($candidate); + + if ($captureable->has($candidate)) { + break; + } + } + + for ($offset = -1; $offset > -8; $offset--) { + $candidate = new Position($this->position->file, $this->position->rank + $offset); + if (!$candidate->isValid()) { + break; + } + + if ($occupied->has($candidate)) { + break; + } + + $result->add($candidate); + + if ($captureable->has($candidate)) { + break; + } + } + + for ($offset = 1; $offset < 8; $offset++) { + $candidate = new Position($this->position->file + $offset, $this->position->rank); + if (!$candidate->isValid()) { + break; + } + + if ($occupied->has($candidate)) { + break; + } + + $result->add($candidate); + + if ($captureable->has($candidate)) { + break; + } + } + + for ($offset = -1; $offset > -8; $offset--) { + $candidate = new Position($this->position->file + $offset, $this->position->rank); + if (!$candidate->isValid()) { + break; + } + + if ($occupied->has($candidate)) { + break; + } + + $result->add($candidate); + + if ($captureable->has($candidate)) { + break; + } + } + + return $result; + } +} \ No newline at end of file diff --git a/tests/Game/QueenTest.php b/tests/Game/QueenTest.php new file mode 100644 index 0000000..cad7af8 --- /dev/null +++ b/tests/Game/QueenTest.php @@ -0,0 +1,119 @@ +getMoveCandidateMap(FieldBitMap::empty(), FieldBitMap::empty(), FieldBitMap::empty()); + + $this->assertTrue( + $result->equals(new FieldBitMap([ + new Position(3, 0), + new Position(3, 1), + new Position(3, 2), + new Position(3, 3), + new Position(3, 5), + new Position(3, 6), + new Position(3, 7), + new Position(0, 4), + new Position(1, 4), + new Position(2, 4), + new Position(4, 4), + new Position(5, 4), + new Position(6, 4), + new Position(7, 4), + new Position(2, 3), + new Position(1, 2), + new Position(0, 1), + new Position(4, 5), + new Position(5, 6), + new Position(6, 7), + new Position(4, 3), + new Position(5, 2), + new Position(6, 1), + new Position(7, 0), + new Position(2, 5), + new Position(1, 6), + new Position(0, 7), + ])) + ); + } + + public function testMoves_obstructed() { + $subject = new Queen(new Position( + 3, 0 + ), Side::WHITE); + + $result = $subject->getMoveCandidateMap( + new FieldBitMap([ + new Position(3, 3), + new Position(5, 0), + new Position(2, 1), + ]), + new FieldBitMap([ + new Position(1, 0), + new Position(4, 1), + ]), + FieldBitMap::empty() + ); + + $this->assertTrue( + $result->equals(new FieldBitMap([ + new Position(3, 1), + new Position(3, 2), + new Position(1, 0), + new Position(2, 0), + new Position(4, 0), + new Position(4, 1), + ])) + ); + } + + public function testCaptureable() { + $subject = new Queen( + new Position(5, 6), + Side::WHITE, + ); + + $this->assertTrue( + $subject->getCaptureableMap(true)->equals(new FieldBitMap([ + new Position(5, 6) + ])) + ); + } + + public function testCaptureMap() { + $subject = new Queen(new Position( + 5, 2 + ), Side::WHITE); + + $result = $subject->getCaptureMap( + new FieldBitMap([ + new Position(4, 2), + new Position(6, 2), + new Position(5, 4), + new Position(4, 3), + new Position(3, 0), + new Position(6, 3), + new Position(6, 1), + ]) + ); + + $this->assertTrue( + $result->equals(new FieldBitMap([ + new Position(5, 0), + new Position(5, 1), + new Position(5, 3), + new Position(4, 1), + ])) + ); + } +} \ No newline at end of file