Exemplo n.º 1
0
 def finalize_score(self):
     """ When game is completed, update scores with the tiles left """
     if self._game_resigned:
         # In case of a resignation, the resigning player has already lost all points
         return
     for ix in range(2):
         # Add the score of the opponent's tiles
         self._scores[ix] += Alphabet.score(self._racks[1 - ix].contents())
         # Subtract the score of the player's own tiles
         self._scores[ix] -= Alphabet.score(self._racks[ix].contents())
         if self._scores[ix] < 0:
             self._scores[ix] = 0
Exemplo n.º 2
0
    def _append_final_adjustments(self, movelist):
        """ Appends final score adjustment transactions to the given movelist """

        # Lastplayer is the player who finished the game
        lastplayer = self.moves[-1].player if self.moves else 0

        if not self.state.is_resigned():

            # If the game did not end by resignation, check for a timeout
            overtime = self.overtime()
            adjustment = list(self.overtime_adjustment())
            sc = self.state.scores()

            if any(overtime[ix] >= Game.MAX_OVERTIME for ix in range(2)): # 10 minutes overtime
                # Game ended with a loss on overtime
                ix = 0 if overtime[0] >= Game.MAX_OVERTIME else 1
                adjustment[1 - ix] = 0
                # Adjust score of losing player down by 100 points
                adjustment[ix] = - min(100, sc[ix])
                # If losing player is still winning on points, add points to the
                # winning player so that she leads by one point
                if sc[ix] + adjustment[ix] >= sc[1 - ix]:
                    adjustment[1 - ix] = sc[ix] + adjustment[ix] + 1 - sc[1 - ix]
            else:
                # Normal end of game
                opp_rack = self.state.rack(1 - lastplayer)
                opp_score = Alphabet.score(opp_rack)
                last_rack = self.state.rack(lastplayer)
                last_score = Alphabet.score(last_rack)
                if not last_rack:
                    # Won with an empty rack: Add double the score of the losing rack
                    movelist.append((1 - lastplayer, (u"", u"--", 0)))
                    movelist.append((lastplayer, (u"", u"2 * " + opp_rack, 2 * opp_score)))
                else:
                    # The game has ended by passes: each player gets her own rack subtracted
                    movelist.append((1 - lastplayer, (u"", opp_rack, -1 * opp_score)))
                    movelist.append((lastplayer, (u"", last_rack, -1 * last_score)))

            # If this is a timed game, add eventual overtime adjustment
            if tuple(adjustment) != (0, 0):
                movelist.append((1 - lastplayer, (u"", u"TIME", adjustment[1 - lastplayer])))
                movelist.append((lastplayer, (u"", u"TIME", adjustment[lastplayer])))

        # Add a synthetic "game over" move
        movelist.append((1 - lastplayer, (u"", u"OVER", 0)))
Exemplo n.º 3
0
 def client_state(self):
     """ Create a package of information for the client about the current state """
     reply = dict()
     if self.state.is_game_over():
         # The game is now over - one of the players finished it
         reply["result"] = Error.GAME_OVER # Not really an error
         num_moves = 1
         if self.last_move is not None:
             # Show the autoplayer move if it was the last move in the game
             reply["lastmove"] = self.last_move.details()
             num_moves = 2 # One new move to be added to move list
         newmoves = [(player, m.summary(self.state.board())) for player, m in self.moves[-num_moves:]]
         # Lastplayer is the player who finished the game
         lastplayer = self.moves[-1][0]
         if not self.resigned:
             # If the game did not end by resignation,
             # account for the losing rack
             rack = self.state._racks[1 - lastplayer].contents()
             # Subtract the score of the losing rack from the losing player
             newmoves.append((1 - lastplayer, (u"", rack, -1 * Alphabet.score(rack))))
             # Add the score of the losing rack to the winning player
             newmoves.append((lastplayer, (u"", rack, 1 * Alphabet.score(rack))))
         # Add a synthetic "game over" move
         newmoves.append((1 - lastplayer, (u"", u"OVER", 0)))
         reply["newmoves"] = newmoves
         reply["bag"] = "" # Bag is now empty, by definition
         reply["xchg"] = False # Exchange move not allowed
     else:
         # Game is still in progress
         reply["result"] = 0 # Indicate no error
         reply["rack"] = self.state.player_rack().details()
         reply["lastmove"] = self.last_move.details()
         reply["newmoves"] = [(player, m.summary(self.state.board())) for player, m in self.moves[-2:]]
         reply["bag"] = self.display_bag()
         reply["xchg"] = self.state.is_exchange_allowed()
     reply["scores"] = self.state.scores()
     return reply
Exemplo n.º 4
0
    def finalize_score(self, lost_on_overtime = None, overtime_adjustment = None):
        """ When game is completed, calculate the final score adjustments """

        if self._game_resigned:
            # In case of a resignation, the resigning player has already lost all points
            return

        sc = self._scores
        adj = self._adj_scores

        if lost_on_overtime is not None:
            # One of the players lost on overtime
            player = lost_on_overtime
            # Subtract 100 points from the player
            adj[player] = - min(100, sc[player])
            # If not enough to make the other player win, add to the other player
            if sc[player] + adj[player] >= sc[1 - player]:
                adj[1 - player] = sc[player] + adj[player] + 1 - sc[1 - player]
            # There is no consideration of rack leave in this case
            return

        if any(self._racks[ix].is_empty() for ix in range(2)):
            # Normal win by one of the players
            for ix in range(2):
                # Add double the score of the opponent's tiles (will be zero for the losing player)
                adj[ix] = 2 * Alphabet.score(self.rack(1 - ix))
        else:
            # Game expired by passes
            for ix in range(2):
                # Subtract the score of the player's own tiles
                adj[ix] = - Alphabet.score(self.rack(ix))

        # Apply overtime adjustment, if any
        if overtime_adjustment is not None:
            for ix in range(2):
                adj[ix] += overtime_adjustment[ix]