More clean-up and correctness. More castling work

This commit is contained in:
Sage Vaillancourt 2020-12-30 16:56:57 -05:00
parent 44c493c035
commit 4d927e1866
1 changed files with 62 additions and 53 deletions

View File

@ -28,6 +28,10 @@ const Images = [
'./black_king.svg', './black_king.svg',
]; ];
function range(n) {
return Array.from(Array(n).keys());
}
function isBlack(piece) { function isBlack(piece) {
return piece != null && piece.color === BLACK; return piece != null && piece.color === BLACK;
} }
@ -231,13 +235,13 @@ class Board extends React.Component {
} }
if (isPawn(piece)) { if (isPawn(piece)) {
let pieceIsBlack = isBlack(piece); const pieceIsBlack = isBlack(piece);
let shift = pieceIsBlack ? -1 : 1; const shift = pieceIsBlack ? -1 : 1;
let startLine = pieceIsBlack ? 6 : 1; const startLine = pieceIsBlack ? 6 : 1;
// Check for en passant // Check for en passant
let left = this.pieceAt(x - 1, y); const left = this.pieceAt(x - 1, y);
let right = this.pieceAt(x + 1, y); const right = this.pieceAt(x + 1, y);
if (left != null && left.passantable && left.color !== piece.color) { if (left != null && left.passantable && left.color !== piece.color) {
moves.push({x: x - 1, y: y + shift, passant: {x: x - 1, y}}) moves.push({x: x - 1, y: y + shift, passant: {x: x - 1, y}})
} }
@ -268,28 +272,40 @@ class Board extends React.Component {
addBunch(n => {return x + n;}, n => {return y - n;}); addBunch(n => {return x + n;}, n => {return y - n;});
addBunch(n => {return x - n;}, n => {return y - n;}); addBunch(n => {return x - n;}, n => {return y - n;});
} else if (isQueen(piece)) { } else if (isQueen(piece)) {
let [rook, bishop] = const [rook, bishop] =
[new Piece(piece.color, ROOK), new Piece(piece.color, BISHOP)]; [new Piece(piece.color, ROOK), new Piece(piece.color, BISHOP)];
moves = moves.concat(this.getValidMovesAt(rook, x, y)); moves = moves.concat(this.getValidMovesAt(rook, x, y));
moves = moves.concat(this.getValidMovesAt(bishop, x, y)); moves = moves.concat(this.getValidMovesAt(bishop, x, y));
} else if (isKnight(piece)) { } else if (isKnight(piece)) {
let deltas = [ [
[2, 1], [2, -1], [-2, 1], [-2, -1], [2, 1], [2, -1], [-2, 1], [-2, -1],
[1, 2], [1, -2], [-1, 2], [-1, -2], [1, 2], [1, -2], [-1, 2], [-1, -2],
]; ].forEach(delta => tryAddMove(x + delta[0], y + delta[1]));
deltas.forEach(delta => tryAddMove(x + delta[0], y + delta[1]));
} else if (isKing(piece)) { } else if (isKing(piece)) {
let deltas = [ [[1, 1], [1, -1], [-1, 1], [-1, -1], [0, 1], [0, -1], [1, 0], [-1, 0]]
[1, 1], [1, -1], [-1, 1], [-1, -1], [0, 1], [0, -1], [1, 0], [-1, 0] .forEach(delta => tryAddMove(x + delta[0], y + delta[1]));
]; if (piece.moves === 0) {
deltas.forEach(delta => tryAddMove(x + delta[0], y + delta[1])); const [x, y] = this.getXandY(this.findIndex(piece));
let leftRook = this.pieceAt(0, y);
if(isRook(leftRook) && leftRook.moves === 0) {
// Check if between space puts king in check
// Check if spaces between rook and king are empty
// add move(x: x - 2, y, castle: [x, y])
}
let rightRook = this.pieceAt(7, y);
if(isRook(rightRook) && rightRook.moves === 0) {
// Check if between space puts king in check
// Check if spaces between rook and king are empty
// add move(x: x + 2, y, castle: [x, y])
}
}
} }
return moves; return moves;
} }
findIndex(piece) { findIndex(piece) {
for(let i = 0; i < this.squareCount(); i++) { for(let i = 0; i < this.squareCount(); i++) {
let check = this.state.squares[i]; const check = this.state.squares[i];
if(check && check.type === piece.type && check.color === piece.color) { if(check && check.type === piece.type && check.color === piece.color) {
return i; return i;
} }
@ -298,8 +314,8 @@ class Board extends React.Component {
} }
distanceBetween(i1, i2) { distanceBetween(i1, i2) {
let [pos1X, pos1Y] = this.getXandY(i1); const [pos1X, pos1Y] = this.getXandY(i1);
let [pos2X, pos2Y] = this.getXandY(i2); const [pos2X, pos2Y] = this.getXandY(i2);
let a = pos1X - pos2X; let a = pos1X - pos2X;
a = a * a; a = a * a;
@ -311,12 +327,12 @@ class Board extends React.Component {
} }
inCheck(piece) { inCheck(piece) {
let kingPos = this.getXandY(this.findIndex(piece)); const kingPos = this.getXandY(this.findIndex(piece));
for(let i = 0; i < this.squareCount(); i++) { for(let i = 0; i < this.squareCount(); i++) {
let [x, y] = this.getXandY(i); const [x, y] = this.getXandY(i);
if(this.isEnemyOf(piece, x, y)) { if(this.isEnemyOf(piece, x, y)) {
let moves = this.getValidMoves(i); const moves = this.getValidMoves(i);
for(let j = 0; j < moves.length; j++) { for(let j = 0; j < moves.length; j++) {
if(moves[j].x === kingPos[0] && moves[j].y === kingPos[1]) { if(moves[j].x === kingPos[0] && moves[j].y === kingPos[1]) {
return piece; return piece;
@ -329,26 +345,26 @@ class Board extends React.Component {
} }
whoInCheck() { whoInCheck() {
let blackKing = this.inCheck(new Piece(BLACK, KING)); const blackKing = this.inCheck(new Piece(BLACK, KING));
return blackKing ? blackKing : this.inCheck(new Piece(WHITE, KING)); return blackKing ? blackKing : this.inCheck(new Piece(WHITE, KING));
} }
checkmate() { checkmate() {
let checkedKing = this.whoInCheck(); const checkedKing = this.whoInCheck();
if (checkedKing != null) { if (checkedKing != null) {
// For each square // For each square
for(let i = 0; i < this.squareCount(); i++) { for(let i = 0; i < this.squareCount(); i++) {
let piece = this.squareAt(i); const piece = this.squareAt(i);
// If that piece is on the checked team // If that piece is on the checked team
if (piece != null && isBlack(piece) === isBlack(checkedKing)) { if (piece != null && isBlack(piece) === isBlack(checkedKing)) {
// For each move of the above piece // For each move of the above piece
let moves = this.getValidMoves(i) const moves = this.getValidMoves(i)
for(let move of moves) { for(const move of moves) {
// Copy the board // Copy the board
let board = this.clone(); const board = this.clone();
board.state.squares[board.getIndex(move.x, move.y)] = board.state.squares[i]; board.state.squares[board.getIndex(move.x, move.y)] = board.state.squares[i];
board.state.squares[i] = null; board.state.squares[i] = null;
let check = board.inCheck(checkedKing); const check = board.inCheck(checkedKing);
if (check == null || check.color !== checkedKing.color) { if (check == null || check.color !== checkedKing.color) {
return false; return false;
} }
@ -362,16 +378,16 @@ class Board extends React.Component {
} }
getValidMoves(source) { getValidMoves(source) {
let [x, y] = this.getXandY(source); const [x, y] = this.getXandY(source);
let piece = this.squareAt(source); const piece = this.squareAt(source);
return this.getValidMovesAt(piece, x, y); return this.getValidMovesAt(piece, x, y);
} }
isValidMove(source, dest) { isValidMove(source, dest) {
let [destX, destY] = this.getXandY(dest); const [destX, destY] = this.getXandY(dest);
for (let move of this.getValidMoves(source)) { for (const move of this.getValidMoves(source)) {
if (destX === move.x && destY === move.y) { if (destX === move.x && destY === move.y) {
return move; return move;
} }
@ -390,7 +406,7 @@ class Board extends React.Component {
makeMove(from, to) { makeMove(from, to) {
const squares = this.state.squares.slice(); const squares = this.state.squares.slice();
let move = this.isValidMove(from, to) const move = this.isValidMove(from, to)
if (move) { if (move) {
if (move.passant) { if (move.passant) {
squares[this.getIndex(move.passant.x, move.passant.y)] = null; squares[this.getIndex(move.passant.x, move.passant.y)] = null;
@ -404,7 +420,7 @@ class Board extends React.Component {
if (move.passantable) { if (move.passantable) {
squares[from].passantable = true; squares[from].passantable = true;
} }
let y = this.getXandY(to)[1]; const y = this.getXandY(to)[1];
squares[to] = squares[from]; squares[to] = squares[from];
squares[from] = null; squares[from] = null;
if (squares[to].type === PAWN && (y === 0 || y === 7)) { if (squares[to].type === PAWN && (y === 0 || y === 7)) {
@ -433,7 +449,7 @@ class Board extends React.Component {
board.state.squares[i] = board.state.squares[board.heldPiece()]; board.state.squares[i] = board.state.squares[board.heldPiece()];
board.state.squares[this.heldPiece()] = null; board.state.squares[this.heldPiece()] = null;
let moversKing = this.state.blackIsNext ? const moversKing = this.state.blackIsNext ?
new Piece(BLACK, KING) : new Piece(WHITE, KING); new Piece(BLACK, KING) : new Piece(WHITE, KING);
if (board.inCheck(moversKing) != null) { if (board.inCheck(moversKing) != null) {
return; return;
@ -444,7 +460,7 @@ class Board extends React.Component {
}); });
} }
} else if (this.state.squares[i] != null) { } else if (this.state.squares[i] != null) {
let isSquareBlack = isBlack(this.state.squares[i]); const isSquareBlack = isBlack(this.state.squares[i]);
if(isSquareBlack === this.state.blackIsNext) { if(isSquareBlack === this.state.blackIsNext) {
this.setHand({ this.setHand({
heldPiece: i, heldPiece: i,
@ -454,10 +470,8 @@ class Board extends React.Component {
} }
renderSquare(i) { renderSquare(i) {
let plainBg = (i + (Math.floor(i / 8))) % 2 === 0 ? const plainBg = (i + (Math.floor(i / 8))) % 2 === 0 ? "white" : "#666";
"white" : "#666"; const bgColor = this.heldPiece() === i ? "#5D98E6" : plainBg;
let bgColor = this.heldPiece() === i ?
"#5D98E6" : plainBg;
return ( return (
<Square <Square
key={"square-" + i} key={"square-" + i}
@ -471,32 +485,27 @@ class Board extends React.Component {
row(r) { row(r) {
const i = r * 8; const i = r * 8;
return ( return (
<div className="board-row" key={"row=" + r}> { <div className="board-row" key={"row=" + r}>
[0, 1, 2, 3, 4, 5, 6, 7] {range(8).map(n => this.renderSquare(n + i))}
.map(n => this.renderSquare(n + i)) </div>
} </div>
); );
} }
render() { render() {
let checkMsg = this.whoInCheck() ? "Check! " : ""; const checkMsg = this.whoInCheck() ? "Check! " : "";
let isCheckmate = this.checkmate(); const isCheckmate = this.checkmate();
let namedPlayer = isCheckmate ? const namedPlayer = isCheckmate ?
!this.state.blackIsNext : this.state.blackIsNext !this.state.blackIsNext : this.state.blackIsNext
let color = namedPlayer ? 'Black' : 'White'; const color = namedPlayer ? 'Black' : 'White';
const status = isCheckmate ? "Checkmate! " + color + " Wins!" : const status = isCheckmate ? "Checkmate! " + color + " Wins!" :
checkMsg + color + "'s Turn"; checkMsg + color + "'s Turn";
let texttext = return (
<div style={{textAlign: `center`,}}> <div style={{textAlign: `center`,}}>
<div className="status"><h1>{status}</h1></div> <div className="status"><h1>{status}</h1></div>
{[0, 1, 2, 3, 4, 5, 6, 7] {range(8).map(n => this.row(n))}
.map(n => this.row(n))}
</div> </div>
;
return (
texttext
); );
} }
} }