Spaces:
Running
Running
__all__ = ["PLAYER1", "PLAYER2", "Connect4"] | |
PLAYER1, PLAYER2 = "red", "yellow" | |
class Connect4: | |
""" | |
A Connect Four game. | |
Play moves with :meth:`play`. | |
Get past moves with :attr:`moves`. | |
Check for a victory with :attr:`winner`. | |
""" | |
def __init__(self): | |
self.moves = [] | |
self.top = [0 for _ in range(7)] | |
self.winner = None | |
def last_player(self): | |
""" | |
Player who played the last move. | |
""" | |
return PLAYER1 if len(self.moves) % 2 else PLAYER2 | |
def last_player_won(self): | |
""" | |
Whether the last move is winning. | |
""" | |
b = sum(1 << (8 * column + row) for _, column, row in self.moves[::-2]) | |
return any(b & b >> v & b >> 2 * v & b >> 3 * v for v in [1, 7, 8, 9]) | |
def play(self, player, column): | |
""" | |
Play a move in a column. | |
Returns the row where the checker lands. | |
Raises :exc:`RuntimeError` if the move is illegal. | |
""" | |
if player == self.last_player: | |
raise RuntimeError("It isn't your turn.") | |
row = self.top[column] | |
if row == 6: | |
raise RuntimeError("This slot is full.") | |
self.moves.append((player, column, row)) | |
self.top[column] += 1 | |
if self.winner is None and self.last_player_won: | |
self.winner = self.last_player | |
return row |