More clean-up and correctness. More castling work
This commit is contained in:
parent
44c493c035
commit
4d927e1866
115
src/index.js
115
src/index.js
|
@ -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
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue