Connect K
unknown
python
17 days ago
3.1 kB
14
Indexable
""" R B B R B R ... _ _ _ _ _ ... -1 0 1 2 3 k = 3 Player R inserts at 2 R B B B B R R R ... _ _ _ _ _ ... -1 0 1 2 3 """ class Token: def __init__(self, color): self.color = color def __eq__(self, other): self.color == other.color def __hash__(self): return hash(self.color) from collections import defaultdict class Board: def __init__(self, k): self.columns = defaultdict(list) self.k = k def _check_count(placed_token, gen): count = 0 for new_token in gen(): if new_token != placed_token: return count count += 1 return count def _horizontal_generator(placed_token, x, y, x_direction, y_direction): col = self.columns[x] for delta in range(1, self.k): new_x = x + delta * x_direction new_y = y + delta * y_direction new_column = self.columns[new_x] if len(new_column) < new_y + 1: # since we are 1 indexed return yield new_column[-new_y - 1] def _won_horizontally(self, token, column): col = self.columns[column] def _horizontally(placed_token, y, direction): # direciton is -1 or 1, -1 is left, 1 is right # y is 0-indexed count = 0 for delta in range(1, self.k): new_column = self.columns[column + delta * direction] if len(new_column) < y + 1: # since we are 1 indexed return count # we want to count backwards from the back, python -1 == last element => y = 0 if new_column[-y - 1] != placed_token: return count # they are the same count += 1 return count # all are the same def _horizontally_left(placed_token, y) -> int: return _horizontally(placeD_token, y, -1) def _horizontally_right(placed_token, y) -> int: return _horizontally(placeD_token, y, 1) wins = set() for y, placed_token in enumerate(col[::-1]): # 1 for self if 1 + _horizontally_left(placed_token, y) + _horizontally_right(placed_token, y) >= self.k: wins.add(placed_token) return wins def _won_vertically(self, token, column) -> List[Token]: col = self.columns[column] count = 0 for placed_token in col[-1:]: if placed_token != token: return set() # there are no winners count += 1 if count == self.k: return {placed_token} return set() def play(self, token, column): # return the token type which indicates the identity of the player self.columns[column].append(token) total_wins = set() for win_condition in [self._won_horizontally(token, column), self._won_vertically(token, column)]: total_wins |= win_condition() return total_wins
Editor is loading...
Leave a Comment