dicechess.engine.jvmapi

JVM-language-agnostic facade over the engine, for callers not written in Scala.

This is the JVM row's counterpart to the JS row's EngineFacade: the surface a Java or Kotlin consumer binds to instead of the Scala API, which leans on Either returns, extension methods, and opaque types that do not survive the language boundary intact. Everything outside this package is internal to such a consumer, whatever its Scala visibility says.

Key Components

  • dicechess.engine.jvmapi.JvmApi: DFEN parsing, active color, and legal-turn enumeration, exposed through java.util types and primitives only.
  • JvmApi.Turn: one legal turn as its UCI micro-moves plus the position they lead to.

The facade's Java-callability is pinned by a Java-source test (jvm/src/test/java/) — signatures can stop being reachable from Java without any Scala-side compiler error.

Attributes

Members list

Type members

Classlikes

object JvmApi

A JVM-language-agnostic facade over the engine's Scala API — the JVM-row counterpart to the JS row's EngineFacade (js/.../EngineFacade.scala). For a Java, Kotlin, or other JVM-language caller, the plain Scala API has three sharp edges this facade exists to remove:

A JVM-language-agnostic facade over the engine's Scala API — the JVM-row counterpart to the JS row's EngineFacade (js/.../EngineFacade.scala). For a Java, Kotlin, or other JVM-language caller, the plain Scala API has three sharp edges this facade exists to remove:

  • Either[String, GameState] (FenParser.parse) has no idiomatic Java consumption; parseDfen converts the Left case to an exception.
  • GameState.makeMove is an extension method: it compiles onto a synthetic $package object, not a real class, and its JVM name is disambiguated by @targetName (an implementation detail no contract promises to keep). GameState.activeColor has the opposite problem — it is an ordinary inline def member, so it is erased at the call site and leaves no bytecode at all, not even one reachable by reflection. activeColor and legalTurns wrap the ones a caller actually needs behind ordinary static methods.
  • Move is an opaque Int: erasure makes a bare List[List[Move]] look, from Java, like an unchecked List[List[Object]] of boxed integers with no safe way to read it back. legalTurns decodes each path to its java.util.List[String] of UCI tokens (and the position after playing it) so the opaque type never crosses the boundary.

'''What this deliberately does not do''': there is no applyTurn(state, List[String]) that re-parses UCI tokens back into moves. play-api's protocol treats UCI strings as opaque tokens matched by exact string equality against engine-generated legal paths, never independently decoded (see WebhookBot's Scaladoc) — a second decoder here would be a fifth place that can drift from the encoder in Move.toUci. A caller that already holds a UCI move list (e.g. from the platform's inline legalMoves) matches it against legalTurns's own uci field to get the corresponding Turn.finalState, instead of decoding the strings itself.

'''Two supported shapes of consumer'''. A ''webhook bot'' is handed a position and asked for one turn — it needs only parseDfen, activeColor and legalTurns. An ''autonomous bot'' drives the whole game itself and needs the rest of the loop: read the pending dice (dicePool), roll and set the next ones (withDice), enumerate or ask a built-in bot for a turn (legalTurns / bestTurn), hand the move over (endTurn), decide whether the game is finished (isGameOver / winner / halfMoveClock), score a position (evaluate) and serialize it back out (toDfen). Dice ''generation'' stays on the caller's side deliberately: an offline loop needs nothing more than java.util.Random, and a platform game gets its dice from the platform.

Attributes

Source
JvmApi.scala
Supertypes
class Object
trait Matchable
class Any
Self type
JvmApi.type