117 lines
2.4 KiB
TypeScript
117 lines
2.4 KiB
TypeScript
import { COLOR, PIECE, FILE, RANK } from "./primitives";
|
|
import BoardWireFormat from "./boardWireFormat";
|
|
|
|
export type PieceState = {
|
|
kind: PIECE;
|
|
color: COLOR;
|
|
};
|
|
|
|
export type FileState = {
|
|
[key in RANK]?: PieceState;
|
|
};
|
|
|
|
export type BoardState = {
|
|
[key in FILE]?: FileState;
|
|
};
|
|
|
|
export type Coordinates = {
|
|
rank: RANK;
|
|
file: FILE;
|
|
};
|
|
|
|
const iconFor = ({ kind, color }: PieceState): string => {
|
|
switch (kind) {
|
|
case "pawn":
|
|
return color === "white" ? "♙" : "♟︎";
|
|
case "rook":
|
|
return color === "white" ? "♖" : "♜";
|
|
case "knight":
|
|
return color === "white" ? "♘" : "♞";
|
|
case "bishop":
|
|
return color === "white" ? "♗" : "♝";
|
|
case "queen":
|
|
return color === "white" ? "♕" : "♛";
|
|
case "king":
|
|
return color === "white" ? "♔" : "♚";
|
|
}
|
|
};
|
|
|
|
const assertFile = (maybeFile: string): FILE => {
|
|
switch (maybeFile) {
|
|
case "a":
|
|
case "b":
|
|
case "c":
|
|
case "d":
|
|
case "e":
|
|
case "f":
|
|
case "g":
|
|
case "h":
|
|
return maybeFile as FILE;
|
|
default:
|
|
throw new Error("Invalid file");
|
|
}
|
|
};
|
|
|
|
const opposite = (color: COLOR): COLOR => {
|
|
if (color === "white") {
|
|
return "black";
|
|
} else {
|
|
return "white";
|
|
}
|
|
};
|
|
|
|
const promoteCoordinates = (
|
|
state: BoardState,
|
|
color: COLOR
|
|
): Coordinates | undefined => {
|
|
const backRank: RANK = color === "white" ? 8 : 1;
|
|
|
|
const result = Object.entries(state).find((arr) => {
|
|
const elem = arr[1];
|
|
if (typeof elem === "undefined") {
|
|
return false;
|
|
}
|
|
|
|
const pieceState = elem[backRank];
|
|
|
|
if (typeof pieceState === "undefined") {
|
|
return false;
|
|
}
|
|
|
|
return pieceState.kind === "pawn" && pieceState.color === color;
|
|
});
|
|
|
|
if (typeof result === "undefined") {
|
|
return;
|
|
}
|
|
|
|
const fileId = result[0];
|
|
|
|
return {
|
|
file: assertFile(fileId),
|
|
rank: backRank,
|
|
};
|
|
};
|
|
|
|
const isPromoteAvailable = (state: BoardState, color: COLOR): boolean => {
|
|
return typeof promoteCoordinates(state, color) !== "undefined";
|
|
};
|
|
|
|
export const fromWireFormat = (boardWireFormat: BoardWireFormat): BoardState =>
|
|
boardWireFormat.reduce(
|
|
(currentState, [file, rank, kind, color]) => ({
|
|
...currentState,
|
|
[file]: {
|
|
...currentState[file],
|
|
[rank]: {
|
|
kind,
|
|
color,
|
|
},
|
|
},
|
|
}),
|
|
{} as BoardState
|
|
);
|
|
|
|
export default BoardState;
|
|
export { iconFor, isPromoteAvailable, opposite, promoteCoordinates };
|