Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class State(object):
- X = 'X'
- O = 'O'
- NULL = '-'
- def __init__(self, row1=None, row2=None, row3=None):
- self.rows = [row or [self.NULL]*3 for row in [row1, row2, row3]]
- self.turn = self.O
- @property
- def horizontal_rows(self):
- return self.rows
- @property
- def vertical_rows(self):
- return [[c1, c2, c3] for c1, c2, c3 in zip(*self.rows)]
- @property
- def diagonal_forward(self):
- return [r[i] for i, r in enumerate([list(reversed(r)) for r in self.rows])]
- @property
- def diagonal_backward(self):
- return [row[index] for index, row in enumerate(self.rows)]
- def is_won(self):
- for win_case in [*self.horizontal_rows, *self.vertical_rows, self.diagonal_forward, self.diagonal_backward]:
- if self.NULL not in win_case and len(set(win_case)) == 1:
- return set(win_case)
- def is_full(self):
- for row in self.horizontal_rows + self.vertical_rows:
- if any([item == self.NULL for item in row]):
- return False
- return True
- def space_occupied(self, row, column):
- return self.rows[row][column] in [self.X, self.O]
- def add_move(self, row, column):
- self.rows[row][column] = self.turn
- self.turn = self.X if self.turn == self.O else self.O
- def __repr__(self):
- formatted = [str(index or '>') + ' ' +' ' .join(row) for index, row in enumerate([[str(f) for f in range(1,4)]] + self.rows)]
- return '\t'+'\n\t'.join(formatted)
- class Game(object):
- def __init__(self):
- print('Welcome to Tic Tac Toe! When playing your turn, input a column and row (starting top left) e.g. - 1 2 (values between 1-3)')
- self.state = State()
- def run(self):
- while not self.state.is_won() and not self.state.is_full():
- print('\nThe Board is:\n\n%s\n' % repr(self.state))
- self.state.add_move(*self.get_input())
- if self.state.is_full() and not self.state.is_won():
- print('Tie game:\n%s' % repr(self.state))
- else:
- print('Congrats %r, you won!:\n%s' % (self.state.is_won(), repr(self.state)))
- def get_input(self):
- row_input = None
- while not self.validate_input(row_input):
- message = '%rs turn: ' % self.state.turn
- row_input = [item - 1 for item in reversed([int(x) for x in input(message).split()])]
- return row_input
- def validate_input(self, player_input):
- if isinstance(player_input, list) and len(player_input) == 2 and all([0 <= n <= 2 for n in player_input]):
- if not self.state.space_occupied(*player_input):
- return True
- return False
- if __name__ == '__main__':
- Game().run()
Add Comment
Please, Sign In to add comment