Skip to content

Instantly share code, notes, and snippets.

@msyvr
Last active October 4, 2021 08:10
Show Gist options
  • Save msyvr/5bfc3f552beb66623f5a00d129bb977d to your computer and use it in GitHub Desktop.
Save msyvr/5bfc3f552beb66623f5a00d129bb977d to your computer and use it in GitHub Desktop.
recurse-center--post-pairing-tictactoe-w-computer-random-choices
from hrplayers_ttt import hPlayer, rPlayer
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:
if symbol == 'x':
current_player = player_x
else:
current_player = player_o
# display a fresh game board with IDs for plays
game.show_nums_board()
# display the current plays
choice = current_player.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 # this return associates with the function that it's wrapped in, which is play() and, thus, the interpreter doesn't make it to the tie declaration just after the current while loop
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 = rPlayer('o')
game = Tictactoe()
play(game, player_x, player_o)
import random
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
class rPlayer(Player):
def __init__(self, symbol):
super().__init__(symbol)
def take_turn(self, game):
# choose a random available spot
choice = random.choice(game.avail_spots)
return choice
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment