refactor: migrate OnnxStrategy onto dicechess-engine-scala's JvmApi - #18
Conversation
OnnxStrategy reached into the Scala engine through surface never meant for Java: reflection in a static initializer to find the @targetName-disambiguated makeMove(Move) extension method (which compiles onto a synthetic Position$package class), an unchecked cast through Object to unwrap TurnGenerator's List[List[Move]] (Move is an opaque Int, erased on the JVM), manual Either unwrapping for FenParser.parse, and a hand-rolled moveToNotation reimplementing UCI encoding with raw bit masks. dicechess-engine-scala v1.12.0 ships JvmApi specifically to remove all of that: parseDfen (Either -> exception), activeColor, and legalTurns (each legal turn as its UCI sequence plus the resulting GameState, replacing the reflective apply loop and the encoder in one call). Existing OnnxStrategyTest cases are black-box against chooseMoves and pass unmodified -- same behavior, ~120 fewer lines, zero reflection. Closes #17
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThe Maven dependency updates to engine version ChangesOnnxStrategy JvmApi migration
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant OnnxStrategy
participant JvmApi
participant OnnxEvaluator
OnnxStrategy->>JvmApi: Parse DFEN and read active color
OnnxStrategy->>JvmApi: Request legal turns
JvmApi-->>OnnxStrategy: Return turns with final states and UCI sequences
OnnxStrategy->>OnnxEvaluator: Evaluate each final state
OnnxEvaluator-->>OnnxStrategy: Return scores
OnnxStrategy-->>OnnxStrategy: Return highest-scoring UCI sequence
Possibly related issues
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Welcome to Codecov 🎉Once you merge this PR into your default branch, you're all set! Codecov will compare coverage reports and display results in all future pull requests. Thanks for integrating Codecov - We've got you covered ☂️ |



Context
Bumps
dicechess.engine.versionto1.12.0(the release that shipsdicechess.engine.jvmapi.JvmApi, dicechess-engine-scala#558) and rewritesOnnxStrategyagainst it.OnnxStrategypreviously reached into surface never meant for Java consumption:GameState.makeMove(Move)— an@targetName-disambiguated extension method that compiles onto a syntheticPosition$packageclass, with no ordinary Java entry point.Objectto unwrapTurnGenerator.generateAllLegalTurnPaths'sList[List[Move]]—Moveis an opaqueInt, erased on the JVM, so the nested Scala collection looked likeList[List[Object]]of boxed integers from Java.Eitherunwrapping forFenParser.parse.moveToNotationreimplementing UCI encoding with raw bit masks.Changes
OnnxStrategy.chooseMovesnow:JvmApi.parseDfen(dfen)— throwsIllegalArgumentExceptionon a bad DFEN instead of anEitherto unwrap.JvmApi.activeColor(state)— a real static entry point, no reflection.JvmApi.legalTurns(state)— each legal turn as its UCI micro-move sequence and the resultingGameStatein one call, so scoring a candidate turn no longer needs a separate apply-loop or an unchecked cast.Net: ~120 fewer lines, the static initializer and its reflection are gone entirely, no more hand-rolled bit-twiddling for notation.
Verification
mise run check(Spotless + unit tests + shaded-jar package) against the real publisheddicechess-engine-scala_3:1.12.0from GitHub Packages (not a local snapshot):BUILD SUCCESS, 4/4 tests pass (OnnxStrategyTest×3,WebhookIntegrationTest×1), unmodified.OnnxStrategyTest's three cases are black-box againstchooseMoves()(empty DFEN → empty list; single pawn die → 1 micro-move; triple dice pool → ≤3 micro-moves) — passing unmodified is exactly the regression signal that the rewrite preserves behavior.Out of scope
OnnxEvaluator— unaffected, it already takesGameState/int colordirectly (opaqueColorerases toint, so no interop issue existed there to begin with).Main/Strategy— unaffected.Closes #17