Skip to content

Instantly share code, notes, and snippets.

@robinovitch61
Created April 27, 2019 02:16
Show Gist options
  • Save robinovitch61/871ad66641811d16bcc2a7f49b5e6050 to your computer and use it in GitHub Desktop.
Save robinovitch61/871ad66641811d16bcc2a7f49b5e6050 to your computer and use it in GitHub Desktop.
RecurseTacToe
# IDEAS FOR COMPUTERIZED OPPONENT:
# [] Add prompt for 1 Player or 2 Player at start of game
# [] Based on number of players, override player selection with random computer selection
# [] Once random selection is working, add more intelligent computer selection (some ideas):
# * If computer could win game, it should win game
# * If computer can put board in state where next move it could win game, it should do that move
# * If computer can put board in state where next move it could win game REGARDLESS of human selection, do that move
# * Apply deep learning on millions of games of tic tac toe to become the ultimate RecurseTacToe algorithm (just kidding :D)
BOARD_TEMPLATE = '''
{top_left} | {top_middle} | {top_right}
-----------
{middle_left} | {center} | {middle_right}
-----------
{bottom_left} | {bottom_middle} | {bottom_right}
'''
# Dictionary containing current state of the board
board_state = {
'top_left':' ',
'top_middle':' ',
'top_right':' ',
'middle_left':' ',
'center':' ',
'middle_right':' ',
'bottom_left':' ',
'bottom_middle':' ',
'bottom_right':' ',
}
# Define all the winning combinations
winning_combinations = (
# left to rights
('top_left', 'top_middle', 'top_right'),
('middle_left', 'center', 'middle_right'),
('bottom_left', 'bottom_middle', 'bottom_right'),
# top to bottoms
('top_left', 'middle_left', 'bottom_left'),
('top_middle', 'center', 'bottom_middle'),
('top_right', 'middle_right', 'bottom_right'),
# diagonals
('top_left', 'center', 'bottom_right'),
('top_right', 'center', 'bottom_left'),
)
def get_player_symbols():
"""Prompt for symbol selection.
Args:
None
Returns:
dict: mapping of player name ('Player 1' or 'Player 2') to symbol ('X' or 'O')
"""
p1_symbol = None
while p1_symbol not in ('X', 'O'):
p1_symbol = input("Player 1, type your symbol! X's or O's: ").upper()
if p1_symbol not in ('X', 'O'):
print("\nInvalid Choice: Please type either X's or O's.")
p2_symbol = 'O' if p1_symbol == 'X' else 'X'
print("Player 1 selected {}'s! That makes Player 2 {}'s.".format(p1_symbol, p2_symbol))
player_dict = {'Player 1':p1_symbol, 'Player 2':p2_symbol}
return player_dict
def get_open_spots():
"""Get the open spaces on the board given current board state.
Args:
None
Returns:
tuple: open space options
"""
return tuple([k.replace('_', ' ') for k,v in board_state.items() if v == ' '])
def is_game_over():
"""Check if game is over.
Args:
None
Returns:
bool: True if game over, False if game shall continue
"""
return not bool(len(get_open_spots()))
def won_game():
"""Check if game has a winner.
Args:
None
Returns:
str or None: if winner exists, returns winner name ('Player 1' or 'Player 2')
else returns None
"""
for player, symbol in player_dict.items():
for combination in winning_combinations:
if (
board_state[combination[0]] == symbol
and board_state[combination[1]] == symbol
and board_state[combination[2]] == symbol
):
return player
return None
def play_turn(whos_turn):
"""Plays turn of tic tac toe and updates board_state.
Args:
whos_turn (str): name of player whos turn it is ('Player 1' or 'Player 2')
Returns:
None
"""
available = get_open_spots()
selection = None
while selection not in available:
current_board = BOARD_TEMPLATE.format(**board_state)
if len(available) == 1:
print('Last available option is {}!'.format(available[0]))
selection = available[0]
break
selection = input("\n{}'s turn ({}'s). Please type one of the following options:\n\n * {}\n{}\n{} ({}'s): ".format(
whos_turn,
player_dict[whos_turn],
'\n * '.join(available),
current_board,
whos_turn,
player_dict[whos_turn])).replace("'","")
if selection not in available:
print('Invalid or unavailable selection!')
board_state[selection.replace(' ', '_')] = player_dict[whos_turn]
print(BOARD_TEMPLATE.format(**board_state))
return 'Player 2' if whos_turn == 'Player 1' else 'Player 1'
# Play game via command line
if __name__ == '__main__':
print('\n%%%%%%%%%%%%%%%%%%%%%%%%%%%')
print(' Welcome to RecurseTacToe! ')
print('%%%%%%%%%%%%%%%%%%%%%%%%%%%\n')
player_dict = get_player_symbols()
winner = None
whos_turn = 'Player 1'
while not is_game_over() and not winner:
whos_turn = play_turn(whos_turn)
winner = won_game()
if winner:
print("{} ({}'s) won! Nice job!".format(winner, player_dict[winner]))
else:
print("Tie game!")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment