Created
April 21, 2019 16:35
-
-
Save avin-sharma/5c0b89699b60529107c37c3613cf224a to your computer and use it in GitHub Desktop.
A simple terminal based 2 player TIC-TAC-TOE
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Terminal TIC-TAC-TOE | |
# Written in Python 3 | |
class Board: | |
def __init__(self, n=3): | |
self.n = n | |
self.state = [[' ' for _ in range(n)] for _ in range(n)] | |
self.active_player = 'X' | |
self.t = 0 | |
self.min_move_before_check = (self.n - 1) * 2 | |
def draw_board(self): | |
n = self.n | |
moves = self.state | |
# Drawing top legend | |
board = '\n ' | |
for i in range (n): | |
board += ' {} '.format(chr(97 + i)) | |
print(board, '\n') | |
for i in range(n*2 - 1): | |
board = '' | |
if i % 2 == 0: | |
row = i//2 | |
board += '{} {} '.format((row + 1), moves[row][0]) # Drawing left legend + first element of the row | |
for j in range(1, n): | |
board += '| {} '.format(moves[row][j]) | |
else: | |
# Drawing divisions | |
board += ' ' | |
board += ' ---' * n | |
print(board) | |
print() | |
# Convert move to numbers (row=0 col=0 to move -> 'a1') | |
def move_to_numbers(self, move): | |
col, row = list(move) | |
col = ord(col) - 97 | |
row = int(row) - 1 | |
return row, col | |
# Convert move to numbers (move-> 'a1' to row=0 col=0) | |
def numbers_to_move(self, row, col): | |
move = chr(97+col-1) + str(row) | |
return move | |
# Check if the tile has not been used/ is empty | |
def is_move_valid(self, row, col): | |
return True if self.state[row][col] == ' ' else False | |
# Play a move | |
def play_move(self): | |
if self.t == 9: | |
return False | |
# If running on windows/cmd remove the ANSI escape sequences, they add color to text. | |
move = input('Enter your move \033[93m\033[1m {} \033[0m: '.format(self.active_player)) | |
# check if nothing has been entered | |
if not move: | |
print("Please play a move!") | |
return True | |
row, col = self.move_to_numbers(move) | |
if self.is_move_valid(row, col): | |
self.state[row][col] = self.active_player | |
self.draw_board() | |
if self.t >= self.min_move_before_check: | |
if self.has_won(row, col): | |
print(self.active_player + ' WINS!') | |
return False | |
self.active_player = 'O' if self.active_player == 'X' else 'X' | |
self.t += 1 | |
else: | |
print("Tile occupied, please play an empty tile!") | |
return True | |
def has_won(self, current_row, current_col): | |
win_arr = [self.active_player for _ in range(self.n)] | |
# Check row win | |
if self.state[current_row] == win_arr: | |
return True | |
# Check col win | |
if [self.state[i][current_col] for i in range(self.n)] == win_arr: | |
return True | |
# Check diag win | |
if current_row == current_col and [self.state[i][i] for i in range(self.n)] == win_arr: | |
return True | |
#Check anti-diag win | |
if current_row + current_col == self.n - 1 and [self.state[i][self.n-i-1] for i in range(self.n)] == win_arr: | |
return True | |
return False | |
# Play the game till someone wins or ends at a draw | |
def play(self): | |
print('\n#########################\n###### TIC TAC TOE ######\n#########################\n') | |
print('Welcome! \nEnter your move in the following format alphabetNUMBER (eg. a1)\n') | |
self.draw_board() | |
while self.play_move(): | |
pass | |
def get_valid_tiles(self, state): | |
tiles = [] | |
for row in state: | |
for col in row: | |
if state[row][col] == ' ': | |
tiles.append((row, col)) | |
return tiles | |
# Play a game | |
board = Board() | |
board.play() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment