shootout.gno
3.12 Kb · 114 lines
1// Package shootout holds the state types of gno.land/r/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/shots:
2// games, challengers' sessions and their kicks.
3//
4// They live in a package rather than in the realm because gno only lets a
5// realm's own code allocate the types that realm declares, and the game's
6// rules engine runs in a separate, upgradeable implementation realm. Declared
7// here, both realms can build and read them, and like the realm's storage
8// they never change once deployed.
9package shootout
10
11import "gno.land/p/g1lnkytfqcjwllws63gvf0mv9yt04aswy4y9amhm/penalty/v0"
12
13// GameStatus is where a game is in its life.
14type GameStatus uint8
15
16const (
17 GameOpen GameStatus = iota + 1 // waiting for a challenger
18 GamePlaying // a challenger is playing a shootout
19 GameWon // a challenger won the pot; closed
20 GameCancelled // the creator withdrew it before anyone played; closed
21)
22
23func (s GameStatus) String() string {
24 switch s {
25 case GameOpen:
26 return "open"
27 case GamePlaying:
28 return "playing"
29 case GameWon:
30 return "won"
31 case GameCancelled:
32 return "cancelled"
33 }
34 return "unknown"
35}
36
37// Game is a pot and the constants it is played for.
38type Game struct {
39 ID uint64
40 Creator address
41 Config penalty.Config
42 EntryFee int64 // ugnot a challenger pays into the pot to play
43 TimeoutBlocks int64 // a challenger idle this long may be forfeited by anyone
44 Pot int64 // ugnot
45 Status GameStatus
46 Sessions int // challengers so far; while playing, the live session is number Sessions
47 Winner address
48 CreatedHeight int64
49 ClosedHeight int64
50}
51
52// SessionStatus is how a challenger's shootout stands.
53type SessionStatus uint8
54
55const (
56 SessionPlaying SessionStatus = iota + 1
57 SessionWon
58 SessionLost
59 SessionForfeited
60)
61
62func (s SessionStatus) String() string {
63 switch s {
64 case SessionPlaying:
65 return "playing"
66 case SessionWon:
67 return "won"
68 case SessionLost:
69 return "lost"
70 case SessionForfeited:
71 return "forfeited"
72 }
73 return "unknown"
74}
75
76// Kick is one kick of a shootout, with everything needed to re-run it:
77// penalty.SimulateShot(Shot, Plan, game.Config) == Result. Seed is the
78// 32 bytes that completed it, derived from the block it was played in.
79type Kick struct {
80 Round int
81 Kicker penalty.Side
82 Shot penalty.ShotParams
83 Plan penalty.KeeperPlan
84 Seed penalty.Seed
85 Result penalty.Result
86 Height int64 // block the kick was played in
87 Time int64 // its block time, unix nanoseconds (the seed's source)
88}
89
90// Session is one challenger's shootout against the chain.
91type Session struct {
92 GameID uint64
93 No int
94 Player address
95 Paid int64
96 Score penalty.Shootout
97 Kicks []Kick
98 Status SessionStatus
99 JoinHeight int64
100 LastActionHeight int64
101 EndHeight int64
102}
103
104// Next says what the session is waiting for: "shoot", "keep", or "none" once
105// it is over.
106func (s Session) Next() string {
107 if s.Status != SessionPlaying {
108 return "none"
109 }
110 if s.Score.Next() == penalty.SidePlayer {
111 return "shoot"
112 }
113 return "keep"
114}