Some clean-up and correctness

This commit is contained in:
Sage Vaillancourt 2020-12-30 13:48:53 -05:00
parent 94db8dfb8c
commit 44c493c035
2 changed files with 76 additions and 149 deletions

View File

@ -59,15 +59,8 @@ ol, ul {
background: #ddd; background: #ddd;
} }
.game {
}
.game-board { .game-board {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.game-info {
margin-left: 20px;
}

View File

@ -126,7 +126,7 @@ class Board extends React.Component {
} }
clone() { clone() {
var board = new Board(); let board = new Board();
board.state.squares = this.state.squares.slice(); board.state.squares = this.state.squares.slice();
board.state.blackIsNext = this.state.blackIsNext; board.state.blackIsNext = this.state.blackIsNext;
board.state.hand = { board.state.hand = {
@ -136,43 +136,30 @@ class Board extends React.Component {
} }
reset() { reset() {
let whiteRow = [ let squares = [];
new Piece(WHITE, ROOK), const mainRow = [ROOK, KNIGHT, BISHOP, QUEEN, KING, BISHOP, KNIGHT, ROOK];
new Piece(WHITE, KNIGHT),
new Piece(WHITE, BISHOP),
new Piece(WHITE, QUEEN),
new Piece(WHITE, KING),
new Piece(WHITE, BISHOP),
new Piece(WHITE, KNIGHT),
new Piece(WHITE, ROOK),
];
let blackRow = [
new Piece(BLACK, ROOK),
new Piece(BLACK, KNIGHT),
new Piece(BLACK, BISHOP),
new Piece(BLACK, QUEEN),
new Piece(BLACK, KING),
new Piece(BLACK, BISHOP),
new Piece(BLACK, KNIGHT),
new Piece(BLACK, ROOK)
];
function add(num, color, type) { function add(num, color, type) {
for(var i = 0; i < num; i++) { for(let i = 0; i < num; i++) {
squares.push(new Piece(color, type)); if(color != null && type != null) {
squares.push(new Piece(color, type));
} else {
squares.push(null);
}
} }
} }
let squares = whiteRow;
mainRow.forEach(type => add(1, WHITE, type));
add(8, WHITE, PAWN); add(8, WHITE, PAWN);
squares = squares.concat(Array(32).fill(null)); add(32, null, null);
add(8, BLACK, PAWN); add(8, BLACK, PAWN);
squares = squares.concat(blackRow); mainRow.forEach(type => add(1, BLACK, type));
return squares; return squares;
} }
getXandY(i) { getXandY(i) {
let x = i % 8; const x = i % 8;
let y = Math.floor(i / 8); const y = Math.floor(i / 8);
return [x, y]; return [x, y];
} }
@ -184,9 +171,16 @@ class Board extends React.Component {
return x < 8 && x >=0 && y < 8 && y >= 0; return x < 8 && x >=0 && y < 8 && y >= 0;
} }
squareCount() {
return this.state.squares.length;
}
squareAt(i) {
return i >= 0 && i < 64 ? this.state.squares[i] : null;
}
pieceAt(x, y) { pieceAt(x, y) {
let i = this.getIndex(x, y); if (this.isValidXY(x, y)) {
if (i < 64 && this.isValidXY(x, y)) {
return this.state.squares[this.getIndex(x, y)]; return this.state.squares[this.getIndex(x, y)];
} else { } else {
return null; return null;
@ -194,7 +188,7 @@ class Board extends React.Component {
} }
whiteAt(x, y) { whiteAt(x, y) {
let square = this.pieceAt(x, y); const square = this.pieceAt(x, y);
if (square == null) { if (square == null) {
return false; return false;
} }
@ -202,7 +196,7 @@ class Board extends React.Component {
} }
blackAt(x, y) { blackAt(x, y) {
let square = this.pieceAt(x, y); const square = this.pieceAt(x, y);
if (square == null) { if (square == null) {
return false; return false;
} }
@ -210,26 +204,31 @@ class Board extends React.Component {
} }
isEnemyOf(piece, x, y) { isEnemyOf(piece, x, y) {
let pieceIsBlack = isBlack(piece); return isBlack(piece) ? this.whiteAt(x, y) : this.blackAt(x, y);
return pieceIsBlack ? this.whiteAt(x, y) : this.blackAt(x, y);
} }
getValidMovesAt(piece, x, y) { getValidMovesAt(piece, x, y) {
var i; let moves = [];
var moves = []; const tryAddMove = (x, y) => {
let tryAddMove = (x, y) => {
if (this.isValidXY(x, y)) { if (this.isValidXY(x, y)) {
if(this.pieceAt(x, y) == null) { if(this.pieceAt(x, y) == null) {
moves.push({x: x, y: y}); moves.push({x, y});
// Keep searching // Keep searching
return 0; return 0;
} else if (this.isEnemyOf(piece, x, y)) { } else if (this.isEnemyOf(piece, x, y)) {
moves.push({x: x, y: y}); moves.push({x, y});
} }
// Stop searching // Stop searching
return 1; return 1;
} }
}; };
function addBunch(xFunc, yFunc, isUp) {
for (let i = 1; i < 8; i++) {
if(tryAddMove(xFunc(i), yFunc(i)) !== 0) {
break;
}
}
}
if (isPawn(piece)) { if (isPawn(piece)) {
let pieceIsBlack = isBlack(piece); let pieceIsBlack = isBlack(piece);
@ -240,78 +239,37 @@ class Board extends React.Component {
let left = this.pieceAt(x - 1, y); let left = this.pieceAt(x - 1, y);
let right = this.pieceAt(x + 1, y); let 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: y}}) moves.push({x: x - 1, y: y + shift, passant: {x: x - 1, y}})
} }
if (right != null && right.passantable && right.color !== piece.color) { if (right != null && right.passantable && right.color !== piece.color) {
moves.push({x: x + 1, y: y + shift, passant: {x: x + 1, y: y}}) moves.push({x: x + 1, y: y + shift, passant: {x: x + 1, y}})
} }
// Pawn moving two spaces becomes en-passantable
if (this.pieceAt(x, y + shift) == null) { if (this.pieceAt(x, y + shift) == null) {
moves.push({x: x, y: y + shift}); moves.push({x, y: y + shift});
// Pawn moving two spaces becomes en-passantable
if (y === startLine && this.pieceAt(x, y + (shift * 2)) == null) { if (y === startLine && this.pieceAt(x, y + (shift * 2)) == null) {
moves.push({x: x, y: y + (shift * 2), passantable: true}); moves.push({x, y: y + (shift * 2), passantable: true});
} }
} }
[x + 1, x - 1].forEach(x => { [x + 1, x - 1].forEach(x => {
if (this.isValidXY(x, y + shift) && this.isEnemyOf(piece, x, y + shift)) { if (this.isValidXY(x, y + shift) && this.isEnemyOf(piece, x, y + shift)) {
moves.push({x: x, y: y + shift}); moves.push({x, y: y + shift});
} }
}); });
} else if (isRook(piece)) { } else if (isRook(piece)) {
// Down addBunch(n => {return x;}, n => {return y + n;});
for (i = y + 1; i < 8; i++) { addBunch(n => {return x;}, n => {return y - n;});
if (tryAddMove(x, i) !== 0) { addBunch(n => {return x + n;}, n => {return y;});
break; addBunch(n => {return x - n;}, n => {return y;});
}
}
// Up
for (i = y - 1; i >= 0; i--) {
if (tryAddMove(x, i) !== 0) {
break;
}
}
// Right
for (i = x + 1; i < 8; i++) {
if (tryAddMove(i, y) !== 0) {
break;
}
}
// Left
for (i = x - 1; i >= 0; i--) {
if (tryAddMove(i, y) !== 0) {
break;
}
}
} else if (isBishop(piece)) { } else if (isBishop(piece)) {
// Down-Right addBunch(n => {return x + n;}, n => {return y + n;});
for (i = 1; i < 8; i++) { addBunch(n => {return x - n;}, n => {return y + n;});
if (tryAddMove(x + i, y + i) !== 0) { addBunch(n => {return x + n;}, n => {return y - n;});
break; addBunch(n => {return x - n;}, n => {return y - n;});
}
}
// Up-Right
for (i = 1; i < 8; i++) {
if (tryAddMove(x + i, y - i) !== 0) {
break;
}
}
// Down-Left
for (i = 1; i < 8; i++) {
if (tryAddMove(x - i, y + i) !== 0) {
break;
}
}
// Up-Left
for (i = 1; i < 8; i++) {
if (tryAddMove(x - i, y - i) !== 0) {
break;
}
}
} else if (isQueen(piece)) { } else if (isQueen(piece)) {
let [rook, bishop] = isBlack(piece) ? let [rook, bishop] =
[new Piece(BLACK, ROOK), new Piece(BLACK, BISHOP)] : [new Piece(piece.color, ROOK), new Piece(piece.color, BISHOP)];
[new Piece(WHITE, ROOK), new Piece(WHITE, 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)) {
@ -330,7 +288,7 @@ class Board extends React.Component {
} }
findIndex(piece) { findIndex(piece) {
for(var i = 0; i < this.squareCount(); i++) { for(let i = 0; i < this.squareCount(); i++) {
let check = this.state.squares[i]; let 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;
@ -343,24 +301,23 @@ class Board extends React.Component {
let [pos1X, pos1Y] = this.getXandY(i1); let [pos1X, pos1Y] = this.getXandY(i1);
let [pos2X, pos2Y] = this.getXandY(i2); let [pos2X, pos2Y] = this.getXandY(i2);
var a = pos1X - pos2X; let a = pos1X - pos2X;
a = a * a; a = a * a;
var b = pos1Y - pos2Y; let b = pos1Y - pos2Y;
b = b * b; b = b * b;
return Math.sqrt(a + b); return Math.sqrt(a + b);
} }
inCheck(piece) { inCheck(piece) {
var i; let kingPos = this.getXandY(this.findIndex(piece));
var kingPos = this.getXandY(this.findIndex(piece));
for(i = 0; i < this.squareCount(); i++) { for(let i = 0; i < this.squareCount(); i++) {
let [x, y] = this.getXandY(i); let [x, y] = this.getXandY(i);
if(this.isEnemyOf(piece, x, y)) { if(this.isEnemyOf(piece, x, y)) {
let moves = this.getValidMoves(i); let moves = this.getValidMoves(i);
for(var 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;
} }
@ -376,27 +333,19 @@ class Board extends React.Component {
return blackKing ? blackKing : this.inCheck(new Piece(WHITE, KING)); return blackKing ? blackKing : this.inCheck(new Piece(WHITE, KING));
} }
squareCount() {
return this.state.squares.length;
}
squareAt(i) {
return i >= 0 && i < 64 ? this.state.squares[i] : null;
}
checkmate() { checkmate() {
let checkedKing = this.whoInCheck(); let checkedKing = this.whoInCheck();
if (checkedKing != null) { if (checkedKing != null) {
// For each square // For each square
for(var i = 0; i < this.squareCount(); i++) { for(let i = 0; i < this.squareCount(); i++) {
let piece = this.squareAt(i); let 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) let moves = this.getValidMoves(i)
for(var move of moves) { for(let move of moves) {
// Copy the board // Copy the board
var board = this.clone(); let 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); let check = board.inCheck(checkedKing);
@ -422,7 +371,7 @@ class Board extends React.Component {
isValidMove(source, dest) { isValidMove(source, dest) {
let [destX, destY] = this.getXandY(dest); let [destX, destY] = this.getXandY(dest);
for (var move of this.getValidMoves(source)) { for (let move of this.getValidMoves(source)) {
if (destX === move.x && destY === move.y) { if (destX === move.x && destY === move.y) {
return move; return move;
} }
@ -480,7 +429,7 @@ class Board extends React.Component {
} }
if (this.isHoldingPiece()) { if (this.isHoldingPiece()) {
// Copy the board // Copy the board
var board = this.clone(); let board = this.clone();
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;
@ -511,6 +460,7 @@ class Board extends React.Component {
"#5D98E6" : plainBg; "#5D98E6" : plainBg;
return ( return (
<Square <Square
key={"square-" + i}
piece={this.state.squares[i]} piece={this.state.squares[i]}
onClick={() => this.handleClick(i)} onClick={() => this.handleClick(i)}
bgColor={bgColor} bgColor={bgColor}
@ -518,42 +468,30 @@ class Board extends React.Component {
); );
} }
row(row) { row(r) {
let i = row * 8; const i = r * 8;
return ( return (
<div className="board-row"> <div className="board-row" key={"row=" + r}> {
{this.renderSquare(i)} [0, 1, 2, 3, 4, 5, 6, 7]
{this.renderSquare(i + 1)} .map(n => this.renderSquare(n + i))
{this.renderSquare(i + 2)} } </div>
{this.renderSquare(i + 3)}
{this.renderSquare(i + 4)}
{this.renderSquare(i + 5)}
{this.renderSquare(i + 6)}
{this.renderSquare(i + 7)}
</div>
); );
} }
render() { render() {
let checkMsg = this.whoInCheck() ? "Check! " : ""; let checkMsg = this.whoInCheck() ? "Check! " : "";
let isCheckmate = this.checkmate(); let isCheckmate = this.checkmate();
var namedPlayer = isCheckmate ? let namedPlayer = isCheckmate ?
!this.state.blackIsNext : this.state.blackIsNext !this.state.blackIsNext : this.state.blackIsNext
let color = namedPlayer ? 'Black' : 'White'; let color = namedPlayer ? 'Black' : 'White';
const status = isCheckmate ? "Checkmate! " + color + " Wins!" : const status = isCheckmate ? "Checkmate! " + color + " Wins!" :
checkMsg + color + "'s Turn"; checkMsg + color + "'s Turn";
var texttext = let texttext =
<div style={{textAlign: `center`,}}> <div style={{textAlign: `center`,}}>
<div className="status"><h1>{status}</h1></div> <div className="status"><h1>{status}</h1></div>
{this.row(0)} {[0, 1, 2, 3, 4, 5, 6, 7]
{this.row(1)} .map(n => this.row(n))}
{this.row(2)}
{this.row(3)}
{this.row(4)}
{this.row(5)}
{this.row(6)}
{this.row(7)}
</div> </div>
; ;
@ -567,10 +505,6 @@ class Game extends React.Component {
render() { render() {
return ( return (
<div className="game"> <div className="game">
<div className="game-info">
<div>{/* status */}</div>
<ol>{/* TODO */}</ol>
</div>
<div className="game-board"> <div className="game-board">
<Board /> <Board />
</div> </div>