fix(official-bots): use ThreadLocalRandom in PolyglotBook for native image
Build & Test (NowChessSystems) TeamCity build finished
Build & Test (NowChessSystems) TeamCity build finished
A stored java.util.Random field is reachable from BotController's static openingBook, so GraalVM baked it into the image heap and aborted the native build (Random in image heap has a cached seed). Use ThreadLocalRandom.current() at call time instead — no stored instance, nothing in the image heap, still thread-safe. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import de.nowchess.api.game.GameContext
|
|||||||
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
import de.nowchess.api.move.{Move, MoveType, PromotionPiece}
|
||||||
|
|
||||||
import java.io.{DataInputStream, FileInputStream, InputStream}
|
import java.io.{DataInputStream, FileInputStream, InputStream}
|
||||||
import java.util.Random
|
import java.util.concurrent.ThreadLocalRandom
|
||||||
import scala.collection.mutable
|
import scala.collection.mutable
|
||||||
|
|
||||||
/** Reads a Polyglot opening book (.bin file) and probes it for moves.
|
/** Reads a Polyglot opening book (.bin file) and probes it for moves.
|
||||||
@@ -18,8 +18,6 @@ import scala.collection.mutable
|
|||||||
*/
|
*/
|
||||||
final class PolyglotBook private (entries: Map[Long, Vector[BookEntry]]):
|
final class PolyglotBook private (entries: Map[Long, Vector[BookEntry]]):
|
||||||
|
|
||||||
private val rng = Random()
|
|
||||||
|
|
||||||
/** Probe the book for a move in the given position. Returns a weighted random move, or None if not in book. */
|
/** Probe the book for a move in the given position. Returns a weighted random move, or None if not in book. */
|
||||||
def probe(context: GameContext): Option[Move] =
|
def probe(context: GameContext): Option[Move] =
|
||||||
val hash = PolyglotHash.hash(context)
|
val hash = PolyglotHash.hash(context)
|
||||||
@@ -95,7 +93,7 @@ final class PolyglotBook private (entries: Map[Long, Vector[BookEntry]]):
|
|||||||
if entries.length == 1 then entries.head
|
if entries.length == 1 then entries.head
|
||||||
else
|
else
|
||||||
val totalWeight = entries.map(_.weight).sum
|
val totalWeight = entries.map(_.weight).sum
|
||||||
val pick = rng.nextInt(totalWeight.max(1)) // NOSONAR
|
val pick = ThreadLocalRandom.current().nextInt(totalWeight.max(1)) // NOSONAR
|
||||||
|
|
||||||
@scala.annotation.tailrec
|
@scala.annotation.tailrec
|
||||||
def select(remaining: Int, idx: Int): BookEntry =
|
def select(remaining: Int, idx: Int): BookEntry =
|
||||||
|
|||||||
Reference in New Issue
Block a user