From 0ba0c2850f91d29d2052bbd06aabea062ee7858f Mon Sep 17 00:00:00 2001 From: Sage Vaillancourt Date: Sun, 3 Jan 2021 13:32:58 -0500 Subject: [PATCH] Clean-up and more testing --- package.json | 5 +- src/board.js | 29 +++++----- src/board.test.js | 141 +++++++++++++++++++++++++++++++++------------- 3 files changed, 122 insertions(+), 53 deletions(-) diff --git a/package.json b/package.json index 2963b91..c37ebb7 100644 --- a/package.json +++ b/package.json @@ -35,5 +35,8 @@ "last 1 safari version" ] }, - "homepage": "./" + "homepage": "./", + "devDependencies": { + "react-test-renderer": "^17.0.1" + } } diff --git a/src/board.js b/src/board.js index bf8d9dc..383b034 100644 --- a/src/board.js +++ b/src/board.js @@ -169,7 +169,9 @@ class Board extends React.Component { text = text.replace(/[\n]+/g, ''); const squares = text.substring(1); return { - hand: null, + hand: { + heldPiece: null, + }, blackIsNext: text[0].toUpperCase() === 'B', squares: squares.split('').map(c => { const type = c.toLowerCase(); @@ -236,8 +238,7 @@ class Board extends React.Component { doReset() { this.setState(this.getSetting(SHUFFLING_ENABLED) ? - this.shuffledBackRowState() : - this.originalState()); + this.shuffledBackRowState() : this.originalState()); this.setState({ showPopup: false, }); @@ -314,7 +315,7 @@ class Board extends React.Component { return 1; } }; - function addBunch(xFunc, yFunc, isUp) { + const addBunch = (xFunc, yFunc, isUp) => { for (let i = 1; i < 8; i++) { if(tryAddMove(xFunc(i), yFunc(i)) !== 0) { break; @@ -470,8 +471,8 @@ class Board extends React.Component { for(const move of moves) { // Copy the board const board = this.clone(); - board.state.squares[board.getIndex(move.x, move.y)] = board.state.squares[i]; - board.state.squares[i].isEmpty(); + const moveIndex = board.getIndex(move.x, move.y); + board.state.squares[moveIndex] = board.state.squares[i]; const check = board.inCheck(checkedKing); if (check == null || check.color !== checkedKing.color) { return false; @@ -517,19 +518,18 @@ class Board extends React.Component { const move = this.isValidMove(from, to) if (move) { if (move.passant) { - squares[this.getIndex(move.passant.x, move.passant.y)] = new Piece(EMPTY, EMPTY); + const i = this.getIndex(move.passant.x, move.passant.y); + squares[i] = new Piece(EMPTY, EMPTY); } if (move.castle) { // .castle holds the position where the rook should end up // King moved left const rookX = move.castle[0] > move.x ? 0 : 7; - console.log("Replace "); - console.log(move.castle); - console.log("With "); - console.log([rookX, move.castle[1]]); - squares[this.getIndex(move.castle[0], move.castle[1])] = - squares[this.getIndex(rookX, move.castle[1])]; - squares[this.getIndex(rookX, move.castle[1])] = new Piece(EMPTY, EMPTY); + console.log("Replace " + move.castle + " with " + [rookX, move.castle[1]]); + const rookStart = this.getIndex(rookX, move.castle[1]); + const rookLanding = this.getIndex(move.castle[0], move.castle[1]); + squares[rookLanding] = squares[rookStart]; + squares[rookStart] = new Piece(EMPTY, EMPTY); } // Remove existing passantable states squares.forEach(square => { @@ -703,4 +703,5 @@ class Board extends React.Component { } export default Board; +export {Piece}; export { BLACK, WHITE, PAWN, ROOK, KNIGHT, BISHOP, QUEEN, KING, EMPTY }; diff --git a/src/board.test.js b/src/board.test.js index cbd7c84..6e31ccf 100644 --- a/src/board.test.js +++ b/src/board.test.js @@ -1,51 +1,116 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import renderer from 'react-test-renderer'; + import Board from './board'; import * as game from './board'; +it('detects friendship and enemyship', () => { + const black = new game.Piece(game.BLACK, game.KING); + const black2 = new game.Piece(game.BLACK, game.QUEEN); + const white = new game.Piece(game.WHITE, game.KING); + const white2 = new game.Piece(game.WHITE, game.QUEEN); + const empty = new game.Piece(game.EMPTY, game.EMPTY); + const empty2 = new game.Piece(game.EMPTY, game.EMPTY); + + const truths = [ + black.isFriendOf(black2), + white.isFriendOf(white2), + + black.isEnemyOf(white), + white.isEnemyOf(black), + ]; + for (const truth of truths) { + expect(truth).toBe(true); + } + + const lies = [ + black.isFriendOf(white), black.isFriendOf(empty), + white.isFriendOf(black), white.isFriendOf(empty), + empty.isFriendOf(white), empty.isFriendOf(black), empty.isFriendOf(empty2), + + black.isEnemyOf(black2), black.isEnemyOf(empty), + white.isEnemyOf(white2), white.isEnemyOf(empty), + empty.isEnemyOf(white), empty.isEnemyOf(black), empty.isEnemyOf(empty2), + ]; + for (const lie of lies) { + expect(lie).toBe(false); + } +}); + it('is created correctly', () => { - const board = new Board(); - const rows = ['B', - 'rnbqkbnr', - 'pppppppp', - '________', - '________', - '________', - '________', - 'PPPPPPPP', - 'RNBQKBNR' - ]; - expect(board.textFromState()).toBe(rows.join('')); + const board = new Board(); + const rows = ['B', + 'rnbqkbnr', + 'pppppppp', + '________', + '________', + '________', + '________', + 'PPPPPPPP', + 'RNBQKBNR' + ]; + expect(board.textFromState()).toBe(rows.join('')); + for (const square of board.state.squares) { + expect(square.hasntMoved()).toBe(true); + } }); it('is created from text correctly', () => { - const rows = ['B', - 'pppppppp', - 'pppppppp', - '________', - '________', - '________', - '________', - 'PPPPPPPP', - 'PPPPPPPP' - ]; - const board = new Board({text: rows.join('')}); - expect(board.textFromState()).toBe(rows.join('')); + const rows = ['B', + 'pppppppp', + 'pppppppp', + '________', + '________', + '________', + '________', + 'PPPPPPPP', + 'PPPPPPPP' + ]; + const board = new Board({text: rows.join('')}); + expect(board.textFromState()).toBe(rows.join('')); }); it('detects an obvious checkmate', () => { - const rows = ['B', - 'q_______', - 'q______K', - 'q_______', - '________', - '________', - '________', - '________', - 'k_______' - ]; - const board = new Board({text: rows.join('')}); - const inCheck = board.whoInCheck(); - expect(inCheck.type).toEqual(game.KING); - expect(inCheck.color).toEqual(game.BLACK); + const rows = ['B', + 'q_______', + 'q______K', + 'q_______', + '________', + '________', + '________', + '________', + 'k_______' + ]; + const board = new Board({text: rows.join('')}); + const inCheck = board.whoInCheck(); + expect(inCheck.type).toEqual(game.KING); + expect(inCheck.color).toEqual(game.BLACK); +}); + +it('detects basic castling', () => { + const startRows = ['B', + '____k___', + '________', + '________', + '________', + '________', + '________', + 'PPPPPPPP', + 'R___K__R' + ]; + // const endRows = ['B', + // '____k___', + // '________', + // '________', + // '________', + // '________', + // '________', + // 'PPPPPPPP', + // 'R____RK_' + // ]; + let board = new Board({text: startRows.join('')}); + let move = board.isValidMove(60, 62); + expect(move.x).toBe(6); + expect(move.y).toBe(7); });