faf7eb38ea
Build & Test (NowChessSystems) TeamCity build finished
Repetition: alpha-beta seeded the repetition map with only the root position, so search was blind to positions already reached in the real game and would happily shuffle into draws when ahead. Reconstruct the full game-history position hashes by replaying moves and seed the search state with them; treat a twofold occurrence at non-root nodes as a draw. Contempt: draws are now scored CONTEMPT (25cp) away from zero, signed by ply parity, so the bot avoids dead-equal repetitions instead of settling. Endgame: pure NNUE lacks mating knowledge and stalls KX-vs-K conversions. Add a MopUp correction (edge-driving + king-proximity) applied only in lone-king endgames with sufficient mating material; zero elsewhere so middlegame NNUE output is untouched. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
1.5 KiB
Scala
35 lines
1.5 KiB
Scala
package de.nowchess.bot
|
|
|
|
import de.nowchess.api.board.{Board, Color, File, Piece, Rank, Square}
|
|
import de.nowchess.api.game.GameContext
|
|
import de.nowchess.bot.bots.nnue.MopUp
|
|
import org.scalatest.funsuite.AnyFunSuite
|
|
import org.scalatest.matchers.should.Matchers
|
|
|
|
class MopUpTest extends AnyFunSuite with Matchers:
|
|
|
|
private def ctx(turn: Color, pieces: (Square, Piece)*): GameContext =
|
|
GameContext.initial.withBoard(Board(pieces.toMap)).withTurn(turn)
|
|
|
|
private val wk = Square(File.E, Rank.R1) -> Piece.WhiteKing
|
|
private val wq = Square(File.D, Rank.R1) -> Piece.WhiteQueen
|
|
private val bkCorner = Square(File.H, Rank.R8) -> Piece.BlackKing
|
|
private val bkCenter = Square(File.D, Rank.R4) -> Piece.BlackKing
|
|
|
|
test("zero in a balanced middlegame-like position (both sides have material)"):
|
|
MopUp.score(ctx(Color.White, wk, wq, bkCorner, Square(File.A, Rank.R8) -> Piece.BlackQueen)) should be(0)
|
|
|
|
test("zero when winner lacks mating material (lone king vs king)"):
|
|
MopUp.score(ctx(Color.White, wk, bkCorner)) should be(0)
|
|
|
|
test("positive for the winning side to move in KQ vs K"):
|
|
MopUp.score(ctx(Color.White, wk, wq, bkCorner)) should be > 0
|
|
|
|
test("negative for the bare-king side to move in KQ vs K"):
|
|
MopUp.score(ctx(Color.Black, wk, wq, bkCorner)) should be < 0
|
|
|
|
test("cornered bare king scores higher than centralized bare king"):
|
|
val cornered = MopUp.score(ctx(Color.White, wk, wq, bkCorner))
|
|
val centralized = MopUp.score(ctx(Color.White, wk, wq, bkCenter))
|
|
cornered should be > centralized
|