Skip to content

Commit

Permalink
Feature/en passant (#727)
Browse files Browse the repository at this point in the history
* Refactored the en passant logic

* Refactored enPassantSq()

* Refactored enPassantSq()

* Refactored enPassant()

* Implemented enPassantReset()

* Refactored enPassantReset() as enPassantPawn()

* Renamed enPassant as xEnPassantSq

* Renamed enPassantSq() as xEnPassantSq()

* Renamed enPassantPawn() as xEnPassantPawn()

* Documented Chess\Variant\Classical\P

* Updated Chess\Variant\AbstractPiece
  • Loading branch information
programarivm authored Jan 28, 2025
1 parent 8aeb246 commit c7de8e5
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 42 deletions.
2 changes: 1 addition & 1 deletion src/Variant/AbstractBoard.php
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ protected function lanToPseudoPgn(string $color, string $lan): string
} else {
$promo = '';
}
if ($x || $a->enPassant() === $sqs[1]) {
if ($x || $a->xEnPassantSq === $sqs[1]) {
return "{$a->file()}x{$sqs[1]}{$promo}";
} else {
return "{$sqs[1]}{$promo}";
Expand Down
34 changes: 34 additions & 0 deletions src/Variant/AbstractPiece.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Chess\Variant\RType;
use Chess\Variant\Classical\B;
use Chess\Variant\Classical\N;
use Chess\Variant\Classical\P;
use Chess\Variant\Classical\Q;
use Chess\Variant\Classical\R;
use Chess\Variant\Classical\PGN\Castle;
Expand Down Expand Up @@ -341,6 +342,7 @@ public function isKingLeftInCheck(): bool
*/
public function move(): bool
{
$this->enPassant();
$this->capture();
$this->board->detach($this->board->pieceBySq($this->sq));
$class = VariantType::getClass($this->board->variant, $this->id);
Expand All @@ -358,6 +360,22 @@ public function move(): bool
return true;
}

/**
* Set the en passant capture square.
*/
public function enPassant(): void
{
if ($this->id === Piece::P) {
if (abs($this->rank() - (int) substr($this->move['to'], 1)) === 2) {
$this->xEnPassantSq($this->move['to']);
} elseif ($pawn = $this->xEnPassantPawn()) {
$pawn->xEnPassantSq = '';
}
} elseif ($pawn = $this->xEnPassantPawn()) {
$pawn->xEnPassantSq = '';
}
}

/**
* Piece promotion.
*/
Expand Down Expand Up @@ -440,6 +458,22 @@ public function updateCastle(): AbstractPiece
return $this;
}

/**
* Returns the en passant capture pawn.
*
* @return null|\Chess\Variant\Classical\P
*/
public function xEnPassantPawn(): ?P
{
foreach ($this->board->pieces($this->oppColor()) as $piece) {
if ($piece->id === Piece::P && $piece->xEnPassantSq) {
return $piece;
}
}

return null;
}

/**
* Adds a new element to the history array.
*/
Expand Down
2 changes: 1 addition & 1 deletion src/Variant/Classical/FEN/StrToBoard.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ protected function enPassant(AbstractBoard $board): AbstractBoard
foreach ($board->pieces($this->fields[1]) as $piece) {
if ($piece->id === Piece::P) {
if (in_array($this->fields[3], $piece->xSqs)) {
$piece->enPassant = $this->fields[3];
$piece->xEnPassantSq = $this->fields[3];
}
}
}
Expand Down
66 changes: 27 additions & 39 deletions src/Variant/Classical/P.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ class P extends AbstractPiece
public array $xSqs;

/**
* En passant square.
* En passant capture square.
*
* @var string
*/
public string $enPassant = '';
public string $xEnPassantSq = '';

/**
* @param string $color
Expand Down Expand Up @@ -85,7 +85,7 @@ public function moveSqs(): array
$sqs[] = $sq;
}
}
$sqs[] = $this->enPassant();
$sqs[] = $this->xEnPassantSq;

return array_filter(array_unique($sqs));
}
Expand All @@ -107,6 +107,23 @@ public function defendedSqs(): array
return $sqs;
}

/**
* Set the en passant capture square.
*/
public function xEnPassantSq(string $sq): void
{
foreach ($this->board->pieces($this->oppColor()) as $piece) {
if ($piece->id === Piece::P) {
$rank = (int) substr($sq, 1);
$rank = $this->color === Color::W ? $rank - 1 : $rank + 1;
$xEnPassantSq = $sq[0] . $rank;
if (in_array($xEnPassantSq, $piece->xSqs)) {
$piece->xEnPassantSq = $xEnPassantSq;
}
}
}
}

/**
* Returns the start rank.
*
Expand Down Expand Up @@ -151,41 +168,6 @@ public function promoRank(Square $square): int
return 1;
}

/**
* Returns the en passant square.
*
* @return string
*/
public function enPassant(): string
{
if ($end = end($this->board->history)) {
if ($end['color'] === $this->oppColor()) {
$enPassant = explode(' ', $end['fen'])[3];
if (in_array($enPassant, $this->xSqs)) {
$this->enPassant = $enPassant;
}
}
}

return $this->enPassant;
}

/**
* Returns the en passant pawn.
*
* @return null|\Chess\Variant\AbstractPiece
*/
public function enPassantPawn(): ?AbstractPiece
{
if ($this->enPassant) {
$rank = (int) substr($this->enPassant, 1);
$this->color === Color::W ? $rank-- : $rank++;
return $this->board->pieceBySq($this->enPassant[0] . $rank);
}

return null;
}

/**
* Returns true if the pawn is promoted.
*
Expand All @@ -203,7 +185,13 @@ public function isPromoted(Square $square): bool
public function capture(): void
{
if (str_contains($this->move['case'], 'x')) {
if ($piece = $this->enPassantPawn() ?? $this->board->pieceBySq($this->move['to'])) {
if ($this->xEnPassantSq) {
$rank = (int) substr($this->xEnPassantSq, 1);
$rank = $this->color === Color::W ? $rank - 1 : $rank + 1;
if ($piece = $this->board->pieceBySq($this->xEnPassantSq[0] . $rank)) {
$this->board->detach($piece);
}
} elseif ($piece = $this->board->pieceBySq($this->move['to'])) {
$this->board->detach($piece);
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/Variant/Classical/BoardTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,7 @@ public function play_a_sequence_of_moves_w_exf6()
$this->assertTrue($board->play('b', 'f5'));
$pawn_e5 = $board->pieceBySq('e5');
$pawn_e5->moveSqs(); // this creates the en passant property
$this->assertSame('f6', $pawn_e5->enPassant);
$this->assertSame('f6', $pawn_e5->xEnPassantSq);
$this->assertTrue($board->play('w', 'exf6'));
}

Expand Down

0 comments on commit c7de8e5

Please sign in to comment.