-
Notifications
You must be signed in to change notification settings - Fork 1
/
game.lua
209 lines (200 loc) · 6.45 KB
/
game.lua
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
require('logic')
local winSound = love.audio.newSource( 'sound/win.mp3','static' )
local loseSound = love.audio.newSource( 'sound/lose.mp3','static' )
function newPlayer()
return {
-- list of dice
hand = {},
-- number of dice allowed in hand
health = 1,
-- name, makes it easier to tell players apart
name = "Unnamed Player",
-- Used for random seeding
randomSequence = {
love.math.random(10),
love.math.random(10),
love.math.random(10),
love.math.random(10),
love.math.random(10)
}
}
end
function newGame()
return {
-- list of players
players = {},
-- index of player who's current turn it is
currentPlayerIndex = 1,
-- Current Bet on the table
currentBet = {count=1,face=2},
-- index of most recent guess submitter
currentSubmitter = 0,
-- winner is nil until the game ends, then it's the index of winner
winner=nil,
-- state == {'round_start','round_over','round_mid','game_over'}
state = 'round_start',
-- iterate players
nextTurn = function(self)
self.currentPlayerIndex = self.currentPlayerIndex + 1
if self.currentPlayerIndex > #self.players then
self.currentPlayerIndex = 1
end
if self.players[self.currentPlayerIndex].health == 0 then
self:nextTurn()
end
end,
-- tests if submitted Bet is acceptable
isValidBet = function(self,newBet)
return isValidBet(self.currentBet,newBet)
end,
-- reassigns current Bet
submitBet = function(self,newBet)
newBet = convertAnonymousToBet(newBet)
if self:isValidBet(newBet) then
self.currentBet.face = newBet.face
self.currentBet.count = newBet.count
self.currentSubmitter = self.currentPlayerIndex
else
return false
end
self:changeState('round_mid')
self:nextTurn()
return true
end,
-- set up a brand new game
setup = function(self, numberOfPlayers, numberOfDicePerPlayer)
self.players = {}
self.currentPlayerIndex = 1 --love.math.random(numberOfPlayers)
self.currentBet = {count=0,face=0}
self:changeState('round_start')
for player_number=1,numberOfPlayers do
self.players[player_number] = newPlayer()
self.players[player_number].name = 'Player ' .. player_number
self.players[player_number].health = numberOfDicePerPlayer
for di_number=1,self.players[player_number].health do
self.players[player_number].hand[#self.players[player_number].hand + 1] = rollDi()
end
end
end,
-- sets up next round; also evaluates if player is last one standing
setupRound = function(self,playerGoingFirst)
if playerGoingFirst == nil then print('Need to know who is going first!') return end
self.currentPlayerIndex = playerGoingFirst
self.currentBet = {count=0,face=0}
self:changeState('round_start')
local numberOfPlayersStillIn = 0
for player_number=1,#self.players do
self.players[player_number].hand = {}
if self.players[player_number].health > 0 then
numberOfPlayersStillIn = numberOfPlayersStillIn + 1
end
for di_number=1,self.players[player_number].health do
self.players[player_number].hand[#self.players[player_number].hand + 1] = rollDi()
end
end
if numberOfPlayersStillIn == 1 then
self.winner = playerGoingFirst
self:changeState('game_over')
end
end,
-- helper function to read the current board state
printBoard = function(self)
for i=1, #self.players do
if i == self.currentPlayerIndex then
print('** ' .. self.players[i].name)
else
print(self.players[i].name)
end
local hand = ''
for x=1, self.players[i].health do
hand = hand .. self.players[i].hand[x] .. ','
end
print(hand)
end
print('current bet on the board: ' .. self.currentBet.count .. ' ' .. self.currentBet.face .. 's')
if self.currentSubmitter ~= nil then
print('bet was submitted by ' .. self.currentSubmitter)
end
end,
-- End of round; Compares current bet to the actual board state, returns
-- TRUE if the bet is accurate
-- ie: FALSE means the caller loses
evaluate = function(self)
self:changeState('round_over')
if self.currentBet.face == 0 then return nil end
local diceList = {}
diceList[1] = 0
diceList[2] = 0
diceList[3] = 0
diceList[4] = 0
diceList[5] = 0
diceList[6] = 0
for player_number = 1, #self.players do
for hand_index = 1, self.players[player_number].health do
diceList[#diceList + 1] = self.players[player_number].hand[hand_index]
end
end
local truth = evaluateBoard(diceList)
return truth[self.currentBet.face] >= self.currentBet.count
end,
-- ends round; returns winner
call = function(self)
local caller_lost = self:evaluate()
if caller_lost == nil then return end
local loser = 0
local winner = 0
if caller_lost then
loser = self.currentPlayerIndex
winner = self.currentSubmitter
else
loser = self.currentSubmitter
winner = self.currentPlayerIndex
end
self.players[loser].health = self.players[loser].health - 1
-- Consider refactoring, player 1 might not always be the client
if self.players[loser] == 1 then
loseSound:play()
else
winSound:play()
end
print(winner..','..loser)
return {winner,loser}
end,
totalDice = function(self)
local total = 0
for i = 1, #self.players do
total = total + self.players[i].health
end
return total
end,
changeState = function(self,targetState)
local allowed = false
if self.state == 'round_mid' then
if targetState == 'round_over' then
allowed = true
end
end
if targetState == 'game_over' and self.state == 'round_start' then
allowed = true
end
if targetState == 'round_start' then
if self.state == 'round_over' then
allowed = true
end
end
if targetState == 'round_mid' then
if self.state == 'round_start' then
allowed = true
end
end
if allowed then
self.state = targetState
else
if self.state ~= targetState then
print('illegal state change attempted: ' .. self.state .. ' -> '..targetState)
end
end
return allowed
end,
}
end