mirror of
https://github.com/sigmasternchen/php-chess
synced 2025-03-15 07:58:54 +00:00
feat: Add queens to game system
This commit is contained in:
parent
5b9178b11d
commit
c74f53fce4
2 changed files with 231 additions and 0 deletions
112
src/Game/Queen.php
Normal file
112
src/Game/Queen.php
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Game;
|
||||||
|
|
||||||
|
class Queen extends Piece {
|
||||||
|
|
||||||
|
public function getName(): string {
|
||||||
|
return "Queen";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getShort(): string {
|
||||||
|
return "Q";
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getMoveCandidateMap(FieldBitMap $occupied, FieldBitMap $captureable, FieldBitMap $threatened): FieldBitMap {
|
||||||
|
$result = FieldBitMap::empty();
|
||||||
|
|
||||||
|
$directions = [true, true, true, true];
|
||||||
|
for ($i = 1; $i < 8; $i++) {
|
||||||
|
for ($d = 0; $d < 4; $d++) {
|
||||||
|
if ($directions[$d]) {
|
||||||
|
$candidate = new Position(
|
||||||
|
$this->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;
|
||||||
|
}
|
||||||
|
}
|
119
tests/Game/QueenTest.php
Normal file
119
tests/Game/QueenTest.php
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Game;
|
||||||
|
|
||||||
|
use PHPUnit\Framework\TestCase;
|
||||||
|
|
||||||
|
final class QueenTest extends TestCase {
|
||||||
|
|
||||||
|
public function testMoves_unobstructed() {
|
||||||
|
$subject = new Queen(new Position(
|
||||||
|
3, 4
|
||||||
|
), Side::WHITE);
|
||||||
|
|
||||||
|
$result = $subject->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),
|
||||||
|
]))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue