Created
January 28, 2018 04:54
-
-
Save breeko/8b7f698a1ebcf2c0a0d477286062cf20 to your computer and use it in GitHub Desktop.
Connect-4 type game object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| class Connect: | |
| def __init__(self, connect=4, width=7, height=6): | |
| self.height = height | |
| self.width = width | |
| self.connect = connect | |
| self.legal_players = ["X", "O"] | |
| self.reset() | |
| def reset(self): | |
| self.board = [[" " for _ in range(self.width)] for _ in range(self.height)] | |
| def __str__(self): | |
| """ String representation of a game """ | |
| board = "" | |
| for r in range(self.height): | |
| board += "|" | |
| for c in range(self.width): | |
| board += "{}|".format(self.board[r][c]) | |
| board += "\n" | |
| return board[:-1] | |
| def __eq__(self, other): | |
| if isinstance(other, type(self)): | |
| return self.board == other.board | |
| return False | |
| def __hash__(self): | |
| return hash("".join(sum(self.board,[]))) | |
| def copy(self): | |
| """ Creates a copy of the game object """ | |
| new_board = self.__class__(connect=self.connect, width=self.width, height=self.height) | |
| new_board.board = [x[:] for x in self.board] | |
| return new_board | |
| def get_moves(self): | |
| # Check if top row filled | |
| return [idx for idx, val in enumerate(self.board[0]) if val == " "] | |
| def _is_match(self, match): | |
| s_match = set(match) | |
| if len(s_match) == 1 and " " not in s_match: | |
| return match[0] | |
| def move(self, player, c): | |
| player = player.upper() | |
| assert c in self.get_moves(), "Illegal move" | |
| assert player in self.legal_players, "Illegal player" | |
| move_row = 0 | |
| for r in reversed(range(self.height)): | |
| if self.board[r][c] == " ": | |
| move_row = r | |
| break | |
| self.board[move_row][c] = player | |
| def winner(self): | |
| # check horizontal | |
| for r in range(self.height): | |
| for c in range(self.width - self.connect + 1): | |
| match = [self.board[r][c+off] for off in range(self.connect)] | |
| if self._is_match(match) is not None: | |
| return match[0] | |
| # check vertical | |
| for r in range(self.height - self.connect + 1): | |
| for c in range(self.width): | |
| match = [self.board[r+off][c] for off in range(self.connect)] | |
| if self._is_match(match) is not None: | |
| return match[0] | |
| # check diagonal | |
| for r in range(self.height - self.connect // 2 - 1): | |
| for c in range(self.width - self.connect // 2 - 1): | |
| # diagonal \ | |
| match = [self.board[r + off][c + off] for off in range(self.connect)] | |
| if self._is_match(match) is not None: | |
| return match[0] | |
| # diagonal / | |
| match = [self.board[off][self.width - off - 1] for off in range(self.connect)] | |
| if self._is_match(match) is not None: | |
| return match[0] | |
| def score_game(self, player): | |
| if self.winner() == player: | |
| return 1 | |
| elif self.winner() in self.legal_players: | |
| return -1 | |
| return 0 | |
| def gameover(self): | |
| return len(self.get_moves()) == 0 or self.winner() is not None |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment