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

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

json.gno

2.64 Kb · 108 lines
  1package connect4_v3
  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>,"games":[...]}: Open and Playing games in
 25// id order, skipping offset and returning at most limit (clamped to 1-100).
 26func ActiveJSON(offset, limit int) string {
 27	if offset < 0 {
 28		offset = 0
 29	}
 30	if limit < 1 {
 31		limit = 1
 32	}
 33	if limit > 100 {
 34		limit = 100
 35	}
 36	var b strings.Builder
 37	writeNow(&b)
 38	b.WriteString(`,"games":[`)
 39	n := 0
 40	active.IterateByOffset(offset, limit, func(_ string, v any) bool {
 41		if n > 0 {
 42			b.WriteString(",")
 43		}
 44		writeGame(&b, v.(*Game))
 45		n++
 46		return false
 47	})
 48	b.WriteString("]}")
 49	return b.String()
 50}
 51
 52func writeNow(b *strings.Builder) {
 53	b.WriteString(`{"now":`)
 54	b.WriteString(strconv.FormatInt(time.Now().Unix(), 10))
 55}
 56
 57// writeGame emits one game. Every stored string is validated on write
 58// (addresses by IsValid, the commitment as hex), so Quote is defence in depth.
 59func writeGame(b *strings.Builder, g *Game) {
 60	turnPlayer := ""
 61	deadline := int64(0)
 62	if g.Status == Playing {
 63		deadline = g.deadline().Unix()
 64		if g.Turn != 0 {
 65			turnPlayer = g.player(g.Turn).String()
 66		}
 67	}
 68	b.WriteString(`{"id":`)
 69	b.WriteString(strconv.Itoa(g.ID))
 70	writeStr(b, "creator", g.Creator.String())
 71	writeStr(b, "opponent", g.Opponent.String())
 72	writeStr(b, "acceptor", g.Acceptor.String())
 73	writeNum(b, "stake", g.Stake)
 74	writeNum(b, "fee", g.Fee)
 75	writeNum(b, "expiresAt", g.ExpiresAt.Unix())
 76	writeStr(b, "commitment", g.Commitment)
 77	b.WriteString(`,"board":"`)
 78	for c := 0; c < cols; c++ {
 79		for r := 0; r < rows; r++ {
 80			b.WriteByte('0' + g.Board[c][r])
 81		}
 82	}
 83	b.WriteString(`"`)
 84	writeNum(b, "turn", int64(g.Turn))
 85	writeStr(b, "turnPlayer", turnPlayer)
 86	writeNum(b, "moves", int64(g.Moves))
 87	writeNum(b, "lastCol", int64(g.LastCol))
 88	writeNum(b, "lastRow", int64(g.LastRow))
 89	writeNum(b, "deadline", deadline)
 90	writeStr(b, "status", g.Status.String())
 91	writeStr(b, "winner", g.Winner.String())
 92	b.WriteString("}")
 93}
 94
 95// writeStr and writeNum append `,"k":v`; the caller writes the first field.
 96func writeStr(b *strings.Builder, k, v string) {
 97	b.WriteString(`,"`)
 98	b.WriteString(k)
 99	b.WriteString(`":`)
100	b.WriteString(strconv.Quote(v))
101}
102
103func writeNum(b *strings.Builder, k string, v int64) {
104	b.WriteString(`,"`)
105	b.WriteString(k)
106	b.WriteString(`":`)
107	b.WriteString(strconv.FormatInt(v, 10))
108}