Skip to content

Instantly share code, notes, and snippets.

@msyvr
Last active September 17, 2021 04:29
Show Gist options
  • Save msyvr/4f4339e7f0165ff60c669d2634742e00 to your computer and use it in GitHub Desktop.
Save msyvr/4f4339e7f0165ff60c669d2634742e00 to your computer and use it in GitHub Desktop.
recurse-center--pairing--tictactoe
from player_ttt import hPlayer
class Tictactoe:
# The tictactoe game board spot IDs will be:
# 0 1 2
# 3 4 5
# 6 7 8
def __init__(self):
# list of all spots in the game, mapping 0 thru 8 to spots on the 3x3 board
self.spot_ids = [i for i in range(9)]
# record of board spot values reflecting which player occupies a spot, and with a space representing an empty/available spot
self.spot_vals = [' ' for i in range(len(self.spot_ids))]
# reference list of available spots
self.avail_spots = [spot for spot, val in enumerate(self.spot_vals) if val == ' ']
# set winner to none; if there's a winner, update with winning player's symbol
self.winner = None
# set up a reference board showing IDs associated with spots on the gameboard
def show_nums_board(self):
count = 0
# loop through each of n rows on the gameboard then print as:
# | rn,c1 | rn,c2 | rn,c3 |
# first, generate array board_rows where the rows are: [0, 1, 2], [3, 4, 5], [6, 7, 8]
board_rows = [[str(self.spot_ids[i]) for i in range(k*3, (k+1)*3)]for k in range(3)]
for row in board_rows:
print('| '+ ' | '.join(row) + ' |')
if count < 2:
print('---------------')
count += 1
else:
print('\n')
# set up a play reference board reflecting the current state of the game
def show_current_board(self):
count = 0
# loop through each of n rows on the gameboard then print as:
# | rn,c1 | rn,c2 | rn,c3 |
# first, generate array board_rows where the rows are: [spot_vals(r0,c0), spot_vals(r0,c1), spot_vals(r0,c2)], etc thru to r=2
current_rows = [[self.spot_vals[i] for i in range(k*3, (k+1)*3)] for k in range(3)]
for row in current_rows:
print('| ' + ' | '.join(row) + ' |')
if count < 2:
print('---------------')
count += 1
else:
print('\n')
def winner_check(self, choice, symbol):
# check if row associated with choice is a winner for symbol
choice_row = choice//3
choice_row_vals = self.spot_vals[choice_row*3:(choice_row+1)*3]
if all([val == symbol for val in choice_row_vals]):
print(f'We have a winner! {symbol} takes the game with a row!')
self.winner = symbol
return
# check if col associated with choice is a winner for symbol
choice_col = choice%3
choice_col_vals = [self.spot_vals[choice_col+(i*3)] for i in range(3)]
if all([val == symbol for val in choice_col_vals]):
print(f'We have a winner! {symbol} takes the game with a column!')
self.winner = symbol
return
# check if diag is winner for symbol
diag_vals = [self.spot_vals[0], self.spot_vals[4], self.spot_vals[8]]
if all([val == symbol for val in diag_vals]):
print(f'We have a winner! {symbol} takes the game on a diagonal!')
self.winner = symbol
return
# check if antidiag is winner for symbol
adiag_vals = [self.spot_vals[2], self.spot_vals[4], self.spot_vals[6]]
if all([val == symbol for val in adiag_vals]):
print(f'We have a winner! {symbol} takes the game on a diagonal!')
self.winner = symbol
return
def play(game, player_x, player_o):
symbol = input('Who goes first? x or o: ').lower()
while symbol != 'x' and symbol != 'o':
symbol = input('Who goes first? Must choose either x or o: ').lower()
# while there are still available spots on the board
while len(game.avail_spots) > 0 and game.winner == None:
# display a fresh game board with IDs for plays
game.show_nums_board()
# display the current plays
choice = int(hPlayer(symbol).take_turn(game))
# update the board spot value
game.spot_vals[choice] = symbol
# update the available choices
game.avail_spots.remove(choice)
# display the updated current plays
game.show_current_board()
# check if this move produced a win: yes? declare winner, exit game
game.winner_check(choice, symbol)
# select next player
if game.winner != None:
return # return associates with the wrapping function (here: play())
symbol = 'x' if symbol == 'o' else 'o'
# declare a tie
print('Tie! Everyone\'s a winner :)')
if __name__ == "__main__":
player_x = hPlayer('x')
player_o = hPlayer('o')
game = Tictactoe()
play(game, player_x, player_o)
class Player:
def __init__(self, symbol):
self.symbol = symbol
def take_turn(self, game):
# pass lets us define take_turn differently for different player types that inherit from the Player class
pass
class hPlayer(Player):
def __init__(self, symbol):
super().__init__(symbol)
def take_turn(self, game):
choice = int(input('Player ' + self.symbol + ', choose your next spot (by id #): '))
while choice not in game.avail_spots:
choice = int(input('Available spots only, please! Try again: '))
return choice
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment