Skip to content

Instantly share code, notes, and snippets.

@breeko
Created January 28, 2018 04:54
Show Gist options
  • Save breeko/8b7f698a1ebcf2c0a0d477286062cf20 to your computer and use it in GitHub Desktop.
Save breeko/8b7f698a1ebcf2c0a0d477286062cf20 to your computer and use it in GitHub Desktop.
Connect-4 type game object
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