connect4 source realm
Package connect4 is a staked Connect 4 game. A creator posts an offer with a ugnot stake; anyone (or a named opponent...
Package connect4 is a staked Connect 4 game. A creator posts an offer with a ugnot stake; anyone (or a named opponent) accepts with the same stake; the winner takes the pot minus a flat house fee.
The first mover is picked by a two-sided commit-reveal. The creator offers with sha256(passphrase), the acceptor accepts with sha256(seed). Then the creator reveals the passphrase (Reveal) and the acceptor the seed (RevealSeed), each within 90s, and the first mover is drawn from both. When a player commits, the other side's secret is still hidden, so neither can grind for an outcome, and once its secret is revealed nobody can change it; the only way out is to not reveal, which forfeits. Watching a pending Accept tells the creator nothing either, so it cannot cancel unfavourable games. Each address may use a commitment once: a reused secret is already public.
Calls signed by an account session key (Quick play) may only Play, Reveal, RevealSeed, ClaimTimeout and Cancel: a stolen session key must not resign games, move stakes or act as the owner.
Every move has a 90s clock measured in block time. Nothing on-chain fires by itself, so an expired clock is settled by anyone calling ClaimTimeout: whoever did not reveal in time forfeits, a game whose first mover never moved is void and both stakes are refunded, otherwise the player who ran out of time forfeits.
1
16
func Accept
crossing ActionAccept joins an open offer by sending exactly its stake. seedCommitment is the lowercase hex sha256 of a secret seed, revealed after the creator's passphrase. The creator then has 90s to Reveal.
func AcceptOwnership
crossing ActionAcceptOwnership completes a TransferOwnership; only the named address may call it.
func ActiveJSON
ActionActiveJSON returns {"now":<unix>,"fee":<ugnot>,"games":[...]}: the house fee for new offers, then Open and Playing games in id order, skipping offset and returning at most limit (clamped to 1-100).
func Cancel
crossing ActionCancel withdraws an open offer and refunds the creator. The creator may cancel at any time; anyone may once the offer has expired.
func ClaimTimeout
crossing ActionClaimTimeout settles a game whose move clock ran out. Anyone may call it.
func GameJSON
ActionGameJSON returns {"now":<unix>,"game":<game>|null}. It is a read-only accessor for clients querying over vm/qeval; now is the block time.
func LeadersJSON
ActionLeadersJSON returns {"wins":[...],"gnot":[...]}: the top-10 boards (most games won, most ugnot won) kept at settlement, highest first. Each entry is {"addr":<address>,"score":<int>}.
func Offer
crossing ActionOffer posts a game open for validFor minutes. The stake is the ugnot sent with the call. A non-empty opponent makes the offer private. commitment is the lowercase hex sha256 of a secret passphrase, revealed after Accept.
func Play
crossing ActionPlay drops a piece in column (1-7). move is the game's move count the player saw (Moves before this piece): a resent or delayed move that the game has moved past is refused instead of being played on a later turn.
func Render
Render serves "" (lobby and leaderboards), "new" (offer form) and "game/<id>" (one game with every action its state allows). Everything written comes from realm state or from query values that have been validated and re-formatted; raw path input is never echoed.
func Resign
crossing ActionResign concedes a game in progress.
func Reveal
crossing ActionReveal discloses the creator's passphrase. It must come within 90s of Accept; the acceptor then has 90s to RevealSeed.
func RevealSeed
crossing ActionRevealSeed discloses the acceptor's seed, which with the creator's passphrase picks the first mover. It must come within 90s of Reveal.
func SetFee
crossing ActionSetFee changes the flat house fee, in ugnot, for new offers. Games already offered keep the fee they were created with.
func TransferOwnership
crossing ActionTransferOwnership names the next owner, who becomes owner by calling AcceptOwnership. Two steps, so a mistyped or non-canonical address can never strand ownership (and the fees): only an address that signs can accept, and it is recorded as it signs.
func WithdrawFees
crossing ActionWithdrawFees sends all collected fees to to.
3
type Game
struct 1type Game struct {
2 ID int
3 Creator address
4 Opponent address // optional; if set, only this address may accept
5 Acceptor address
6 Stake int64 // ugnot, per player
7 Fee int64 // ugnot house fee, fixed at offer time
8 ExpiresAt time.Time
9 // Commitment is the lowercase hex sha256 of the creator's passphrase;
10 // SeedCommitment that of the acceptor's seed, given with Accept.
11 Commitment string
12 SeedCommitment string
13 // Passphrase is set by Reveal; the draw waits for RevealSeed.
14 Passphrase string
15 Revealed bool
16
17 Board board
18 Turn byte // 0 = awaiting the reveals, 1 = creator, 2 = acceptor
19 Moves int
20 LastCol int // column and row of the last piece dropped, valid if Moves > 0
21 LastRow int
22 LastMove time.Time
23 Status Status
24 Winner address
25}type Stats
structtype Status
ident14
- chain stdlib
- chain/banker stdlib
- chain/runtime stdlib
- chain/runtime/unsafe stdlib
- crypto/sha256 stdlib
- encoding/hex stdlib
- gno.land/p/moul/txlink/v0 package
- gno.land/p/nt/avl/v0 package
- gno.land/p/nt/ownable/v0 package
- gno.land/p/nt/svg/v0 package
- net/url stdlib
- strconv stdlib
- strings stdlib
- time stdlib