package de.nowchess.bot

import de.nowchess.api.board.{Board, Color, CastlingRights, File, Piece, Rank, Square}
import de.nowchess.api.game.GameContext
import de.nowchess.api.move.{Move, MoveType}
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers

class ZobristHashTest extends AnyFunSuite with Matchers:

  test("hash is deterministic"):
    val hash1 = ZobristHash.hash(GameContext.initial)
    val hash2 = ZobristHash.hash(GameContext.initial)
    hash1 should equal(hash2)

  test("hash differs after a pawn move"):
    val initial = GameContext.initial
    // Move pawn from e2 to e4
    val board = initial.board.pieces
    val newBoard = board.removed(Square(File.E, Rank.R2)).updated(Square(File.E, Rank.R4), Piece.WhitePawn)
    val afterMove = initial.withBoard(Board(newBoard)).withTurn(Color.Black)
    val hash1 = ZobristHash.hash(initial)
    val hash2 = ZobristHash.hash(afterMove)
    hash1 should not equal hash2

  test("hash includes castling rights"):
    val ctx1 = GameContext.initial
    val ctx2 = ctx1.withCastlingRights(CastlingRights.None)
    val hash1 = ZobristHash.hash(ctx1)
    val hash2 = ZobristHash.hash(ctx2)
    hash1 should not equal hash2

  test("hash includes en-passant square"):
    val ctx1 = GameContext.initial
    val ctx2 = ctx1.withEnPassantSquare(Some(Square(File.E, Rank.R3)))
    val hash1 = ZobristHash.hash(ctx1)
    val hash2 = ZobristHash.hash(ctx2)
    hash1 should not equal hash2

  test("hash includes side to move"):
    val ctx1 = GameContext.initial
    val ctx2 = ctx1.withTurn(Color.Black)
    val hash1 = ZobristHash.hash(ctx1)
    val hash2 = ZobristHash.hash(ctx2)
    hash1 should not equal hash2
