def startHand(gameId): numberOfPlayers = db.numberOfPlayersInGame(gameId) _, _, _, dealer, _, _, _, _, handNo, smallBlind, blindIncrement = db.getGame( gameId) blindsIncreased = False if blindIncrement != 0: if (handNo + 1) % blindIncrement == 0: smallBlind *= 2 blindsIncreased = True handNo += 1 db.updateGame( gameId, "handNo = " + str(handNo) + ", smallBlind = " + str(smallBlind)) smallBlind = smallBlind bigBlind = smallBlind * 2 deck = pd.Deck() deck.shuffle() # Deal cards and set playes to not be folded for i in range(numberOfPlayers): _, _, _, _, _, _, _, _, eliminated, _, _, _ = db.getPlayer(gameId, i) if eliminated == 0: # not eliminated hand = deck.deal(2) db.updatePlayer( gameId, i, "folded = 0, isChecked = 0, cards = \"" + str(hand[0]) + ":" + str(hand[1]) + "\", amountPutInPot = 0, amountPutInPotThisRound = 0") #dealer moves to left dealerPos, smallBlindPos, bigBlindPos, UTG = getNextStartingPlayers(gameId) handLog = "<b>Hand number " + str( handNo) + "</b>\r\n--------------------------------------\r\n" if blindsIncreased: handLog += "Blinds have increased to " + str( smallBlind) + " and " + str(bigBlind) + " chips.\r\n" handLog += "Dealer: " + db.getPlayer(gameId, dealerPos)[3] + "\r\n" #UpdateGame db.updateGame( gameId, "currentPlayer = " + str(UTG) + ", dealer = " + str(dealerPos) + ", board = '', phase = 0, pot = 0, betToMatch = " + str(bigBlind)) handLog += (player.addToPot(gameId, smallBlindPos, smallBlind, "sb") + "\r\n") handLog += (player.addToPot(gameId, bigBlindPos, bigBlind, "bb")) db.updateGame(gameId, "handLog = \"" + handLog + "\"") return UTG
def nextPlayer(gameId): _, _, currentPlayer, dealer, _, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) for i in range(numberOfPlayers - 1): playerNumber = (i + currentPlayer + 1) % numberOfPlayers _, _, _, _, _, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, playerNumber) if not bool(folded) and not bool(eliminated) and not bool( isAllIn) and not bool(isChecked): return db.getPlayer(gameId, playerNumber) return -1 # Error state, should check if round is complete first
def raiseTo(gameId, playerTuple, raiseToChips): _, _, _, _, _, pot, betToMatch, handLog, _, _, _ = db.getGame(gameId) _, playerId, address, name, stack, _, _, _, _, amountPutInPot, _, amountPutInPotThisRound = playerTuple if betToMatch > raiseToChips: return False elif betToMatch == raiseToChips: call(gameId, playerTuple) return True else: chipsToPutIn = raiseToChips - amountPutInPotThisRound logStatement = handLog + "\r\n" + addToPot(gameId, playerId, chipsToPutIn, "raise") numberOfPlayers = db.numberOfPlayersInGame(gameId) for i in range(numberOfPlayers): _, _, _, _, _, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, i) if not bool(folded) and not bool(eliminated) and not bool(isAllIn): db.updatePlayer(gameId, i, "isChecked = 0") # Raiser is checked db.updatePlayer(gameId, playerId, "isChecked = 1") db.updateGame(gameId, "handLog = \"" + logStatement + "\"") return True
def getAllCardsInPlay(gameId): numberOfPlayers = db.numberOfPlayersInGame(gameId) allCards = [] board = db.getGame(gameId)[1] if not board == "": allCards = board.split(":") for i in range(numberOfPlayers): allCards += db.getPlayer(gameId, i)[5].split(":") return allCards
def checkForRoundCompletion(gameId): _, _, currentPlayer, dealer, _, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) for i in range(numberOfPlayers): _, _, _, _, _, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, i) if not bool(folded) and not bool(eliminated) and not bool( isAllIn) and not bool(isChecked): return False return True
def allAreAllIn(gameId): _, _, currentPlayer, dealer, _, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) if nextPlayer(gameId) == -1: return True for i in range(numberOfPlayers): _, _, _, _, _, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, i) if not bool(eliminated) and not bool(folded) and not bool(isAllIn): return False return True
def isGameOver(gameId): _, _, currentPlayer, dealer, _, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) numbernotElim = 0 for i in range(numberOfPlayers): _, _, _, _, _, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, i) if not bool(eliminated): numbernotElim += 1 if numbernotElim > 1: return False return True
def takeFromPot(gameId, player, chips): _, _, _, _, _, pot, _, _, _, _, _ = db.getGame(gameId) playerTuple = db.getPlayer(gameId, player) _, _, address, name, stack, _, _, _, _, amountPutInPot, _, amountPutInPotThisRound = playerTuple logStatement = "" logStatement = "Player " + name + " takes " + str( chips) + " chips from the pot." #update player stack db.updatePlayer(gameId, player, "stack = " + str(stack + chips)) #update pot db.updateGame(gameId, "pot = " + str(pot - chips)) return logStatement
def isHandOver(gameId): _, _, currentPlayer, dealer, phase, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) if phase == 4: return True numberChecked = 0 for i in range(numberOfPlayers): _, _, _, _, _, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, i) if not bool(folded) and not bool(eliminated): numberChecked += 1 if numberChecked > 1: return False return True
def addToPot(gameId, player, chips, action): _, _, _, _, _, pot, betToMatch, _, _, _, _ = db.getGame(gameId) playerTuple = db.getPlayer(gameId, player) _, _, address, name, stack, _, _, _, _, amountPutInPot, _, amountPutInPotThisRound = playerTuple logStatement = "" chipsPutIn = chips if stack <= chips: logStatement += "Player " + name + " is all in! " chipsPutIn = stack db.updatePlayer(gameId, player, "isAllIn = 1") logStatement += "Player " + name + " " if action == "sb": # small blind logStatement += "posted the small blind of " + str( chipsPutIn) + " chips." elif action == "bb": # big blind logStatement += "posted the big blind of " + str( chipsPutIn) + " chips." elif action == "call": logStatement += "calls " + str(chipsPutIn) + " chips." elif action == "raise": # check if amount put in actually makes it a raise (i.e. with all in less than btm) if chipsPutIn > betToMatch: db.updateGame( gameId, "betToMatch = " + str(amountPutInPotThisRound + chipsPutIn)) logStatement += "raises to " + str(amountPutInPotThisRound + chipsPutIn) + " chips." # otherwise betToMatch is not increased and no raise has been made elif action == "check": logStatement += "checks." #update player stack db.updatePlayer( gameId, player, "stack = " + str(stack - chipsPutIn) + ", amountPutInPot = " + str(amountPutInPot + chipsPutIn) + ", amountPutInPotThisRound = " + str(amountPutInPotThisRound + chipsPutIn)) #update pot db.updateGame(gameId, "pot = " + str(pot + chipsPutIn)) return logStatement
def readMail(imapper, mailId=None, fakeMail=None): if DEBUG: mail_id = mailId mail = fakeMail else: mail_id = imapper.listids()[0] mail = imapper.mail(mail_id) # If new email if not db.isMailRead(mail_id): db.addReadMail(mail_id) if mail.title.upper() == "NEW": #make new game gameId = game.newGame(mail.body) firstPlayer = game.startGame(gameId) print("First player = " + str(firstPlayer)) #Send first mail sendMail( db.getPlayer(gameId, firstPlayer)[2], gameId, db.getGame(gameId)[7] + playerInfoLog(gameId, firstPlayer) + instructions()) return gameId #look for game with id in title elif not len(db.getGame(mail.title[4:])) == 0: gameId = mail.title[4:] playerEmail = mail.from_addr[mail.from_addr.find('<') + 1:mail.from_addr.rfind('>')].lower() playerTuple = db.getPlayerByEmail(gameId, playerEmail) gameTuple = db.getGame(gameId) successfulRaise = True #if current player if playerTuple[1] == gameTuple[2]: # current player if mail.body.upper().startswith("CALL"): player.call(gameId, playerTuple) elif mail.body.upper().startswith("RAISE"): if len(mail.body.split(" ")) < 2: successfulRaise = False else: if mail.body.split(" ")[1].strip().find('\r') == -1: chipsToRaiseTo = int( mail.body.split(" ")[1].strip()) else: chipsToRaiseTo = int( mail.body.split(" ")[1].strip() [:mail.body.split(" ")[1].strip().find('\r')]) successfulRaise = player.raiseTo( gameId, playerTuple, chipsToRaiseTo) elif mail.body.upper().startswith("FOLD"): player.fold(gameId, playerTuple) elif mail.body.upper().startswith("ALL IN"): successfulRaise = player.allIn(gameId, playerTuple) else: successfulRaise = False if successfulRaise: if not game.allAreAllIn(gameId): nextPlayerTuple = game.nextPlayer(gameId) if game.checkForRoundCompletion(gameId): # Starts next round and returns active player nextPlayerTuple = db.getPlayer(gameId, game.nextRound(gameId)) if game.isHandOver(gameId): game.showdown(gameId) # Send mail to all players for i in range(db.numberOfPlayersInGame(gameId)): sendMail( db.getPlayer(gameId, i)[2], gameId, db.getGame(gameId)[7]) if not game.isGameOver(gameId): nextPlayerTuple = db.getPlayer( gameId, game.startHand(gameId)) if not game.isGameOver(gameId): if not game.allAreAllIn(gameId): db.updateGame( gameId, "currentPlayer = " + str(nextPlayerTuple[1])) sendMail( nextPlayerTuple[2], gameId, db.getGame(gameId)[7] + playerInfoLog(gameId, nextPlayerTuple[1]) + instructions()) else: _, _, currentPlayer, dealer, _, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) while not game.isHandOver(gameId): game.nextRound(gameId) game.showdown(gameId) # Send mail to all players for i in range(db.numberOfPlayersInGame(gameId)): sendMail( db.getPlayer(gameId, i)[2], gameId, db.getGame(gameId)[7]) if not game.isGameOver(gameId): nextPlayerTuple = db.getPlayer( gameId, game.startHand(gameId)) sendMail( nextPlayerTuple[2], gameId, db.getGame(gameId)[7] + playerInfoLog(gameId, nextPlayerTuple[1]) + instructions()) if game.isGameOver(gameId): _, _, currentPlayer, dealer, _, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) for i in range(numberOfPlayers): _, _, _, _, _, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, i) if not bool(eliminated): winner = i break for i in range(numberOfPlayers): sendMail( db.getPlayer(gameId, i)[2], gameId, "The winner was " + db.getPlayer(gameId, winner)[3] + "! Thanks for playing :)") db.deleteGame(gameId) # unsuccessful raise else: sendMail( playerEmail, gameId, "Invalid input. Please try again.\r\n" + instructions())
def playerInfoLog(gameId, playerId): _, board, _, _, _, pot, betToMatch, handLog, _, _, _ = db.getGame(gameId) string = "\r\n\r\nPlayers:" for i in range(db.numberOfPlayersInGame(gameId)): _, _, address, name, stack, _, isAllIn, folded, eliminated, _, isChecked, _ = db.getPlayer( gameId, i) string += "\r\n" + name + " - " + str(stack) + " chips" _, _, _, name, stack, cards, _, _, _, amountPutInPot, _, amountPutInPotThisRound = db.getPlayer( gameId, playerId) string += "\r\n\r\nIt is your turn " + name + ".\r\nYour cards are: " + game.cardToUnicode( cards.split(":")[0]) + " and " + game.cardToUnicode( cards.split(":")[1]) if board != "": string += "\r\nThe board is : " for card in board.split(":"): string += game.cardToUnicode(str(card)) + ", " string = string[:-2] # get rid of trailing comma string += "\r\nThe pot is " + str(pot) + " chips." string += "\r\nYour stack is " + str(stack) + " chips." if not amountPutInPotThisRound == 0: string += "You have already put in " + str( amountPutInPotThisRound) + " chips into the pot." if betToMatch - amountPutInPotThisRound != 0: string += "\r\nTo call you'll need to put in " + str( betToMatch - amountPutInPotThisRound) + " chips." return string
def showdown(gameId): _, _, currentPlayer, dealer, _, pot, betToMatch, handLog, _, _, _ = db.getGame( gameId) numberOfPlayers = db.numberOfPlayersInGame(gameId) board = db.getGame(gameId)[1] string = "" if board != "": string += "\r\n\r\nThe board was : " for card in board.split(":"): string += cardToUnicode(str(card)) + ", " string = string[:-2] # get rid of trailing comma db.updateGame(gameId, "handLog = \"" + db.getGame(gameId)[7] + string + "\"") isStillIn = [] for i in range(numberOfPlayers): _, _, _, _, stack, cards, isAllIn, folded, eliminated, amountPutInPot, isChecked, _ = db.getPlayer( gameId, i) if not bool(folded) and not bool(eliminated): isStillIn.append([i, amountPutInPot, stack, cards]) thisPot = pot while len(isStillIn) > 1: minimumAIP = min(i[1] for i in isStillIn) thisPot = minimumAIP * len(isStillIn) for i in isStillIn: i[1] -= minimumAIP winners = getWinners(gameId, isStillIn) for i in winners: handLog = db.getGame(gameId)[7] playerTuple = db.getPlayer(gameId, i[0]) logStatement = playerTuple[3] + " shows " + cardToUnicode( playerTuple[5].split(":")[0]) + ", " + cardToUnicode( playerTuple[5].split(":")[1]) logStatement += " (" + i[1] + ")" logStatement += "\r\n" + player.takeFromPot( gameId, i[0], thisPot // len(winners)) db.updateGame( gameId, "handLog = \"" + handLog + "\r\n" + logStatement + "\"") newIsStillIn = [] for i in isStillIn: if i[1] != 0: newIsStillIn.append(i) else: if i[0] not in (j[0] for j in winners): playerTuple = db.getPlayer(gameId, i[0]) logStatement = playerTuple[3] + " shows " + \ cardToUnicode(playerTuple[5].split(":")[0]) + ", " + \ cardToUnicode(playerTuple[5].split(":")[1]) handLog = db.getGame(gameId)[7] db.updateGame( gameId, "handLog = \"" + handLog + "\r\n" + logStatement + "\"") isStillIn = newIsStillIn pot -= thisPot thisPot = 0 if len(isStillIn) == 1: handLog = db.getGame(gameId)[7] logStatement = player.takeFromPot( gameId, isStillIn[0][0], isStillIn[0][1] + (pot - isStillIn[0][1])) db.updateGame(gameId, "handLog = \"" + handLog + "\r\n" + logStatement + "\"") for i in range(numberOfPlayers): _, _, _, _, stack, cards, isAllIn, folded, eliminated, amountPutInPot, isChecked, _ = db.getPlayer( gameId, i) if stack <= 0: db.updatePlayer(gameId, i, "eliminated = 1") db.updatePlayer(gameId, i, "isAllIn = 0")