b72e8ec017
Prerequisite for parallel search. NNUE held all state on one instance: the immutable transposed L1 weight matrix alongside the mutable accumulator stack, scratch buffers and eval cache. That made concurrent eval calls corrupt shared buffers. Extract the read-only parameters into NNUEWeights (heavy to build, safe to share). NNUE now owns only per-instance mutable buffers and references the shared weights, so many evaluators can run in parallel over one weight matrix without duplicating it. Single-instance behaviour is unchanged — EvaluationNNUE still uses one evaluator, so play is identical. Also applies scalafmt alignment to the MopUp files. 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
|