-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmodel_game.go
206 lines (175 loc) · 4.97 KB
/
model_game.go
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
// With love
// 42nd Studio
// 2020-2021
package main
import (
"errors"
"fmt"
"strconv"
"strings"
"github.com/jinzhu/gorm"
)
var checkAllBoards bool
func (game *BingoGame) guardar() error {
var err error
// Check si tiene clave
if game.Password == "" {
game.Password, err = GenerateRandomString(8)
if err != nil {
logError("error generating game password", err)
}
}
// Crear o Actualizar
if game.BingoID == "" {
// Asignar UID
game.BingoID = UIDNew(21)
err = se.db.Create(&game).Error
} else {
err = se.db.Save(&game).Error
}
if err != nil {
strerr := "error guardando game object"
logError(strerr, err)
return errors.New(strerr)
}
return nil
}
func (game *BingoGame) loadFromID(bingoID string) error {
bingoID = strings.ToUpper(bingoID)
fmt.Println("loading game", bingoID)
err := se.db.Where("bingo_id = ?", bingoID).First(&game).Error
return err
}
func (game *BingoGame) loadActiveFromPass(password string) error {
err := se.db.Where("accepting_organizers = true AND password = ?", password).First(&game).Error
return err
}
func (game *BingoGame) getOrganizer(telegramID string) (BingoOrganizer, error) {
var organizer BingoOrganizer
err := se.db.Where("bingo_id = ?", game.BingoID).First(&organizer).Error
return organizer, err
}
func (game *BingoGame) getBoard(boardID string) (BingoBoard, error) {
var board BingoBoard
err := se.db.Where("bingo_id = ? AND board_id = ?", game.BingoID, boardID).First(&board).Error
return board, err
}
func (game *BingoGame) getBoardByInt(boardID int64) (BingoBoard, error) {
var board BingoBoard
err := se.db.Where("bingo_id = ? AND id = ?", game.BingoID, boardID).First(&board).Error
return board, err
}
func (game *BingoGame) loadBoards() error {
err := se.db.Where("bingo_id = ?", game.BingoID).Find(&game.boards).Error
return err
}
func (game *BingoGame) isUnique(hash string) (bool, error) {
var existingBoards []BingoBoard
println("checky", game.BingoID, hash)
err := se.db.Where("bingo_id = ? AND board_hash = ?", game.BingoID, hash).Find(&existingBoards).Error
if err != nil && !gorm.IsRecordNotFoundError(err) {
strerr := fmt.Sprintf("failed checking board uniqueness gid: %s", game.BingoID)
logError(strerr, err)
return false, errors.New(strerr)
}
if len(existingBoards) > 0 {
logError("non unique board!!!", err)
return false, nil
}
return true, nil
}
func (game *BingoGame) generateBoard() (BingoBoard, error) {
var board BingoBoard
board.BingoID = game.BingoID
board.Sold = true
if game.IdentifierType == "num" {
board.BoardID = strconv.Itoa(game.BoardsSold + 1)
}
err := board.guardar()
if err != nil {
strerr := fmt.Sprintf("failed saving board for game (%s)", game.BingoID)
logError(strerr, err)
return board, errors.New(strerr)
}
err = board.generate(game)
if err != nil {
strerr := fmt.Sprintf("failed generating board for game (%s)", game.BingoID)
logError(strerr, err)
return board, errors.New(strerr)
}
game.BoardsSold += 1
err = game.guardar()
if err != nil {
strerr := "failed saving game @game.generateBoard"
logError(strerr, err)
return board, errors.New(strerr)
}
return board, err
}
// drawBalot registra una balota sacada
// marca los tableros que lo tienen
func (game *BingoGame) drawBalot(letter, number string) (int, error) {
winners := 0
println("drawing balot game:", game.BingoID, "balot:", letter, number)
if stringInSlice(letter+number, strings.Split(game.DrawnBalots, ",")) {
strerr := fmt.Sprintf("already drawn (%s %s)", letter, number)
logError(strerr, nil)
return -42, errors.New(strerr)
}
if game.DrawnBalots != "" {
game.DrawnBalots += ","
}
game.DrawnBalots += letter + number
game.Playing = true
err := game.guardar()
if err != nil {
strerr := fmt.Sprintf("failed game.drawBalot (%s %s)", letter, number)
logError(strerr, err)
return 0, errors.New(strerr)
}
if !checkAllBoards {
return 0, nil
}
err = game.loadBoards()
if err != nil {
strerr := fmt.Sprintf("failed game.loadBoards (GID %s)", game.BingoID)
logError(strerr, err)
return 0, errors.New(strerr)
}
println("marcando tableros", len(game.boards))
for _, board := range game.boards {
won, err := board.markSlots(letter, number, game.CurrentMode)
if err != nil {
strerr := fmt.Sprintf("failed marking board (ID %s)", board.BoardID)
logError(strerr, err)
return winners, errors.New(strerr)
}
if won {
winners++
}
}
return winners, err
}
// drawBalot registra una balota sacada
// marca los tableros que lo tienen
func (game *BingoGame) clearSlots() (string, error) {
ogdrawn := game.DrawnBalots
game.DrawnBalots = ""
game.Playing = true
err := game.guardar()
if err != nil {
strerr := fmt.Sprintf("failed saving game.started %s", game.BingoID)
logError(strerr, err)
return ogdrawn, err
}
err = game.loadBoards()
if err != nil {
strerr := fmt.Sprintf("failed loading game (%s) boards", game.BingoID)
logError(strerr, err)
return ogdrawn, err
}
for _, board := range game.boards {
board.clearSlots()
}
return ogdrawn, nil
}