Changeset 16
- Timestamp:
- 02/04/08 05:22:53 (4 years ago)
- Files:
-
- 1 modified
-
holdemtable.py (modified) (13 diffs)
Legend:
- Unmodified
- Added
- Removed
-
holdemtable.py
r15 r16 9 9 pass 10 10 11 class player :11 class player(object): 12 12 starting_money = 1000.0 13 14 13 15 def __init__(self, id, user_id, seat): 14 self.seat = seat 15 self.id = id 16 self.user_id = user_id 17 self.money = self.starting_money 18 self.cards = [] 16 self.__seat = seat 17 self.__id = id 18 self.__user_id = user_id 19 self.__money = self.starting_money 20 self.__in_hand = True 21 self.__cards = [] 19 22 self.__money_in_pot = None #money in pot before previous round 20 23 self.__action_history = [] 21 24 self.__has_acted = False 22 25 self.__has_folded =False 23 self. status = "need implementing"26 self.__status = "need implementing" 24 27 25 28 def nextHand(self): 26 self.__in_hand = True27 29 self.__money_in_pot = 0.0 28 30 self.__has_folded = False 29 self. cards = []31 self.__cards = [] 30 32 self.__action_history = [] 31 33 32 def moneyInPot(self): 33 return __money_in_pot 34 35 def moneyInPhase(self): 36 return sum([ b for a,b in self.__action_history if b != None]) 34 37 35 38 36 def nextPhase(self): 39 37 self.__action_history = [] 40 self.__money_in_pot += self.money InPhase()38 self.__money_in_pot += self.money_in_phase 41 39 self.__has_acted = False 42 43 44 def publicData(self): 40 self.__in_hand = not self.__has_folded 41 42 43 def __publicData(self): 45 44 return {"owner" : self.user_id, 46 45 "status": self.status, 47 46 "money" : self.money, 48 47 "seat" : self.seat} 49 def privateData(self): 48 49 def __privateData(self): 50 50 dat = {"user_id" : self.user_id, 51 51 "id" : self.id, … … 53 53 return dat 54 54 55 def actionHistory(self):56 return self.__action_history57 58 55 def dealCard(self, card): 59 56 self.cards.append(card) 57 60 58 #returns money added to pot if any 61 59 def doAction(self, action, value): 62 print value63 print self.money64 60 if value != None and value > self.money: 65 61 raise InsufficientFundsException("Insufficient Funds") 66 62 else: 67 if value != None: self. money -= value63 if value != None: self.__money -= value 68 64 if not self.__has_acted and action != "small_blinds" and action != "large_blinds": 69 65 self.__has_acted = True … … 71 67 self.__action_history.append((action,value)) 72 68 73 def hasFolded(self): 74 return self.__has_folded 75 def inHand(self): 76 #TODO need to change this 77 return self.__in_hand 78 79 def hasActed(self): 80 return self.__has_acted 69 #lets make a bunch of getters 70 id = property( lambda self: self.__id ) 71 cards = property( lambda self: self.__cards ) 72 money_in_pot = property( lambda self: self.__money_in_pot ) 73 action_history = property( lambda self: self.__action_history ) 74 has_folded = property( lambda self: self.__has_folded ) 75 has_acted = property( lambda self: self.__has_acted ) 76 status = property( lambda self: self.__status ) 77 user_id = property( lambda self: self.__user_id ) 78 seat = property( lambda self: self.__seat ) 79 money = property( lambda self: self.__money ) 80 money_in_phase = property( 81 lambda self: sum([ b for a,b in self.__action_history if b != None]) ) 82 public_data = property(__publicData) 83 private_data = property(__privateData) 84 in_hand = property( lambda self: self.__in_hand ) 81 85 82 86 83 87 PHASES = ["blinds", "flop", "turn", "river"] 84 class holdemround: 88 class holdemround(object): 89 90 85 91 def __init__(self,players,blinds): 86 self. deck = deck.deck()87 self. blinds = blinds92 self.__deck = deck.deck() 93 self.__blinds = blinds 88 94 #keep both of these on hand so we can quickly find a player 89 self.players = players 90 self.player_array = players.values() 91 self.player_array.sort( cmp=lambda x,y: x.seat - y.seat) 92 print self.player_array 95 self.__players = players 96 self.__player_array = players.values() 97 self.__player_array.sort( cmp=lambda x,y: x.seat - y.seat) 93 98 self.__action_on = None 94 self. phase = 095 self. community_cards = None96 self. possible_actions = None #to cache possible actions99 self.__phase = 0 100 self.__community_cards = None 101 self.__possible_actions = None #to cache possible actions 97 102 self.__hand_count = 0 98 103 99 def actionOn(self):100 return self.__action_on101 104 #hand over? 102 103 def isHandOver(self): 104 total = sum([ 1 for p in self.player_array if p.inHand() ]) 105 def __isHandOver(self): 106 total = sum([ 1 for p in self.__player_array if not p.has_folded ]) 105 107 if total == 0: return True 106 108 107 if self. phase == len(PHASES): return True109 if self.__phase == len(PHASES): return True 108 110 return False 109 111 110 112 #return false if game is over 111 113 def nextHand(self): 112 self. deck.shuffle()114 self.__deck.shuffle() 113 115 #rotate the players 114 self.player_array.append(self.player_array.pop(0)) 115 self.phase = None 116 self.pot = 0.0 117 self.community_cards = [] 116 self.__player_array.append(self.__player_array.pop(0)) 117 self.__phase = None 118 self.__community_cards = [] 118 119 self.__hand_count += 1 119 print self. player_array120 for p in self. player_array: p.nextHand()120 print self.__player_array 121 for p in self.__player_array: p.nextHand() 121 122 #deal cards 122 123 for _ in range(2): 123 for p in self. player_array:124 p.dealCard(self. deck.deal())124 for p in self.__player_array: 125 p.dealCard(self.__deck.deal()) 125 126 126 127 return self.nextPhase() … … 130 131 self.__action_on = None 131 132 132 if self. phase != None: self.phase += 1133 else: self. phase = 0134 print "PHASE: %d" % self. phase135 for p in self. player_array: p.nextPhase()136 pn = PHASES[self. phase]133 if self.__phase != None: self.__phase += 1 134 else: self.__phase = 0 135 print "PHASE: %d" % self.__phase 136 for p in self.__player_array: p.nextPhase() 137 pn = PHASES[self.__phase] 137 138 if pn == "blinds": 138 self. player_array[0].doAction("small_blinds",self.blinds[0])139 self. player_array[1].doAction("large_blinds",self.blinds[1])139 self.__player_array[0].doAction("small_blinds",self.__blinds[0]) 140 self.__player_array[1].doAction("large_blinds",self.__blinds[1]) 140 141 self.__action_on = 1 141 142 elif pn == "flop": 142 143 for _ in range(3): 143 self. community_cards.append(self.deck.deal())144 self.__community_cards.append(self.__deck.deal()) 144 145 elif pn == "turn": 145 self. community_cards.append(self.deck.deal())146 self.__community_cards.append(self.__deck.deal()) 146 147 elif pn == "river": 147 self. community_cards.append(self.deck.deal())148 149 150 if self. isHandOver(): return False148 self.__community_cards.append(self.__deck.deal()) 149 150 151 if self.hand_over: return False 151 152 else: return self.nextAction() 152 153 153 154 #Are there any outstanding bets? 154 155 def outstandingBets(self): 155 max_money = max([p.money InPhase() for p in self.player_array])156 for p in self. player_array:157 if not p.has Folded() and p.moneyInPhase()< max_money:156 max_money = max([p.money_in_phase for p in self.__player_array]) 157 for p in self.__player_array: 158 if not p.has_folded and p.money_in_phase < max_money: 158 159 return True 159 160 return False … … 161 162 #returns false if phase is over 162 163 def nextAction(self): 163 self. possible_actions = None164 self.__possible_actions = None 164 165 165 166 #first check if we have just one player left. then we have an easy winner 166 167 167 if self. isHandOver(): return False168 if self.hand_over: return False 168 169 169 170 #increment the action 170 171 if self.__action_on != None: 171 self.__action_on = ( self.__action_on + 1 ) % len(self. player_array)172 while not self.player_array[self.__action_on].inHand():173 self.__action_on = ( self.__action_on + 1 ) % len(self. player_array)172 self.__action_on = ( self.__action_on + 1 ) % len(self.__player_array) 173 while self.current_player.has_folded: 174 self.__action_on = ( self.__action_on + 1 ) % len(self.__player_array) 174 175 else: self.__action_on = 0 175 if self. player_array[self.__action_on].hasActed()\176 if self.current_player.has_acted\ 176 177 and not self.outstandingBets(): 177 178 return False … … 179 180 180 181 def requiredAction(self, player_id): 181 return self.__action_on != None and player_id == self. player_array[self.__action_on].id182 return self.__action_on != None and player_id == self.current_player.id 182 183 183 184 #returns possible actions for a player 184 def possibleActions(self):185 if self. possible_actions != None:186 return self. possible_actions187 188 me = self. player_array[self.__action_on]189 self. possible_actions = {"fold":(None,None)}190 191 max_money = max([p.money InPhase() for p in self.player_array])185 def __getPossibleActions(self): 186 if self.__possible_actions != None: 187 return self.__possible_actions 188 189 me = self.current_player 190 self.__possible_actions = {"fold":(None,None)} 191 192 max_money = max([p.money_in_phase for p in self.__player_array]) 192 193 193 money_in_phase = me.money InPhase()194 money_in_phase = me.money_in_phase 194 195 195 min_bet = self. blinds[1]196 if PHASES[self. phase] == "river": min_bet *= 2197 198 if max_money == money_in_phase: self. possible_actions["check"] = (None,None)196 min_bet = self.__blinds[1] 197 if PHASES[self.__phase] == "river": min_bet *= 2 198 199 if max_money == money_in_phase: self.__possible_actions["check"] = (None,None) 199 200 200 201 if max_money > money_in_phase: 201 202 call = min(me.money, max_money-money_in_phase) 202 self. possible_actions["call"] = (call,call)203 self.__possible_actions["call"] = (call,call) 203 204 bet_raise = min( me.money, min_bet + max_money - money_in_phase ) 204 205 if max_money == 0 and me.money != 0.0: 205 self. possible_actions["bet"] = (bet_raise, me.money)206 self.__possible_actions["bet"] = (bet_raise, me.money) 206 207 #TODO this needs to change to reflect the last bet 207 else: self. possible_actions["raise"] = (bet_raise, me.money)208 209 return self. possible_actions208 else: self.__possible_actions["raise"] = (bet_raise, me.money) 209 210 return self.__possible_actions 210 211 #TODO fix so unlimited raises aren't allowed 211 212 212 213 213 def getState(self):214 state = {"phase": PHASES[self. phase],215 "action_on": self. player_array[self.__action_on].seat,214 def __getState(self): 215 state = {"phase": PHASES[self.__phase], 216 "action_on": self.current_player.seat, 216 217 "pot_before_phase": self.pot, 217 "community_cards": self. community_cards }218 "community_cards": self.__community_cards } 218 219 p_actions = {} 219 220 220 for (n,p) in self. players.items():221 if p.in Hand(): p_actions[n] = p.actionHistory()221 for (n,p) in self.__players.items(): 222 if p.in_hand: p_actions[n] = p.action_history 222 223 state["player_actions"] = p_actions 223 224 224 225 return state 225 226 226 def potSize(self):227 return sum([ p.moneyInPot for p in self.player_array ])228 227 229 228 def doAction(self, p_id, action, value): 230 if p_id != self. player_array[self.__action_on].id:229 if p_id != self.current_player.id: 231 230 raise InvalidActionException("Action not on player " + p_id) 232 231 233 pa = self. possibleActions()232 pa = self.__getPossibleActions() 234 233 if not action in pa: 235 234 raise InvalidActionException("Action not in possible list") … … 238 237 if not (range[0] <= value <= range[1]): 239 238 raise InvalidActionException("Value out of range") 240 self. player_array[self.__action_on].doAction(action,value)239 self.current_player.doAction(action,value) 241 240 if not self.nextAction(): 242 241 if not self.nextPhase(): … … 245 244 pass 246 245 246 #properties 247 state = property( __getState ) 248 current_player = property( lambda self: self.__player_array[self.__action_on]) 249 hand_over = property( __isHandOver ) 250 possible_actions = property( __getPossibleActions ) 251 252 #returns the amount of money in pot before current phase 253 pot = property( lambda self: sum([ p.money_in_pot for p in self.__player_array] )) 247 254 248 255 249 256 class holdemtable: 250 257 def __init__(self, name, max_players = 3, blinds = (5.0,10.0)): 251 self. max_players = max_players252 self. players={}253 self. game_started = False254 self. name = name255 self. holdemround= None256 self. deferred= []257 self. blinds = blinds258 self.__max_players = max_players 259 self.__players={} 260 self.__game_started = False 261 self.__name = name 262 self.__holdemgame = None 263 self.__deferreds = [] 264 self.__blinds = blinds 258 265 self.__cached_response = None 259 266 … … 261 268 def addPlayer(self, data, deferred ): 262 269 p_id = data['client_id'] 263 self. players[p_id]=player(p_id, data['user_id'], len(self.players))270 self.__players[p_id]=player(p_id, data['user_id'], len(self.__players)) 264 271 self.addDeferred( p_id, deferred ) 265 272 self.stateChanged("Player Added") … … 268 275 def checkStart(self): 269 276 if self.isFull(): 270 self. game_state = holdemround(self.players,self.blinds)271 self. game_started = True272 self. game_state.nextHand()277 self.__game_state = holdemround(self.__players,self.__blinds) 278 self.__game_started = True 279 self.__game_state.nextHand() 273 280 self.stateChanged("Game Starting") 274 281 return True … … 277 284 278 285 def isFull(self): 279 return len(self. players) >= self.max_players286 return len(self.__players) >= self.__max_players 280 287 281 288 def genStatus(self, p_id): … … 286 293 287 294 table_info = {} 288 table_info["game_in_progress"] = self. game_started289 table_info["name"] = self. name290 table_info["blinds"] = self. blinds295 table_info["game_in_progress"] = self.__game_started 296 table_info["name"] = self.__name 297 table_info["blinds"] = self.__blinds 291 298 292 299 players = {} 293 for (n,d) in self. players.items():294 players[n] = d.public Data()300 for (n,d) in self.__players.items(): 301 players[n] = d.public_data 295 302 table_info["players"] = players 296 303 root["table_info"] = table_info 297 304 298 if self. game_started:299 root["game_state"] = self. game_state.getState()305 if self.__game_started: 306 root["game_state"] = self.__game_state.state 300 307 self.__cached_response = root 301 308 302 309 copy = self.__cached_response.copy() 303 you = self. players[p_id].privateData()304 305 req_action = self. game_started and self.game_state.requiredAction(p_id)306 if self. game_started: print self.game_state.requiredAction(p_id)310 you = self.__players[p_id].private_data 311 312 req_action = self.__game_started and self.__game_state.requiredAction(p_id) 313 if self.__game_started: print self.__game_state.requiredAction(p_id) 307 314 308 315 print req_action 309 316 you["required_action"] = req_action 310 if req_action: you["possible_actions"] = self. game_state.possibleActions()317 if req_action: you["possible_actions"] = self.__game_state.possible_actions 311 318 312 319 copy["you"] = you … … 314 321 315 322 def action(self, p_id, action, value): 316 self. game_state.doAction(p_id,action,value)323 self.__game_state.doAction(p_id,action,value) 317 324 self.stateChanged("Actioned") 318 325 319 326 def addDeferred(self, p_id, deferred): 320 self. deferred.append((p_id, deferred))327 self.__deferreds.append((p_id, deferred)) 321 328 322 329 #call this when the state changes to update all the deferred 323 330 def stateChanged(self,action): 324 dl = self. deferred[:]325 self. deferred= []331 dl = self.__deferreds[:] 332 self.__deferreds = [] 326 333 self.__cached_response = None 327 334 for (p,d) in dl:
