class Game(GameFlow, FloatLayout): # give the type of game to a self-created type inheritence from both "FloatLayout" and "ABCMeta" __metaclass__ = type('GameMeta', (type(FloatLayout), ABCMeta), {}) id = "root" turn = 1 round = 1 def round_reset(self): """ At the end of round, update data and views """ self.turn = 1 self.round += 1 self.deck.shuffle() self.board.round_reset() self.player[0].round_reset() self.player[1].round_reset() self.ids.publicArea.round_reset(self.round) self.ids.player1_box.round_reset() self.ids.player2_box.round_reset() def build(self, testMode=True): """ Initiate objects and views. """ ''' init game objects ''' self.deck = Deck() self.evaluator = Evaluator() self.player = [] self.player.append(Player(0)) self.player.append(Player(1)) # board stands for public cards on board self.board = Board() # In test mode, both player select right-most cards for the turn automatically self.testMode = testMode ''' create view objects ''' # Scatter that can be rotated to display players scatter_bot = ScatterLayout(do_rotation=False, do_translation=False, do_scale=False, size_hint=(1, 1), pos_hint={ 'x': 0, 'y': 0 }, rotation=0) # For player on top, the widget rotates 180 degree scatter_top = ScatterLayout(do_rotation=False, do_translation=False, do_scale=False, size_hint=(1, 1), pos_hint={ 'x': 0, 'y': 0 }, rotation=180) box = PlayerDeck() box2 = PlayerDeck() publicArea = PublicArea() box.build(self, "player1", 0, self.testMode) box2.build(self, "player2", 1, self.testMode) publicArea.build() scatter_bot.add_widget(box) scatter_top.add_widget(box2) self.add_widget(scatter_bot) self.add_widget(scatter_top) self.add_widget(publicArea) # register id of view objects self.ids[box.id] = box self.ids[box2.id] = box2 self.ids[publicArea.id] = publicArea def round_play(self): """ A game round starts here. """ #self.round_reset() # draw cards for players and board self.player[0].hand = self.deck.draw(5) self.player[1].hand = self.deck.draw(5) self.board.set_cards(self.deck.draw(2)) # update view self.ids.player1_box.round_play() self.ids.player2_box.round_play() self.ids.publicArea.round_play(self.board.get_cards()) self.ids.player1_box.update_hand(self.player[0].hand, self.turn) self.ids.player2_box.update_hand(self.player[1].hand, self.turn) # TODO: fix bet self.ids.publicArea.set_chip_info(self.player[0].chip, self.player[1].chip, self.board.bonus) self.ids.publicArea.set_info(self.board.get_bet_string(self.turn)) def round_end(self): """ The end of a game round. Decide winner of the round and chip shift based on: (1) If any lier caught (2) Card score """ self.turn = 5 ''' Evaluation card rank ''' self.player[0].cardScore = self.evaluator.evaluate( self.board.get_cards(), self.player[0].hand) self.player[1].cardScore = self.evaluator.evaluate( self.board.get_cards(), self.player[1].hand) self.player[0].rank = self.evaluator.get_rank_class( self.player[0].cardScore) self.player[1].rank = self.evaluator.get_rank_class( self.player[1].cardScore) ''' Card winner ''' cardWinner = 1 if self.player[0].cardScore < self.player[1].cardScore: cardWinner = 0 # Player1 ''' Decide chip gain rate for winner, loser and board ''' winnerRate = 1.0 # The chip to handover to the card winner loserRate = 0.0 # The chip to handover to the card loser maintainRate = 0.0 # The chip left on the table if self.player[cardWinner].caught and self.player[cardWinner ^ 1].caught: # Both of players lied, and caught. winnerRate, maintainRate, loserRate = 0, 1, 0 elif self.player[cardWinner].caught: # Only winner caught if self.player[cardWinner].suspect: winnerRate, maintainRate, loserRate = -1, 1.5, 0.5 else: winnerRate, maintainRate, loserRate = -0.5, 1, 0.5 elif self.player[cardWinner ^ 1].caught: # Only loser caught if self.player[cardWinner ^ 1].suspect: winnerRate, maintainRate, loserRate = 1.5, 0.5, -1 else: winnerRate, maintainRate, loserRate = 1.5, 0, -0.5 else: # No one caught winnerRate, maintainRate, loserRate = 1, 0, 0 if self.player[cardWinner].suspect: winnerRate -= 0.5 maintainRate += 0.5 if self.player[cardWinner ^ 1].suspect: loserRate -= 0.5 maintainRate += 0.5 """ Winner Host Loser winnerPrize <--1.0 ( Stay at host if winner caught ) LieCost 0.5 <--------> 0.5 ( Pay to opponent if caught ) SuspectCost 0.5-> <-0.5 ( Pay to host if suspect not stand ) """ ''' Calculate chip gain ''' stacks = self.board.totalChip bonus = self.board.bonus self.player[cardWinner].chip += int(stacks * winnerRate) self.player[cardWinner ^ 1].chip += int(stacks * loserRate) if winnerRate > 0: # winner gets bonus self.player[cardWinner].chip += bonus bonus = stacks * maintainRate elif winnerRate < 0 and loserRate > 0: # loser gets bonus self.player[cardWinner ^ 1].chip += bonus bonus = stacks * maintainRate else: # no one gets bonus due to double caught bonus = bonus + stacks * maintainRate self.board.set_bonus(int(bonus)) # TODO: real winner, win type, chip gain roundMsg = "Player " + str(cardWinner + 1) + " wins." ''' Test Mode message ''' # print cards for check in test mode if self.testMode: print '*' * 50 if self.player[cardWinner].caught and self.player[cardWinner ^ 1].caught: print "Draw due to double caught." elif not self.player[cardWinner].caught and not self.player[ cardWinner ^ 1].caught: print "No one caught." print " Player1\t\tPlayer2" print "Lie : ", self.player[0].lie, "\t\t", self.player[ 1].lie print "Suspection: ", self.player[0].suspect, "\t\t", self.player[ 1].suspect print "Caught : ", self.player[0].caught, "\t\t", self.player[ 1].caught print "Fold : ", self.player[0].fold, "\t\t", self.player[ 1].fold if cardWinner == 0: print " Win\t\tLose" else: print " Lose\t\tWin" print "Rate (winner/maintain/loser): ", winnerRate, maintainRate, loserRate print "Chip and bonus after: ", self.board.totalChip, self.board.bonus print "Card rank: " print "Player 1 hand rank = %d (%s)" % (self.player[0].cardScore, self.player[0].rank) print "Player 2 hand rank = %d (%s)" % (self.player[1].cardScore, self.player[1].rank) print '*' * 50 ''' end a game round ''' # TODO: show at another place self.ids.player1_box.set_button_message( self.evaluator.class_to_string(self.player[0].rank)) self.ids.player2_box.set_button_message( self.evaluator.class_to_string(self.player[1].rank)) self.ids.publicArea.round_end("Round : " + str(self.round) + "\n" + roundMsg + "\nNew Round") self.board.round_end() self.ids.player1_box.round_end() self.ids.player2_box.round_end()