Last active
September 17, 2021 04:29
-
-
Save msyvr/4f4339e7f0165ff60c669d2634742e00 to your computer and use it in GitHub Desktop.
recurse-center--pairing--tictactoe
This file contains 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
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) |
This file contains 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 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