Skip to content

Instantly share code, notes, and snippets.

@barangerbenjamin
Created January 8, 2021 16:13
Show Gist options
  • Save barangerbenjamin/d0c90d4c4eb49576c53c783b199675eb to your computer and use it in GitHub Desktop.
Save barangerbenjamin/d0c90d4c4eb49576c53c783b199675eb to your computer and use it in GitHub Desktop.
class Connect4():
def __init__(self): # Constructor
self.current_player = "1" # Who's playing now
self.next_player = "2" # Who's the next player
self.ongoing = True # Is the game finished?
self.grid = [
['0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0'],
['0', '0', '0', '0', '0', '0', '0']
] # State of the board
def play_is_valid(self, col): # Method to check if play is valid
column = [row[col] for row in self.grid] # Build column
return column.count("0") >= 1 # if there is no "0", the column if full of "1" or "2"
def check_won(self, col, row, r): # Method to check if the last move won
column = [row[col] for row in self.grid] # Build column
winning_comb = "1111" if self.current_player == "1" else '2222' # Build winning pattern depending of current player
return winning_comb in ''.join(column) or winning_comb in ''.join(row) or winning_comb in self.diag_left(col, r) or winning_comb in self.diag_right(col, r) # Test all the methods to check if win
def diag_left(self, col, r): # Method to build the left diagonale
diag_left = ""
j = 0
for i in range(r, 6): # Going from current row to max one
if col + j >= 0: # checking we're in bounds
row = self.grid[i] # Retrieving row
el = row[col - j] # Retrieving element at the col index - 1 (going diag bottom left)
diag_left += el # Adding the element to the string
j += 1
diag_left = diag_left[::-1] # Reversing the string, cause we collected in the reversed order
j = 1
for i in range(r - 1, -1, -1): # Going from current row -1 to first one (index 0)
if col + j < 7: # checking we're in bounds
row = self.grid[i] # Retrieving row
el = row[col + j] # Retrieving element at the col index + 1 (going diag top right)
diag_left += el # Adding the element to the string
j += 1
return diag_left
def diag_right(self, col, r): # Method to build the right diagonale
diag_right = ""
j = 1
for i in range(r + 1, 6): # Going from current row + 1 to max one
if col + j < 7: # checking we're in bounds
row = self.grid[i] # Retrieving row
el = row[col + j] # Retrieving element at the column index + 1 (going diag bottom right)
diag_right += el # Adding the element to the string
j += 1
diag_right = diag_right[::-1] # Reversing the string, cause we collected in the reversed order
j = 0
for i in range(r, -1, -1): # Going from current row to the first one (index 0 with a step of -1)
if col + j >= 0: # checking we're in bounds
row = self.grid[i] # Retrieving row
el = row[col - j] # Retrieving element at the column index -1 (going diag top left)
diag_right += el # Adding the element to the string
j += 1
return diag_right
def play(self, col):
if self.ongoing == False: # Checking that the game is still ongoing
return "Game has finished!"
if self.play_is_valid(col) == False: # Checking that the column is not full
return "Column full!"
# add the player number to the bottom of column
column = [row[col] for row in self.grid] # Building current column where the user played
i = -1
while i > -7: # Looping through the column indexes in reverse order because the play should fall at the bottom of the column
if column[i] == "0": # If "0", no one played here yet, play is valid
self.grid[i][col] = self.current_player # If play validm update position with the number of the current player
if self.check_won(col, self.grid[i], 6 + i): # Check if there is a winner
self.ongoing = False # If yes, update the attribute saying the game is over
return f"Player {self.current_player} wins!"
self.current_player = "1" if self.current_player == "2" else "2" # Update the current player
self.next_player = "1" if self.next_player == "2" else "2" # Update the next player
break # No need to loop if the play is already done
i -= 1 # Prevent infinite loop
for row in self.grid: # Display state of grid after move
print(row)
return f"Player {self.next_player} has a turn"
connect = Connect4() # Instantiate the class Connect4
print(connect.play(6)) # play in column 6
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment