Skip to content

Instantly share code, notes, and snippets.

@hdorothea
Created August 21, 2016 02:16
Show Gist options
  • Save hdorothea/8cc12bb6c98765071d7ffbcf62b7c741 to your computer and use it in GitHub Desktop.
Save hdorothea/8cc12bb6c98765071d7ffbcf62b7c741 to your computer and use it in GitHub Desktop.
A simple tic-tac-toe game in Python
import itertools
class Board(object):
def __init__(self):
self.rows = [[' ', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
@property
def diagonals(self):
return [[self.rows[0][0], self.rows[1][1], self.rows[2][2]],
[self.rows[0][2], self.rows[1][1], self.rows[2][0]]]
@property
def columns(self):
return map(list, zip(*self.rows))
def __str__(self):
return " a b c\n0 {}\n1 {}\n2 {}".format(' '.join(self.rows[0]),
' '.join(self.rows[1]),
' '.join(self.rows[2]))
def update_board(board, player, coordinates):
board.rows[coordinates[0]][coordinates[1]] = player
def check_win(board):
lines = board.rows + board.columns + board.diagonals
for line in lines:
if (all(board_position == 'X' for board_position in line) or
all(board_position == 'O' for board_position in line)):
return True
def parse_coordinates(input_coordinates, board):
letters_to_numbers = {'a': 0, 'b': 1, 'c': 2}
try:
coordinates = (int(input_coordinates[0]),
letters_to_numbers[input_coordinates[1]])
except (ValueError, KeyError):
coordinates = (int(input_coordinates[1]),
letters_to_numbers[input_coordinates[0]])
if (coordinates[0] > (len(board.rows) - 1)):
raise ValueError('Out of bound coordinates')
if board.rows[coordinates[0]][coordinates[1]] != ' ':
raise ValueError('Duplicate coordinates')
return coordinates
def play():
board = Board()
players = itertools.cycle(['X', 'O'])
for x in range(9):
player = players.next()
print board
print ('Player-{} please enter the coordinates for your move'
.format(player))
while True:
try:
input_coordinates = raw_input()
coordinates = parse_coordinates(input_coordinates, board)
except (ValueError, IndexError, KeyError):
print 'The coordinates you entered are not valid. Re-enter.'
continue
break
update_board(board, player, coordinates)
if x > 5:
if check_win(board):
print 'Player-{} won!'.format(player)
return
print 'The game ended in a draw'
if __name__ == '__main__':
play()
import unittest
from tictactoe import Board, update_board, check_win, parse_coordinates
class TicTacTest(unittest.TestCase):
def test_board_columns(self):
board = Board()
board.rows = [['00', '01', '02'],
['10', '11', '12'],
['20', '21', '22']]
expected_columns = [['00', '10', '20'],
['01', '11', '21'],
['02', '12', '22']]
self.assertEqual(expected_columns, board.columns)
def test_board_diagonals(self):
board = Board()
board.rows = [['00', '01', '02'],
['10', '11', '12'],
['20', '21', '22']]
expected_diagonals = [['00', '11', '22'], ['02', '11', '20']]
self.assertEqual(expected_diagonals, board.diagonals)
def test_update_board(self):
board = Board()
update_board(board, 'X', (1, 1))
expected_rows_columns = [[' ', ' ', ' '],
[' ', 'X', ' '],
[' ', ' ', ' ']]
expected_diagonals = [[' ', 'X', ' '], [' ', 'X', ' ']]
self.assertEqual(expected_rows_columns, board.columns)
self.assertEqual(expected_rows_columns, board.rows)
self.assertEqual(expected_diagonals, board.diagonals)
def test_check_column_win(self):
board = Board()
board.rows = [['X', ' ', ' '], ['X', ' ', ' '], ['X', ' ', ' ']]
self.assertTrue(check_win(board))
def test_check_row_win(self):
board = Board()
board.rows = [['X', 'X', 'X'], [' ', ' ', ' '], [' ', ' ', ' ']]
self.assertTrue(check_win(board))
def test_check_first_diagonal_win(self):
board = Board()
board.rows = [['X', ' ', ' '], [' ', 'X', ' '], [' ', ' ', 'X']]
self.assertTrue(check_win(board))
def test_check_second_diagonal_win(self):
board = Board()
board.rows = [[' ', ' ', 'X'], [' ', 'X', ' '], ['X', ' ', ' ']]
self.assertTrue(check_win(board))
def test_parse_coordinates(self):
board = Board()
input_coordinates_1 = '1b'
input_coordinates_2 = 'b1'
expected_parsed_coordinates = (1, 1)
self.assertEqual(expected_parsed_coordinates,
parse_coordinates(input_coordinates_1, board))
self.assertEqual(expected_parsed_coordinates,
parse_coordinates(input_coordinates_2, board))
def test_parse_duplicate_coordinates(self):
board = Board()
board.rows = [['X', ' ', ' '], [' ', ' ', ' '], [' ', ' ', ' ']]
self.assertRaises(ValueError, parse_coordinates, '0a', board)
def test_parse_outofbound_coordinates(self):
board = Board()
self.assertRaises(ValueError, parse_coordinates, '0d', board)
if __name__ == '__main__':
unittest.main()
@0204pavan
Copy link

Can we run the unit test code for testing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment