Skip to content

jengine-solitaire

Klondike, FreeCell and Spider with deals proved winnable, and Green Baize.

KindProject package: linked into the builds of the projects that list it
Sourcepackages/jengine-solitaire
Version0.1.0
Entry pointjengine_solitaire::SolitairePackage
Script namespaceSolitaire
Listed byprojects/arcade-classics

List it in the top-level "packages" array of project.jengine:

{
"packages": [
{ "name": "jengine-solitaire", "source": { "type": "path", "path": "../../packages/jengine-solitaire" } }
]
}

Then rebuild the editor viewport for the project (jengine viewport-build projects/<name>, or the editor’s Rebuild viewport banner). Native and web builds link it on their own.

A scene that uses its components must be a v2 scene ("version": 2): a v1 scene has no field for a package component and keeps it as inert custom data.

A script can check that the package is linked with if Solitaire == nil then return end.

Scene keyRust type
sol_tableTablepackage only: needs a v2 scene

Commands run in every runtime and return nothing; a package publishes what scripts read onto components (see the notes below). The flat name also works.

CallFlat name
Solitaire.deal(e, variant, seed)sol_deal
Solitaire.deal_winnable(e, variant, pick)sol_deal_winnable
Solitaire.resume(e, variant, seed, history, time)sol_resume
Solitaire.restart(e)sol_restart
Solitaire.undo(e)sol_undo
Solitaire.hint(e)sol_hint
Solitaire.pause(e, paused)sol_pause
Solitaire.stop(e)sol_stop
Solitaire.press(e, x, y)sol_press
Solitaire.drag(e, x, y)sol_drag
Solitaire.release(e, x, y)sol_release
  • projects/arcade-classics/assets/scenes/baize.scene

From packages/jengine-solitaire/src/lib.rs.

Patience: Klondike, FreeCell and Spider - and Green Baize, the arcade’s card table.

rules is the game as data - piles, and the two questions every move asks - and solver proves deals winnable before they ship.

This module puts a deal on the table. Every physical card is one entity for the whole deal, keyed by the card’s id, so a card that moves glides from where it was to where it now belongs rather than vanishing from one pile and appearing on another; a card turned over flips. A tap sends a card where it can best go; a drag carries a run and drops it on the pile under it. The package reads the pointer itself (the mouse, which a first finger also is) through the frame camera, and sol_press / sol_drag / sol_release feed the same path by hand.

FreeCell plays safe cards home for the player, as FreeCell always has. When nothing is left to decide - every card face up and the stock empty, or every FreeCell column in order - the cards go home by themselves. A win ends in the cascade: every card bouncing off the table.

One sol_table: atlas (the cards’ texture; regions c_<suit><rank>, back, and the slot* outlines) and winnable - seeds per variant that tests/green_baize.rs re-proves.

CallDoes
Solitaire.deal(e, variant, seed)a deal: klondike1, klondike3, freecell, spider1, spider2
Solitaire.deal_winnable(e, variant, pick)a deal from the proved list (pick is any number; it is wrapped)
Solitaire.resume(e, variant, seed, history, time)a deal with a saved history replayed onto it
Solitaire.restart(e) / Solitaire.undo(e) / Solitaire.hint(e)the same deal again; take back a move; show one
Solitaire.pause(e, paused) / Solitaire.stop(e)stop the clock and the pointer; clear the table
Solitaire.press(e, x, y) / Solitaire.drag(e, x, y) / Solitaire.release(e, x, y)a pointer, by hand

The sol_table bag: active, variant, seed, moves, time, won, finishing, can_undo, stock, redeals, history, winnable (whether this seed is on the proved list), and events: moved, home, flipped, run_done, drew, redealt, dealt, needs_columns, invalid, hint, no_hint, won, cascade_done.