Search Apps Documentation Source Content File Folder Download Copy Actions Download 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}