Purpose
A rule that fits
on a small board.
Shiftora is a simple wallet-isolated sliding puzzle. Eight tiles and one empty cell occupy a 3×3 board. Only an orthogonally adjacent tile can move into the space. No operator decides an outcome or assigns a prize.
The deterministic initial board is intentionally only two moves from the target. This demonstrates exact state transitions, not difficulty, random fairness, ranking or proof of a person's skill.
Board model
Nine cells.
One compact state.
The contract stores a wallet's round (uint64), moves (uint32), packed board (uint64), empty-cell index (uint8) and active flag. Cell indices 0–8 run left to right, top to bottom; each cell occupies a four-bit nibble, with zero denoting the space.
INITIAL_BOARD is the row-major arrangement [1,2,3,4,0,6,7,5,8]. SOLVED_BOARD is [1,2,3,4,5,6,7,8,0].
A valid move
Beside the space.
Not across the board.
reset() increments the caller's round, sets moves to zero, loads the fixed initial board, places the space at cell 4 and marks the round active. Reset can replace an active or completed round; no prior progress is preserved as current state.
slide(uint8 cell,uint64 expectedRound,uint32 expectedMoves) rejects an inactive round, stale round/move count, cell above 8 and any non-neighbor, including diagonal moves and row-boundary wrap. It swaps the selected tile into the empty cell and increments moves. A solved board becomes inactive.
State & events
A confirmed move.
A checkable record.
- puzzles(account)
- The account's current round/moves/board/empty/active tuple. The default zero state is unstarted, not a valid tile permutation.
- Reset
- Emits indexed account, exact new round and initial packed board.
- Slid
- Emits indexed account, round, selected cell, resulting board, move count and solved flag.
Expected round/moves provide an atomic stale-state guard for slides. Reset has no expected-state arguments; the frontend rechecks current state before sending, but cannot reserve it while a wallet dialog is pending. Receipt matching must verify the exact predicted event, not just any successful transaction.
Events are historical. Another later transaction can change current state; a confirmed event is not a guarantee the board still matches it. There is no global leaderboard, replay indexer, account count or public community feed in this Demo.
Deployment
Ready to inspect.
Not silently live.
This project includes its own unchanged ShiftoraTiles source, pinned compiler, real ephemeral-chain business and adapter tests, and a non-broadcast deployment preview. Public network/address/explorer remain unset. Onchain reads/writes cannot be enabled by Connect Wallet.
Public deployment needs a separate explicit authorization plus controlled local CLI signer, compatible network/account/balance/gas preflight and receipt/runtime checks. Private keys never belong in a webpage. Rule changes use a new reviewed address, not a hidden proxy upgrade.
Practice has no real wallet, shared state, signature, gas or saved progress. Reload clears it. A successful local solve is not a transaction or reward entitlement.