Example #1
0
 def _compute_winner(self, use_cards=True, player_filter=None):
     maxpoints = 0
     top_players = []
     player_filter = player_filter or set(range(self.players_number))
     for i, p in enumerate(self.players):
         if i not in player_filter:
             continue
         if use_cards:
             c = self._compute_cards_points(p['cards'])
             pt = p['points'] + c
             ref_logger.info('player %s got %s points (%s from cards)',
                             i + 1, pt, c)
         else:
             pt = p['points']
             ref_logger.info('at tie-breaker player %s got %s points',
                             i + 1, pt)
         if pt > maxpoints:
             maxpoints = pt
             top_players = [i]
         elif pt == maxpoints:
             top_players.append(i)
     if len(top_players) == 1:
         return top_players[
             0] + 1  # winning player count goes from 1: 0 is "no winner"
     if not use_cards:
         ref_logger.error(
             'players %s are tied with and witout cards, returing draw',
             [pi + 1 for pi in top_players])
         return DRAW
     return self._compute_winner(use_cards=False)
Example #2
0
 def _check_deaths(self):
     '''
         set players status to DEAD if it is time
     '''
     g_reds = 0
     n_ind = COMMON_TRACKS_NAMES.index(NOISE_TRACK_NAME)
     s_ind = PLAYER_TRACKS_NAMES.index(SOCIAL_TRACK_NAME)
     c_ind = COMMON_TRACKS_NAMES.index(CASH_TRACK_NAME)
     if COMMON_TRACKS_EFFECT[n_ind][2].get(self.common_tracks[n_ind],
                                           (None, ))[0] == RED:
         g_reds += 1
         ref_logger.debug('a red for everyone, noise is high')
     for i, p in enumerate(self.players):
         if p['status'] == DEAD:
             continue
         p_reds = sum(1 for v, (_, _,
                                e) in zip(p['tracks'], PLAYER_TRACKS_EFFECT)
                      if e.get(v, (None, ))[0] == RED)
         ref_logger.debug('player %s has %s red dots', i + 1, p_reds)
         if COMMON_TRACKS_EFFECT[c_ind][2].get(self.common_tracks[c_ind],
                                               (None, ))[0] == RED:
             social_value = p['tracks'][s_ind]
             for j, p2 in enumerate(self.players):
                 if j != i and p2['status'] == ALIVE and p2['tracks'][
                         s_ind] < social_value:
                     break
             else:
                 ref_logger.debug(
                     'plus the cash one, because it\'s the worst')
                 p_reds += 1
         if p_reds >= REDS_TO_DIE:
             ref_logger.info('player %s dies with %s red dots', i + 1,
                             p_reds)
             p['status'] = DEAD
Example #3
0
 def execute_turn(self, moves):
     '''
        each move is two values separed by space.
        each of them is either an int between 1 and 6, or wc{n} with n in AVAILABLE_WCS
     '''
     wcs = tuple('wc{}'.format(n) for n in AVAILABLE_WCS)
     cards = [DECK[c] for c in self.cards_on_the_table]
     dices = [[] for _ in cards]
     ref_logger.info('received moves %s', moves)
     for i, (m, p) in enumerate(zip(moves, self.players)):
         pl = i + 1
         if p['status'] == DEAD:
             ref_logger.debug('player %s is DEAD, ignoring input', pl)
         expected_values = 2 - len(p['wc_dices'])
         values = [v for v in m.split(' ') if v]
         if (l := len(values)) != expected_values:
             raise InvalidMove('expected {} values, got {}'.format(
                 expected_values, l))
         modifiers = [0] * len(PLAYER_TRACKS_NAMES)
         for v in values:
             if v in wcs:
                 self._send_to_wc(pl, p, int(v[-1]))
             elif not v.isdigit():
                 raise InvalidMove('unexpected value: {}'.format(v))
             else:
                 v = int(v)
                 if v < 1 or v > 6:
                     raise InvalidMove(
                         'numeric value not in range 1-6: {}'.format(v))
                 dices[v - 1].append(i)
                 c = cards[v - 1]
                 p['points'] += c[2]
                 for ind, val in enumerate(c[3]):
                     modifiers[ind] += val
                 ref_logger.debug(
                     'player %s puts a dice on card %s, for %s points and modifiers %s',
                     pl, v, c[2], c[3])
         for tind, mod in enumerate(modifiers):
             trackmax = PLAYER_TRACKS_LENGTH[tind] - 1
             currval = p['tracks'][tind]
             p['tracks'][tind] += max(min(mod, trackmax - currval),
                                      -currval)
         ref_logger.debug('player %s modified status: %s', pl,
                          [ti + 1 for ti in p['tracks']])
Example #4
0
 def _shift_wc(self):
     '''
         scrolls every waiting player in the wc
     '''
     l_ind = PLAYER_TRACKS_NAMES.index(LIQUID_TRACK_NAME)
     for i, p in enumerate(self.players):
         to_remove = []
         if p['status'] == DEAD:
             continue
         for j, d in enumerate(p['wc_dices']):
             if d[1] == 1:
                 q = min(d[0], p['tracks'][l_ind])
                 p['tracks'][l_ind] -= q
                 to_remove.append(j)
                 ref_logger.info(
                     'a dice for player %s reaches wc, %s liquid removed. current liquid: %s',
                     i + 1, q, p['tracks'][l_ind])
             else:
                 d[1] -= 1
         while to_remove:
             j = to_remove.pop()
             p['wc_dices'].pop(j)
Example #5
0
 def check_mate(self, player_id):
     '''
         returns 2 if player {player_id} made checkmate with last move, 1 if stalemate, 0 if none
     '''
     pp = self.player_pieces
     other_player = (player_id % 2) + 1
     other_king = self.kings[other_player]
     ref_logger.debug(
         'looking available moves of next player to detect mate')
     available_moves = any(self.available_moves(other_player))
     if not available_moves:
         ref_logger.info(
             'no available moves, checking whether is stalemate or checkmate'
         )
         check = self.check_menace(other_king,
                                   player_id=player_id,
                                   pieces=pp[player_id])
         if check:  # check
             ref_logger.info('opposing king %s under check from %s, mate!',
                             other_king, check)
             return 2
         return 1
     return 0
Example #6
0
 def setup(self):
     ref_logger.info('starting game')
     return [['WHITE'], ['BLACK']]
Example #7
0
 def setup(self):
     ref_logger.info('starting game')
     p = len(self.players)
     return [[str(p)] for _ in range(p)]
Example #8
0
 def setup(self):
     ref_logger.info('starting game')
     return [[c] for c in COLORS]
Example #9
0
 def setup(self):
     ref_logger.info('starting game; board:\n%s', self.draw_board())
     return [[s] for s in SYMBOLS[1:]]