diff --git a/package.json b/package.json index 77f978dec0bd74e954864f90ffa500dc0f8916f7..0aee7fb9577cfe8360672d91f8630cc8a222713f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "scripts": { "build": "tsc", "dev": "ts-node-dev --respawn --transpileOnly ./src/main.ts", - "serve": "tsc && node ./build/main.js" + "serve": "tsc && node ./build/main.js", + "test": "alsatian './src/test/ts/**/*.spec.ts' " }, "keywords": [], "author": "Gerson SunyƩ", diff --git a/spec/move-validation-spec.ts b/spec/move-validation-spec.ts deleted file mode 100644 index c6378a97658fa4f52e81b09d86bd56347878c941..0000000000000000000000000000000000000000 --- a/spec/move-validation-spec.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { Expect, Test } from "alsatian"; -import * as isPossible from '../src/move-validation' -import * as pieces from '../src/piece' -import { Chessboard, createEmptyChessboard, putPiece } from '../src/chessboard'; -import { Position, position } from '../src/position'; -import { Move, move } from '../src/movements'; - -let chessboard : Chessboard; - -const positionA4 : Position = position(0, 3) // A4 -const positionA5 : Position = position(0, 4) // A5 -const positionA6 : Position = position(0, 5) // A6 -const positionA7 : Position = position(0, 6) // A7 -const positionA8 : Position = position(0, 7) // A8 - -const positionB1 : Position = position(1, 0) // B1 -const positionB2 : Position = position(1, 1) // B2 -const positionB6 : Position = position(1, 5) // B6 - -const positionC3 : Position = position(2, 1) // C3 -const positionC4 : Position = position(2, 3) // C4 -const positionC5 : Position = position(2, 4) // C5 -const positionC6 : Position = position(2, 5) // C6 -const positionC7 : Position = position(2, 6) // C7 - -const positionD2 : Position = position(3, 1) // D2 -const positionD3 : Position = position(3, 2) // D3 -const positionD4 : Position = position(3, 3) // D4 -const positionD5 : Position = position(3, 4) // D5 -const positionD6 : Position = position(3, 5) // D6 -const positionE1 : Position = position(4, 0) // E1 -const positionE4 : Position = position(4, 3) // E4 -const positionE8 : Position = position(4, 7) // E8 -const positionF2 : Position = position(5, 1) // F2 -const positionF6 : Position = position(5, 5) // F6 -const positionG3 : Position = position(6, 2) // G3 -const positionG5 : Position = position(6, 4) // G5 -const positionH1 : Position = position(7, 0) // H1 -const positionH4 : Position = position(7, 3) // H4 -const positionH7 : Position = position(7, 8) // H7 - -// Horizontal moves -const moveE4_H4 : Move = move(positionE4, positionH4); -const moveE4_A4 : Move = move(positionE4, positionA4); - -// Vertical moves -const moveE4_E1 : Move = move(positionE4, positionE1); -const moveE4_E8 : Move = move(positionE4, positionE8); - -// Diagonal moves -const moveE4_A8 : Move = move(positionE4, positionA8); -const moveE4_B1 : Move = move(positionE4, positionB1); -const moveE4_H7 : Move = move(positionE4, positionH7); -const moveE4_H1 : Move = move(positionE4, positionH1); - -// Knight moves -const moveE4_F6 : Move = move(positionE4, positionF6); -const moveE4_G5 : Move = move(positionE4, positionG5); -const moveE4_F2 : Move = move(positionE4, positionF2); -const moveE4_G3 : Move = move(positionE4, positionG3); -const moveE4_D2 : Move = move(positionE4, positionD2); -const moveE4_C3 : Move = move(positionE4, positionC3); -const moveE4_C5 : Move = move(positionE4, positionC5); -const moveE4_D6 : Move = move(positionE4, positionD6); - -// Impossible moves -const moveE4_C7 : Move = move(positionE4, positionC7); -const moveE4_B2 : Move = move(positionE4, positionB2); diff --git a/spec/movements-spec.ts b/spec/movements-spec.ts deleted file mode 100644 index 0ad0cb3a24ea87a583a691fed6399a94a2908ce2..0000000000000000000000000000000000000000 --- a/spec/movements-spec.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { Expect, Test } from "alsatian"; -import {parseMoveString,Move} from "../src/movements" -import {Position, equals} from "../src/position" - diff --git a/src/chessboard.ts b/src/main/ts/chessboard.ts similarity index 100% rename from src/chessboard.ts rename to src/main/ts/chessboard.ts diff --git a/src/main.ts b/src/main/ts/main.ts similarity index 100% rename from src/main.ts rename to src/main/ts/main.ts diff --git a/src/move-validation.ts b/src/main/ts/move-validation.ts similarity index 100% rename from src/move-validation.ts rename to src/main/ts/move-validation.ts diff --git a/src/movements.ts b/src/main/ts/movements.ts similarity index 100% rename from src/movements.ts rename to src/main/ts/movements.ts diff --git a/src/piece.ts b/src/main/ts/piece.ts similarity index 100% rename from src/piece.ts rename to src/main/ts/piece.ts diff --git a/src/position.ts b/src/main/ts/position.ts similarity index 100% rename from src/position.ts rename to src/main/ts/position.ts diff --git a/src/test/ts/move-validation.spec.ts b/src/test/ts/move-validation.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..f27a7ef2bb37652ee3721b6721793097c7048ec5 --- /dev/null +++ b/src/test/ts/move-validation.spec.ts @@ -0,0 +1,145 @@ +import { Expect, Test, Setup} from "alsatian"; +import * as isPossible from '../../main/ts/move-validation' +import * as pieces from '../../main/ts/piece' +import { Chessboard, createEmptyChessboard, putPiece } from '../../main/ts/chessboard'; +import { Position, position } from '../../main/ts/position'; +import { Move, move } from '../../main/ts/movements'; + +let chessboard : Chessboard; + +const positionA4 : Position = position(0, 3) // A4 +const positionA5 : Position = position(0, 4) // A5 +const positionA6 : Position = position(0, 5) // A6 +const positionA7 : Position = position(0, 6) // A7 +const positionA8 : Position = position(0, 7) // A8 + +const positionB1 : Position = position(1, 0) // B1 +const positionB2 : Position = position(1, 1) // B2 +const positionB6 : Position = position(1, 5) // B6 + +const positionC3 : Position = position(2, 1) // C3 +const positionC4 : Position = position(2, 3) // C4 +const positionC5 : Position = position(2, 4) // C5 +const positionC6 : Position = position(2, 5) // C6 +const positionC7 : Position = position(2, 6) // C7 + +const positionD2 : Position = position(3, 1) // D2 +const positionD3 : Position = position(3, 2) // D3 +const positionD4 : Position = position(3, 3) // D4 +const positionD5 : Position = position(3, 4) // D5 +const positionD6 : Position = position(3, 5) // D6 +const positionE1 : Position = position(4, 0) // E1 +const positionE4 : Position = position(4, 3) // E4 +const positionE8 : Position = position(4, 7) // E8 +const positionF2 : Position = position(5, 1) // F2 +const positionF6 : Position = position(5, 5) // F6 +const positionG3 : Position = position(6, 2) // G3 +const positionG5 : Position = position(6, 4) // G5 +const positionH1 : Position = position(7, 0) // H1 +const positionH4 : Position = position(7, 3) // H4 +const positionH7 : Position = position(7, 8) // H7 + +// Horizontal moves +const moveE4_H4 : Move = move(positionE4, positionH4); +const moveE4_A4 : Move = move(positionE4, positionA4); + +// Vertical moves +const moveE4_E1 : Move = move(positionE4, positionE1); +const moveE4_E8 : Move = move(positionE4, positionE8); + +// Diagonal moves +const moveE4_A8 : Move = move(positionE4, positionA8); +const moveE4_B1 : Move = move(positionE4, positionB1); +const moveE4_H7 : Move = move(positionE4, positionH7); +const moveE4_H1 : Move = move(positionE4, positionH1); + +// Knight moves +const moveE4_F6 : Move = move(positionE4, positionF6); +const moveE4_G5 : Move = move(positionE4, positionG5); +const moveE4_F2 : Move = move(positionE4, positionF2); +const moveE4_G3 : Move = move(positionE4, positionG3); +const moveE4_D2 : Move = move(positionE4, positionD2); +const moveE4_C3 : Move = move(positionE4, positionC3); +const moveE4_C5 : Move = move(positionE4, positionC5); +const moveE4_D6 : Move = move(positionE4, positionD6); + +// Impossible moves +const moveE4_C7 : Move = move(positionE4, positionC7); +const moveE4_B2 : Move = move(positionE4, positionB2); + +export class TestBlackPawnMoves { + + chessboard : Chessboard + @Setup + beforeEach(){ + chessboard = createEmptyChessboard(); + } + + @Test("Pawns can move forward") + testPawnCanMoveForward() { + putPiece(chessboard, positionA7, pieces.blackPawn); + let singleForward: Move = {from: positionA7, to: positionA6, isValid: true}; + Expect(isPossible.blackPawnMove(chessboard, singleForward)).toBeTruthy(); + } + + @Test("Pawns cannot move backward") + testPawnCannotMoveBackward() { + putPiece(chessboard, positionA7, pieces.blackPawn); + let singleForward: Move = {from: positionA7, to: positionA8, isValid: true}; + Expect(isPossible.blackPawnMove(chessboard, singleForward)).not.toBeTruthy(); + } + + @Test("When in the initial position, paws can move 2 squares forward") + testPawnInitialMove() { + putPiece(chessboard, positionA7, pieces.blackPawn); + let doubleForward: Move = {from: positionA7, to: positionA5, isValid: true}; + Expect(isPossible.blackPawnMove(chessboard, doubleForward)).toBeTruthy(); + } + + @Test("When a paws has already moved, it cannot move 2 squares forward") + testCannotMoveTwoSquaresIfAlreadyMoved() { + putPiece(chessboard, positionC6, pieces.blackPawn); + let doubleForward: Move = {from: positionC6, to: positionC4, isValid: true} + Expect(isPossible.blackPawnMove(chessboard, doubleForward)).not.toBeTruthy(); + } + + @Test("When in the initial position, pawns cannot move 3 squares forward") + testCannotMoveThreeSquares() { + putPiece(chessboard, positionC6, pieces.blackPawn); + let tripleForward: Move = {from: positionA7, to: positionA4, isValid: true} + Expect(isPossible.blackPawnMove(chessboard, tripleForward)).not.toBeTruthy(); + } + + @Test("When in face of another piece, pawns cannot move foreward") + testPawnCannotMoveForwardToFullSquare() { + putPiece(chessboard, positionA6, pieces.whitePawn); + putPiece(chessboard, positionA7, pieces.blackPawn); + let singleForward: Move = {from: positionA7, to: positionA6, isValid: true} + Expect(isPossible.blackPawnMove(chessboard, singleForward)).not.toBeTruthy(); + } + + @Test("Pawns cannot capture an empty square ") + testPawnCannotCaptureEmptySquare() { + putPiece(chessboard, positionA7, pieces.blackPawn); + let diagonalCapture: Move = {from: positionA7, to: positionB6, isValid: true} + Expect(isPossible.blackPawnMove(chessboard, diagonalCapture)).not.toBeTruthy(); + } + + @Test("Pawns cannot capture pieces of the same color") + testPawnCannotCaptureSameColor() { + putPiece(chessboard, positionA7, pieces.blackPawn); + putPiece(chessboard, positionB6, pieces.blackKing); + + let diagonalCapture: Move = {from: positionA7, to: positionB6, isValid: true} + Expect(isPossible.blackPawnMove(chessboard, diagonalCapture)).not.toBeTruthy(); + } + + @Test("Pawns can capture pieces of a different color") + testPawnCanCaptureDifferentColorPieces() { + putPiece(chessboard, positionA7, pieces.blackPawn); + putPiece(chessboard, positionB6, pieces.whiteQueen); + + let diagonalCapture: Move = {from: positionA7, to: positionB6, isValid: true} + Expect(isPossible.blackPawnMove(chessboard, diagonalCapture)).toBeTruthy(); + } +} diff --git a/src/test/ts/movements.spec.ts b/src/test/ts/movements.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..8e41f143adab3ebb0ccab46b01e8058a7bd463f7 --- /dev/null +++ b/src/test/ts/movements.spec.ts @@ -0,0 +1,48 @@ +import { Expect, Test } from "alsatian"; +import {parseMoveString,Move} from "../../main/ts/movements" +import {Position, equals} from "../../main/ts/position" + +export class ParseMoveStringTest { + + @Test("A2-A4") + testParseA2_A4() { + let move: Move = parseMoveString("A2-A4"); + let expectedFrom: Position = {file: 0, rank:1} + let expectedTo: Position = {file:0, rank:3} + Expect(move.isValid).toBeTruthy(); + Expect(equals(expectedFrom, move.from!)).toBeTruthy(); + Expect(equals(expectedTo, move.to!)).toBeTruthy(); + } + + @Test("B8-B3") + testParseB8_B3() { + let move: Move = parseMoveString("B8-B3"); + let expectedFrom: Position = {file: 1, rank:7} + let expectedTo: Position = {file:1, rank:2} + Expect(move.isValid).toBeTruthy(); + Expect(equals(expectedFrom, move.from!)).toBeTruthy(); + Expect(equals(expectedTo, move.to!)).toBeTruthy(); + } + + @Test("H8-H3") + testParseH8_H3() { + let move: Move = parseMoveString("H8-H3"); + let expectedFrom: Position = {file: 7, rank:7} + let expectedTo: Position = {file:7, rank:2} + Expect(move.isValid).toBeTruthy(); + Expect(equals(expectedFrom, move.from!)).toBeTruthy(); + Expect(equals(expectedTo, move.to!)).toBeTruthy(); + } + + @Test("a1-h8 == A1-H8") + testParseLowerCase() { + let lowercaseMove: Move = parseMoveString("a1-h8"); + let uppercaseMove: Move = parseMoveString("A1-H8"); + + Expect(lowercaseMove.isValid).toBeTruthy(); + Expect(uppercaseMove.isValid).toBeTruthy(); + + Expect(equals(lowercaseMove.from!, uppercaseMove.from!)).toBeTruthy(); + Expect(equals(lowercaseMove.to!, uppercaseMove.to!)).toBeTruthy(); + } +} diff --git a/tsconfig.json b/tsconfig.json index bece16a5e19335903b1a388baa558648e419858a..859fd97ecce104f5524c9b228c2f9c0fb83684eb 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -12,5 +12,8 @@ }, "exclude": [ "node_modules" + ], + "include": [ + "src/main/ts/**/*" ] }