summaryrefslogtreecommitdiffstats
path: root/game/types.go
blob: c3da541101389dbb2b5f5b0d0d9db1d3897628e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
package game

import (
	"golang.org/x/time/rate"
	"math/rand/v2"
	"net/http"
	"sync"
)

type Player struct {
	UserUUID       string
	Money          int32
	CurrentSpaceID SpaceID
	PardonCards    int32
}

type PropertyType int

type EventType int32

func (ctx *Context) EventPeek() EventType {
	return ctx.Turn.EventStack[len(ctx.Turn.EventStack)-1]
}

func (ctx *Context) EventPop() EventType {
	last := ctx.Turn.EventStack[len(ctx.Turn.EventStack)-1]
	ctx.Turn.EventStack = ctx.Turn.EventStack[:len(ctx.Turn.EventStack)-1]
	return last
}

// first, done
func QueuePop[T any](q *[]T) (T, bool) {
	if len(*q) == 0 {
		var zero T
		return zero, true
	}

	lastIdx := len(*q) - 1

	first := (*q)[lastIdx]
	*q = (*q)[:lastIdx]
	return first, false
}

type Space struct {
	PropertyType PropertyType
	SubIndexID   int32 // FK to resp. OwnableProperty types
}

type PropertyStatic struct {
	Name  string
	Price int32
}

type OwnableProperty struct {
	OwnerID PlayerID
	SpaceID SpaceID
}

type ColorGroup int32

type ColorProperty struct {
	Name    string
	Price   int32
	GroupID ColorGroup
	Houses  int32
}

type TaxSpace struct {
	Name   string
	Amount int32
}

type ChanceSpaceIDs struct {
	StCharlesPlace  SpaceID
	Go              SpaceID
	ReadingRailroad SpaceID
	Boardwalk       SpaceID
	IllinoisAvenue  SpaceID
}

type OwnedColorVisitor struct {
	VisitorID PlayerID
	OwnerID   PlayerID
	ColorID   int32
}

type OwnedRailroadVisitor struct {
	VisitorID  PlayerID
	OwnerID    PlayerID
	RailroadID int32
}

type OwnedUtilityVisitor struct {
	VisitorID PlayerID
	OwnerID   PlayerID
	UtilityID int32
	DiceRoll  int32
}

type UnownedPropertyVisitor struct {
	VisitorID  PlayerID
	PropertyID PropertyID
}

type InJailVisitor struct {
	VisitorID PlayerID
	TurnsLeft int32
}

type TaxVisitor struct {
	VisitorID PlayerID
	TaxID     int32
}

type Visitors struct { // SubIndexID is the PK for each resp table
	Unowned  []UnownedPropertyVisitor
	Color    []OwnedColorVisitor
	Railroad []OwnedRailroadVisitor
	Utility  []OwnedUtilityVisitor
	Go       []PlayerID
	Tax      []TaxVisitor
	Chance   []PlayerID
	Chest    []PlayerID
	InJail   []InJailVisitor
	// Parking  []PlayerID
	// Police   []PlayerID
}

// IDs

type PlayerID struct {
	ID int32
}

type PropertyID struct {
	ID int32
}

type SpaceID struct {
	ID int32
}

func (p *PlayerID) Index() int {
	return int(p.ID)
}

func (p *PropertyID) Index() int {
	return int(p.ID)
}

func (s *SpaceID) Index() int {
	return int(s.ID)
}

func Add(a SpaceID, b int32) SpaceID {
	return SpaceID{ID: a.ID + b}
}

// Game Context (Ctx)
type Modifiers struct {
	RailroadRentMultiplier     int32
	UtilityForceRentMultiplier bool
}

type Players struct {
	Alive   []Player // PlayerID is PK
	CanMove []PlayerID
}

type Turn struct {
	Current            PlayerID
	Ended              bool
	DiceRollsRemaining int32
	NumDiceRolled      int32
	RolledDoubles      bool
	MoveQueue          []int32
	EventStack         []EventType
	InDebt             bool
	Modifier           Modifiers
	Log                []string
}

type Properties struct {
	Owners    []OwnableProperty // PropertyID is PK
	Mortgages []PropertyID
}

type Context struct {
	Random     *rand.Rand
	Players    Players
	Turn       Turn // state reset every turn end
	Visitors   Visitors
	Properties Properties
}

type MServer struct {
	subscriberMessageBuffer int
	publishLimiter          *rate.Limiter

	logf func(f string, v ...any)

	serveMux http.ServeMux

	subscribersMu sync.Mutex
	Subscribers   map[*MSub]string

	// uuid to username
	Users map[string]*MUser

	gameCtxMu sync.Mutex
	gameCtx   *Context
	randSeed  *rand.PCG
}

type MSub struct {
	Msgs      chan []byte
	CloseSlow func()
}

type MUser struct {
	Username     string
	Subscription *MSub
}