Skip to content

Commit

Permalink
Implements castling.
Browse files Browse the repository at this point in the history
  • Loading branch information
aryann committed Oct 16, 2024
1 parent d9db54c commit 6d7b9df
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 17 deletions.
29 changes: 28 additions & 1 deletion engine/src/board.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,18 @@ export class BoardState {

this.board[toIndex] = move.promoteTo.charCodeAt(0);
break;

case "castling":
this.board[toIndex] = this.board[fromIndex];

const rookFromIndex = this.toIndex(move.rook.from);
const rookToIndex = this.toIndex(move.rook.to);
this.board[rookToIndex] = this.board[rookFromIndex];

this.board[fromIndex] = 0;
this.board[rookFromIndex] = 0;

break;
}

this.board[fromIndex] = 0;
Expand Down Expand Up @@ -171,7 +183,22 @@ export class BoardState {
this.board[toIndex] = 0;
}

this.board[fromIndex] = this.pieceToInt(this.isWhiteTurn ? "P" : "p");
console.log(state.move.promoteTo, this.isWhiteTurn);
this.board[fromIndex] = this.pieceToInt(
getSide(state.move.promoteTo) === "w" ? "P" : "p"
);
break;

case "castling":
this.board[fromIndex] = this.board[toIndex];

const rookFromIndex = this.toIndex(state.move.rook.from);
const rookToIndex = this.toIndex(state.move.rook.to);
this.board[rookFromIndex] = this.board[rookToIndex];

this.board[toIndex] = 0;
this.board[rookToIndex] = 0;

break;
}

Expand Down
56 changes: 48 additions & 8 deletions engine/src/moves.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,18 @@ describe("castling", () => {
assert.sameDeepMembers(generator.generateMoves("e1"), [
{ type: "normal", from: "e1", to: "f1" },
{ type: "normal", from: "e1", to: "d1" },
{ type: "normal", from: "e1", to: "g1" },
{ type: "normal", from: "e1", to: "c1" },
{
type: "castling",
from: "e1",
to: "g1",
rook: { from: "h1", to: "f1" },
},
{
type: "castling",
from: "e1",
to: "c1",
rook: { from: "a1", to: "d1" },
},
]);
});

Expand All @@ -986,7 +996,12 @@ describe("castling", () => {
assert.sameDeepMembers(generator.generateMoves("e1"), [
{ type: "normal", from: "e1", to: "f1" },
{ type: "normal", from: "e1", to: "d1" },
{ type: "normal", from: "e1", to: "g1" },
{
type: "castling",
from: "e1",
to: "g1",
rook: { from: "h1", to: "f1" },
},
]);
});

Expand All @@ -996,7 +1011,12 @@ describe("castling", () => {
assert.sameDeepMembers(generator.generateMoves("e1"), [
{ type: "normal", from: "e1", to: "f1" },
{ type: "normal", from: "e1", to: "d1" },
{ type: "normal", from: "e1", to: "c1" },
{
type: "castling",
from: "e1",
to: "c1",
rook: { from: "a1", to: "d1" },
},
]);
});

Expand All @@ -1006,8 +1026,18 @@ describe("castling", () => {
assert.sameDeepMembers(generator.generateMoves("e8"), [
{ type: "normal", from: "e8", to: "f8" },
{ type: "normal", from: "e8", to: "d8" },
{ type: "normal", from: "e8", to: "g8" },
{ type: "normal", from: "e8", to: "c8" },
{
type: "castling",
from: "e8",
to: "g8",
rook: { from: "h8", to: "f8" },
},
{
type: "castling",
from: "e8",
to: "c8",
rook: { from: "a8", to: "d8" },
},
]);
});

Expand All @@ -1017,7 +1047,12 @@ describe("castling", () => {
assert.sameDeepMembers(generator.generateMoves("e8"), [
{ type: "normal", from: "e8", to: "f8" },
{ type: "normal", from: "e8", to: "d8" },
{ type: "normal", from: "e8", to: "g8" },
{
type: "castling",
from: "e8",
to: "g8",
rook: { from: "h8", to: "f8" },
},
]);
});

Expand All @@ -1027,7 +1062,12 @@ describe("castling", () => {
assert.sameDeepMembers(generator.generateMoves("e8"), [
{ type: "normal", from: "e8", to: "f8" },
{ type: "normal", from: "e8", to: "d8" },
{ type: "normal", from: "e8", to: "c8" },
{
type: "castling",
from: "e8",
to: "c8",
rook: { from: "a8", to: "d8" },
},
]);
});
});
20 changes: 18 additions & 2 deletions engine/src/moves.ts
Original file line number Diff line number Diff line change
Expand Up @@ -292,7 +292,15 @@ export class MoveGenerator {
const right = SQUARES[rank * NUM_FILES + file + 1];
const rightRight = SQUARES[rank * NUM_FILES + file + 2];
if (!this.board.get(right) && !this.board.get(rightRight)) {
moves.push({ type: "normal", from, to: rightRight });
moves.push({
type: "castling",
from,
to: rightRight,
rook: {
from: (from === "e1" ? "h1" : "h8") as TSquare,
to: (from === "e1" ? "f1" : "f8") as TSquare,
},
});
}
}

Expand All @@ -303,7 +311,15 @@ export class MoveGenerator {
const left = SQUARES[rank * NUM_FILES + file - 1];
const leftLeft = SQUARES[rank * NUM_FILES + file - 2];
if (!this.board.get(left) && !this.board.get(leftLeft)) {
moves.push({ type: "normal", from, to: leftLeft });
moves.push({
type: "castling",
from,
to: leftLeft,
rook: {
from: (from === "e1" ? "a1" : "a8") as TSquare,
to: (from === "e1" ? "d1" : "d8") as TSquare,
},
});
}
}

Expand Down
15 changes: 9 additions & 6 deletions engine/src/perft.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assert, describe, it } from "vitest";
import { BoardState } from "./board";
import { MoveGenerator } from "./moves";
import { getSide, SQUARES } from "./types";
import { getSide, SQUARES, TMove } from "./types";

const visit = (
states: number[],
Expand All @@ -15,17 +15,20 @@ const visit = (
return;
}

const moves: TMove[] = [];
for (const from of SQUARES) {
const piece = board.get(from);
if (!piece || getSide(piece) !== board.sideToMove()) {
continue;
}

for (const move of moveGenerator.generateMoves(from)) {
board.move(move);
visit(states, depth + 1, board, moveGenerator);
board.undo();
}
moves.push(...moveGenerator.generateMoves(from));
}

for (const move of moves) {
board.move(move);
visit(states, depth + 1, board, moveGenerator);
board.undo();
}
};

Expand Down
1 change: 1 addition & 0 deletions engine/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,4 +120,5 @@ export type TMove = {
| { type: "normal" }
| { type: "promotion"; promoteTo: TPiece }
| { type: "enPassant" }
| { type: "castling"; rook: { from: TSquare; to: TSquare } }
);

0 comments on commit 6d7b9df

Please sign in to comment.