Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

json.gno

3.62 Kb · 144 lines
  1package connect4
  2
  3import (
  4	"strconv"
  5	"strings"
  6	"time"
  7)
  8
  9// GameJSON returns {"now":<unix>,"game":<game>|null}. It is a read-only
 10// accessor for clients querying over vm/qeval; now is the block time.
 11func GameJSON(id int) string {
 12	var b strings.Builder
 13	writeNow(&b)
 14	b.WriteString(`,"game":`)
 15	if g := get(id); g != nil {
 16		writeGame(&b, g)
 17	} else {
 18		b.WriteString("null")
 19	}
 20	b.WriteString("}")
 21	return b.String()
 22}
 23
 24// ActiveJSON returns {"now":<unix>,"fee":<ugnot>,"games":[...]}: the house fee
 25// for new offers, then Open and Playing games in id order, skipping offset and
 26// returning at most limit (clamped to 1-100).
 27func ActiveJSON(offset, limit int) string {
 28	if offset < 0 {
 29		offset = 0
 30	}
 31	if limit < 1 {
 32		limit = 1
 33	}
 34	if limit > 100 {
 35		limit = 100
 36	}
 37	var b strings.Builder
 38	writeNow(&b)
 39	writeNum(&b, "fee", fee)
 40	b.WriteString(`,"games":[`)
 41	n := 0
 42	active.IterateByOffset(offset, limit, func(_ string, v any) bool {
 43		if n > 0 {
 44			b.WriteString(",")
 45		}
 46		writeGame(&b, v.(*Game))
 47		n++
 48		return false
 49	})
 50	b.WriteString("]}")
 51	return b.String()
 52}
 53
 54func writeNow(b *strings.Builder) {
 55	b.WriteString(`{"now":`)
 56	b.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
 57}
 58
 59// writeGame emits one game. Every stored string is validated on write
 60// (addresses by IsValid, the commitment as hex), so Quote is defence in depth.
 61func writeGame(b *strings.Builder, g *Game) {
 62	turnPlayer := ""
 63	deadline := int64(0)
 64	if g.Status == Playing {
 65		deadline = g.deadline().Unix()
 66		if g.Turn != 0 {
 67			turnPlayer = g.player(g.Turn).String()
 68		}
 69	}
 70	b.WriteString(`{"id":`)
 71	b.WriteString(strconv.Itoa(g.ID))
 72	writeStr(b, "creator", g.Creator.String())
 73	writeStr(b, "opponent", g.Opponent.String())
 74	writeStr(b, "acceptor", g.Acceptor.String())
 75	writeNum(b, "stake", g.Stake)
 76	writeNum(b, "fee", g.Fee)
 77	writeNum(b, "expiresAt", g.ExpiresAt.Unix())
 78	writeStr(b, "commitment", g.Commitment)
 79	writeStr(b, "seedCommitment", g.SeedCommitment)
 80	// revealed: the creator's passphrase is out; with turn 0 the game waits for RevealSeed.
 81	if g.Revealed {
 82		b.WriteString(`,"revealed":true`)
 83	} else {
 84		b.WriteString(`,"revealed":false`)
 85	}
 86	b.WriteString(`,"board":"`)
 87	for c := 0; c < cols; c++ {
 88		for r := 0; r < rows; r++ {
 89			b.WriteByte('0' + g.Board[c][r])
 90		}
 91	}
 92	b.WriteString(`"`)
 93	writeNum(b, "turn", int64(g.Turn))
 94	writeStr(b, "turnPlayer", turnPlayer)
 95	writeNum(b, "moves", int64(g.Moves))
 96	writeNum(b, "lastCol", int64(g.LastCol))
 97	writeNum(b, "lastRow", int64(g.LastRow))
 98	writeNum(b, "deadline", deadline)
 99	writeStr(b, "status", g.Status.String())
100	writeStr(b, "winner", g.Winner.String())
101	b.WriteString("}")
102}
103
104// writeStr and writeNum append `,"k":v`; the caller writes the first field.
105func writeStr(b *strings.Builder, k, v string) {
106	b.WriteString(`,"`)
107	b.WriteString(k)
108	b.WriteString(`":`)
109	b.WriteString(strconv.Quote(v))
110}
111
112func writeNum(b *strings.Builder, k string, v int64) {
113	b.WriteString(`,"`)
114	b.WriteString(k)
115	b.WriteString(`":`)
116	b.WriteString(strconv.FormatInt(v, 10))
117}
118
119// LeadersJSON returns {"wins":[...],"gnot":[...]}: the top-10 boards (most
120// games won, most ugnot won) kept at settlement, highest first. Each entry is
121// {"addr":<address>,"score":<int>}.
122func LeadersJSON() string {
123	var b strings.Builder
124	b.WriteString(`{"wins":`)
125	writeLeaders(&b, topWins)
126	b.WriteString(`,"gnot":`)
127	writeLeaders(&b, topGnot)
128	b.WriteString("}")
129	return b.String()
130}
131
132func writeLeaders(b *strings.Builder, board []leader) {
133	b.WriteString("[")
134	for i, l := range board {
135		if i > 0 {
136			b.WriteString(",")
137		}
138		b.WriteString(`{"addr":`)
139		b.WriteString(strconv.Quote(l.Addr.String()))
140		writeNum(b, "score", l.Score)
141		b.WriteString("}")
142	}
143	b.WriteString("]")
144}