chessbot/chess/board_test.go

231 lines
6.1 KiB
Go

package chess_test
import (
"fmt"
"os"
"path"
"testing"
"github.com/ekzyis/chessbot/chess"
"github.com/stretchr/testify/assert"
)
func init() {
// change working directory to the root of the project
// so assets/ can be found
wd, _ := os.Getwd()
os.Chdir(path.Dir(wd))
}
func TestBoardInitial(t *testing.T) {
b := chess.NewBoard()
assertPiece(t, b, "a1", chess.Rook, chess.Light)
assertPiece(t, b, "b1", chess.Knight, chess.Light)
assertPiece(t, b, "c1", chess.Bishop, chess.Light)
assertPiece(t, b, "d1", chess.Queen, chess.Light)
assertPiece(t, b, "e1", chess.King, chess.Light)
assertPiece(t, b, "f1", chess.Bishop, chess.Light)
assertPiece(t, b, "g1", chess.Knight, chess.Light)
assertPiece(t, b, "h1", chess.Rook, chess.Light)
assertPiece(t, b, "a2", chess.Pawn, chess.Light)
assertPiece(t, b, "b2", chess.Pawn, chess.Light)
assertPiece(t, b, "c2", chess.Pawn, chess.Light)
assertPiece(t, b, "d2", chess.Pawn, chess.Light)
assertPiece(t, b, "e2", chess.Pawn, chess.Light)
assertPiece(t, b, "f2", chess.Pawn, chess.Light)
assertPiece(t, b, "g2", chess.Pawn, chess.Light)
assertPiece(t, b, "h2", chess.Pawn, chess.Light)
assertPiece(t, b, "a8", chess.Rook, chess.Dark)
assertPiece(t, b, "b8", chess.Knight, chess.Dark)
assertPiece(t, b, "c8", chess.Bishop, chess.Dark)
assertPiece(t, b, "d8", chess.Queen, chess.Dark)
assertPiece(t, b, "e8", chess.King, chess.Dark)
assertPiece(t, b, "f8", chess.Bishop, chess.Dark)
assertPiece(t, b, "g8", chess.Knight, chess.Dark)
assertPiece(t, b, "h8", chess.Rook, chess.Dark)
assertPiece(t, b, "a7", chess.Pawn, chess.Dark)
assertPiece(t, b, "b7", chess.Pawn, chess.Dark)
assertPiece(t, b, "c7", chess.Pawn, chess.Dark)
assertPiece(t, b, "d7", chess.Pawn, chess.Dark)
assertPiece(t, b, "e7", chess.Pawn, chess.Dark)
assertPiece(t, b, "f7", chess.Pawn, chess.Dark)
assertPiece(t, b, "g7", chess.Pawn, chess.Dark)
assertPiece(t, b, "h7", chess.Pawn, chess.Dark)
}
func TestBoardMovePawn(t *testing.T) {
b := chess.NewBoard()
b.Move("e4")
assertNoPiece(t, b, "e2")
assertPiece(t, b, "e4", chess.Pawn, chess.Light)
b.Move("e5")
assertNoPiece(t, b, "e7")
assertPiece(t, b, "e5", chess.Pawn, chess.Dark)
}
func TestBoardMovePawnInvalid(t *testing.T) {
b := chess.NewBoard()
assertMoveError(t, b, "a5", "no pawn found that can move to a5")
assertMoveError(t, b, "b5", "no pawn found that can move to b5")
assertMoveError(t, b, "c5", "no pawn found that can move to c5")
assertMoveError(t, b, "d5", "no pawn found that can move to d5")
assertMoveError(t, b, "e5", "no pawn found that can move to e5")
assertMoveError(t, b, "f5", "no pawn found that can move to f5")
assertMoveError(t, b, "g5", "no pawn found that can move to g5")
assertMoveError(t, b, "h5", "no pawn found that can move to h5")
b.Move("d4")
assertMoveError(t, b, "a4", "no pawn found that can move to a4")
assertMoveError(t, b, "b4", "no pawn found that can move to b4")
assertMoveError(t, b, "c4", "no pawn found that can move to c4")
assertMoveError(t, b, "d4", "no pawn found that can move to d4")
assertMoveError(t, b, "e4", "no pawn found that can move to e4")
assertMoveError(t, b, "f4", "no pawn found that can move to f4")
assertMoveError(t, b, "g4", "no pawn found that can move to g4")
assertMoveError(t, b, "h4", "no pawn found that can move to h4")
}
func TestBoardMovePawnCapture(t *testing.T) {
b := chess.NewBoard()
b.Move("e4")
b.Move("d5")
b.Move("exd5")
assertNoPiece(t, b, "e4")
assertPiece(t, b, "d5", chess.Pawn, chess.Light)
}
func TestBoardMoveKnight(t *testing.T) {
b := chess.NewBoard()
b.Move("Nf3")
assertPiece(t, b, "f3", chess.Knight, chess.Light)
assertNoPiece(t, b, "g1")
b.Move("Nh6")
assertPiece(t, b, "h6", chess.Knight, chess.Dark)
assertNoPiece(t, b, "g8")
}
func TestBoardMoveKnightInvalid(t *testing.T) {
b := chess.NewBoard()
// out of reach
assertMoveError(t, b, "Ng3", "no knight found that can move to g3")
assertMoveError(t, b, "Nb3", "no knight found that can move to b3")
// blocked by own piece
assertMoveError(t, b, "Nd2", "d2 blocked by white pawn")
assertMoveError(t, b, "Ne2", "e2 blocked by white pawn")
b.Move("Nf3")
assertMoveError(t, b, "Ng6", "no knight found that can move to g6")
assertMoveError(t, b, "Nb6", "no knight found that can move to b6")
assertMoveError(t, b, "Ne7", "e7 blocked by black pawn")
assertMoveError(t, b, "Nd7", "d7 blocked by black pawn")
}
func TestBoardMoveBishop(t *testing.T) {
b := chess.NewBoard()
b.Move("Bc4")
assertMoveError(t, b, "Bc4", "no bishop found that can move to c4")
b.Move("e3")
b.Move("e6")
b.Move("Bc4")
assertPiece(t, b, "c4", chess.Bishop, chess.Light)
assertNoPiece(t, b, "f1")
b.Move("Bc5")
assertPiece(t, b, "c5", chess.Bishop, chess.Dark)
assertNoPiece(t, b, "f8")
}
func TestBoardMoveRook(t *testing.T) {
b := chess.NewBoard()
b.Move("Ra3")
assertMoveError(t, b, "Ra3", "no rook found that can move to a3")
b.Move("a4")
b.Move("a5")
b.Move("Ra3")
assertPiece(t, b, "a3", chess.Rook, chess.Light)
assertNoPiece(t, b, "a1")
b.Move("Ra6")
assertPiece(t, b, "a6", chess.Rook, chess.Dark)
assertNoPiece(t, b, "a8")
}
func TestBoardMoveQueen(t *testing.T) {
b := chess.NewBoard()
b.Move("Qd3")
assertMoveError(t, b, "Qd3", "no queen found that can move to d3")
b.Move("d4")
b.Move("d5")
b.Move("Qd3")
assertPiece(t, b, "d3", chess.Queen, chess.Light)
assertNoPiece(t, b, "d1")
b.Move("Qd6")
assertPiece(t, b, "d6", chess.Queen, chess.Dark)
assertNoPiece(t, b, "d8")
}
func assertPiece(t *testing.T, b *chess.Board, position string, name chess.PieceName, color chess.Color) {
p := b.At(position)
c := "white"
if color == chess.Dark {
c = "black"
}
msg := fmt.Sprintf("expected %s %s at %s", c, name, position)
if assert.NotNil(t, p, msg) {
assert.Equal(t, name, p.Name, msg)
assert.Equal(t, color, p.Color, msg)
}
}
func assertNoPiece(t *testing.T, b *chess.Board, position string) {
p := b.At(position)
assert.Nil(t, p, "expected no piece at %s", position)
}
func assertMoveError(t *testing.T, b *chess.Board, position string, message string) {
assert.ErrorContains(t, b.Move(position), message)
}