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.

notify.gno

2.88 Kb · 86 lines
 1package arena
 2
 3import (
 4	"chain"
 5	"strconv"
 6
 7	"gno.land/r/nym-gfanton001/gnotif/v1"
 8)
 9
10// self is the arena's package path; a deploy under another path changes it.
11var self string
12
13// pagePath is where the page lives on its origin, the start of every trigger's link; the
14// registry accepts only a link that starts with "/".
15const pagePath = "/gnomepit/"
16
17// init sets the arena's three gnotif triggers and keeps no handle, so they stay as set
18// for this deploy. A Turn or Ended event carries the address it notifies in "to", so a
19// browser opts in with its wallet's address; a Board event notifies every browser that
20// opted in.
21func init(cur realm) {
22	self = cur.PkgPath()
23	me := cur.Sub(gnotif.Subpath)
24	h := gnotif.Open(cross(me))
25	h.Set(cross(me), "turn", gnotif.Trigger{Event: "Turn", Param: "to", Title: "Your move in Gnomepit", Body: "{text}", Link: pagePath + "#match={match}"})
26	h.Set(cross(me), "ended", gnotif.Trigger{Event: "Ended", Param: "to", Title: "Match over", Body: "{text}", Link: pagePath + "#match={match}"})
27	h.Set(cross(me), "board", gnotif.Trigger{Event: "Board", Title: "Gnomepit challenges", Body: "{text}", Link: pagePath})
28}
29
30// tell emits kind to player about match id. It emits nothing when player made the call,
31// so an event never names its caller.
32func tell(kind string, player, caller address, id int, text string) {
33	if player == caller {
34		return
35	}
36	chain.Emit(kind, "to", player.String(), "match", strconv.Itoa(id), "text", text)
37}
38
39// tellBoard emits Board about match id, whose change altered the open-challenge list. It
40// names no address, so a caller cannot aim it at one player's browser.
41func tellBoard(id int, text string) {
42	chain.Emit("Board", "match", strconv.Itoa(id), "text", text)
43}
44
45// tellEnded sends Ended to each player of the finished match m, numbered id, but caller,
46// one event each, since gnotif reads only the first value of a repeated attribute.
47func tellEnded(m record, id int, caller address) {
48	tell("Ended", m.challenger, caller, id, endText(m, 0))
49	if m.acceptor != m.challenger {
50		tell("Ended", m.acceptor, caller, id, endText(m, 1))
51	}
52}
53
54// endText says how m ended to the player on side.
55func endText(m record, side int) string {
56	won := m.result == "a" && side == 0 || m.result == "b" && side == 1
57	switch m.reason {
58	case "hp":
59		last := m.hp[plansMade(m.plans[0])-1]
60		score := strconv.Itoa(last[side]) + " to " + strconv.Itoa(last[1-side]) + "."
61		switch {
62		case m.result == "draw":
63			return "Draw on HP, " + score
64		case won:
65			return "You won on HP, " + score
66		}
67		return "You lost on HP, " + score
68	case "knockout":
69		switch {
70		case m.result == "draw":
71			return "Both gnomes fell: a draw."
72		case won:
73			return "You won by knockout."
74		}
75		return "You lost by knockout."
76	case "resign":
77		if won {
78			return "Your opponent resigned. You won."
79		}
80		return "You resigned."
81	}
82	if won {
83		return "You won by forfeit."
84	}
85	return "You lost by forfeit."
86}