Skip to content

Instantly share code, notes, and snippets.

@dissolved
Last active June 11, 2017 13:00
Show Gist options
  • Save dissolved/c2878c6477f8658711186e7d970c31ae to your computer and use it in GitHub Desktop.
Save dissolved/c2878c6477f8658711186e7d970c31ae to your computer and use it in GitHub Desktop.
class Board():
"""A Tic-Tac-Toe board.
Internal representation by 1-dimensional list visualized as:
0 | 1 | 2
-----------
3 | 4 | 5
-----------
6 | 7 | 8
"""
win_combos = ((0, 1, 2), (3, 4, 5), (6, 7, 8),
(0, 3, 6), (1, 4, 7), (2, 5, 8),
(0, 4, 8), (2, 4, 6))
def __init__(self):
self.board = list(range(1, 10))
def display(self):
"""Display a text representation of the board."""
representation = '-----------\n'.join([' {} | {} | {} \n']*3)
return representation.format(*self.board)
def winner(self):
"""Return mark of winner, if exists, otherwise return None."""
for cells in Board.win_combos:
if len(set([self.board[i] for i in cells])) == 1:
return self.board[cells[0]]
def open_cells(self):
"""Return a list of available plays."""
return [str(i) for i in self.board if type(i) == int]
def play(self, cell, mark):
"""Place the mark in the specified cell."""
self.board[self.board.index(int(cell))] = mark
from itertools import cycle
from board import Board
import player as plyr
def print_header():
print('------------------------------------------------------------------')
print('--------------------- WELCOME TO TIC-TAC-TOE ---------------------')
print('------------------------------------------------------------------')
def get_players():
x = plyr.Player('X', 'Human')
o = plyr.Computer('O')
return (x, o)
def play_tic_tac_toe():
players = get_players()
board = Board()
for player in cycle(players):
choice = player.prompt(board)
if choice == 'Q':
print("Are we quitting while we're ahead?")
return
else:
board.play(choice, player.mark)
winner = board.winner()
if winner:
board.display()
print('{} wins! Congrats {}!!!'.format(winner, player.name))
break
if not board.open_cells():
board.display()
print('Nobody wins... The only winning move is not to play.')
break
if __name__ == '__main__':
print_header()
play_tic_tac_toe()
import random
class Player:
"""docstring for Player"""
def __init__(self, mark, name=''):
self.name = name
self.mark = mark
def choose_play(self, choices):
human_choices = choices + ['Q']
prompt_str = 'Enter {}: '.format(', '.join(human_choices))
choice = 'none'
while choice not in human_choices:
choice = input(prompt_str).upper()
return choice
def prompt(self, board):
print('\n{}, where do you wish to put your {}?'.format(
self.name, self.mark))
print(board.display())
return self.choose_play(board.open_cells())
class Computer(Player):
"""docstring for Computer"""
def __init__(self, mark):
super(Computer, self).__init__(mark, 'Computer')
def choose_play(self, choices):
choice = str(random.choice(choices))
print('{} chooses {}'.format(self.name, choice))
return choice
from board import Board
import player as plyr
def test_board_displays_new_game():
b = Board()
display = b.display()
expected = ' 1 | 2 | 3 \n-----------\n 4 | 5 | 6 \n-----------\n 7 | 8 | 9 \n'
assert display == expected
def test_computer_makes_selection():
choice = plyr.Computer('X').choose_play([1, 5, 9])
assert choice in ['1', '5', '9']

Todo

  • Write automated tests
  • Improve AI (minmax algorithm)
  • Think about coupling and see if the code can be decoupled cleanly (display vs game logic)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment