Created
August 13, 2020 11:52
-
-
Save rubenhorn/e0c758caf205d4879436836d1f86dbd3 to your computer and use it in GitHub Desktop.
Simple TicTacToe game written in python
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
#!/usr/bin/env python3 | |
import os, re, random | |
clear = lambda: os.system('cls' if os.name == 'nt' else 'clear') | |
def print_header(): | |
print(' _____ _ _____ _____ ') | |
print(' |_ _(_)_|_ _|_ _ _|_ _|__ ___ ') | |
print(' | | | / _|| |/ _` / _|| |/ _ \/ -_)') | |
print(' |_| |_\__||_|\__,_\__||_|\___/\___|') | |
print() | |
def get_player_move(player): | |
print('player {} move (x, y):'.format(player), end='') | |
raw_input = input() | |
try: | |
m = re.match(r'\(\s*(\d+)\s*,\s*(\d+)\s*\)', raw_input) | |
return tuple([int(s) - 1 for s in m.groups()])[::-1] # Reversed | |
except Exception: | |
return None | |
def get_available_moves(state): | |
moves = [] | |
for row_index in range(len(state)): | |
for col_index in range(len(state[0])): | |
if state[row_index][col_index] == 0: | |
moves.append((row_index, col_index)) | |
return moves | |
def has_player_won(state, player): | |
for row_index in range(len(state)): | |
line = 0 | |
for col_index in range(len(state[0])): | |
if state[row_index][col_index] == player: | |
line += 1 | |
if line == 3: | |
return True | |
for col_index in range(len(state[0])): | |
line = 0 | |
for row_index in range(len(state)): | |
if state[row_index][col_index] == player: | |
line += 1 | |
if line == 3: | |
return True | |
if state[0][0] == player and state[1][1] == player and state[2][2] == player: | |
return True | |
if state[0][2] == player and state[1][1] == player and state[2][0] == player: | |
return True | |
return False | |
def print_game(state): | |
print(' x: 1 2 3\n\ry:') | |
first_column = ['1', '2', '3'] | |
for row in state: | |
print(first_column.pop(0) + ' |', end='') | |
for cell in row: | |
cell_state = ' ' | |
if cell == 1: | |
cell_state = 'x' | |
elif cell == 2: | |
cell_state = 'o' | |
print(cell_state + '|', end='') | |
print() | |
def bot_random(state): | |
return random.choice(get_available_moves(state)) | |
def get_player_current_turn(state): | |
player_1_moves = 0 | |
player_2_moves = 0 | |
for row in state: | |
for cell in row: | |
if cell == 1: | |
player_1_moves += 1 | |
elif cell == 2: | |
player_2_moves += 1 | |
return 1 if player_1_moves == player_2_moves else 2 | |
def human_player(state): | |
is_input_valid = True | |
while True: | |
clear() | |
print_header() | |
print_game(state) | |
if not is_input_valid: | |
print('\n\rinvalid move!') | |
else: | |
print('\n') | |
player = get_player_current_turn(state) | |
move = get_player_move(player) | |
if move is None or move not in get_available_moves(state): | |
is_input_valid = False | |
else: | |
return move | |
def exit_with_message(state, message): | |
clear() | |
print_header() | |
print_game(state) | |
print('\n') | |
print(message) | |
input() | |
clear() | |
exit() | |
def handle_game_over(state): | |
if has_player_won(state, 1): | |
exit_with_message(state, 'player 1 wins!') | |
elif has_player_won(state, 2): | |
exit_with_message(state, 'player 2 wins!') | |
elif len(get_available_moves(state)) == 0: | |
exit_with_message(state, 'draw!') | |
def update_game(state, move, player): | |
updated_state = state | |
updated_state[move[0]][move[1]] = player | |
handle_game_over(updated_state) | |
return updated_state | |
try: | |
player_1 = human_player | |
player_2 = bot_random | |
clear() | |
state = [[0, 0, 0], [0, 0, 0], [0, 0, 0]] | |
while True: | |
move = player_1(state) | |
state = update_game(state, move, 1) | |
move = player_2(state) | |
state = update_game(state, move, 2) | |
except KeyboardInterrupt: | |
clear() | |
exit() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment