Beispiel #1
0
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()