Skip to content

Instantly share code, notes, and snippets.

@SyntaxError843
Last active October 14, 2021 07:18
Show Gist options
  • Save SyntaxError843/08f52a20c355dbc31351a3db6ce2245d to your computer and use it in GitHub Desktop.
Save SyntaxError843/08f52a20c355dbc31351a3db6ce2245d to your computer and use it in GitHub Desktop.
TicTacToe
# Tic Tac Toe
import os;
import random;
import time;
# Initialize player vs bot mode [Make true to play against a very stupid bot]
is_pve = True;
# Initialize rows count
rows_count = 3;
# Initialize cells per row count
cells_per_row = 3;
# Initialize board
board = [ str(x) for x in range( 1, (rows_count * cells_per_row + 1) ) ];
# Initialize players
players = [
'X',
'O',
];
# Initialize current player
current_player = players[0];
# Initialize bot player [bot is player 'O']
bot_player = players[1];
# Register a move on the board
def board_make_move( position:str ) :
# Get list of available spaces
available_spaces = [ x for x in board if x.isdigit() ];
# Check if the position is available on the board
if ( position in available_spaces ) :
board[ int(position) - 1 ] = current_player;
return True;
else :
return False;
# Bot AI
def bot_bust_a_move() :
# Flag to check if bot already made a move
bot_already_made_move = False;
# Get opponenet player
opponent_player = players[ 0 if bot_player == players[1] else 1 ];
# Get list of available spaces
available_spaces = [ x for x in board if x.isdigit() ];
# Get list of preferred spaces
preferred_spaces = [ '1', '3', '5', '7', '9' ];
# If the player is about to win attempt to stop them
# And if the bot is about to win then tell it
# In Rows
for i in range( rows_count ) :
current_row = board[ (i*3):(i*3+3) ];
if ( len( [ x for x in current_row if x == opponent_player ] ) == 2 and not bot_already_made_move ) :
bot_already_made_move = board_make_move( [ x for x in current_row if x != opponent_player ][0] );
elif ( len( [ x for x in current_row if x == bot_player ] ) == 2 and not bot_already_made_move ) :
bot_already_made_move = board_make_move( [ x for x in current_row if x != bot_player ][0] );
# In Columns
for i in range( cells_per_row ) :
current_column = [ board[i], board[i+3], board[i+6] ];
if ( len( [ x for x in current_column if x == opponent_player ] ) == 2 and not bot_already_made_move ) :
bot_already_made_move = board_make_move( [ x for x in current_column if x != opponent_player ][0] );
elif ( len( [ x for x in current_column if x == bot_player ] ) == 2 and not bot_already_made_move ) :
bot_already_made_move = board_make_move( [ x for x in current_column if x != bot_player ][0] );
# Diagonals
first_diagonal = [ board[0], board[4], board[8] ];
second_diagonal = [ board[2], board[4], board[6] ];
for diagonal in [ first_diagonal, second_diagonal ] :
if ( len( [ x for x in diagonal if x == opponent_player ] ) == 2 and not bot_already_made_move ) :
bot_already_made_move = board_make_move( [ x for x in diagonal if x != opponent_player ][0] );
elif ( len( [ x for x in diagonal if x == bot_player ] ) == 2 and not bot_already_made_move ) :
bot_already_made_move = board_make_move( [ x for x in diagonal if x != bot_player ][0] );
# Next if the player isn't about to win then check if a preferred space is available
if not bot_already_made_move :
# Priorities the middle spot
if ( '5' in available_spaces ) : bot_already_made_move = board_make_move( '5' );
# Otherwise pick a preferred spot randomly
else : bot_already_made_move = board_make_move( preferred_spaces[ random.randint(0, len(preferred_spaces)-1) ] );
# Lastly if the bot still haven't made a move yet then make one randomly
if not bot_already_made_move : bot_already_made_move = board_make_move( available_spaces[ random.randint(0, len(available_spaces)-1) ] );
# Method to check if it's the bots turn
def is_bot_turn() :
return is_pve and current_player == bot_player;
# Function to clear console
clear_console = lambda: os.system('cls' if os.name in ('nt', 'dos') else 'clear');
# Function to switch between players
def switch_player() :
global current_player;
current_player = players[ 1 if players.index( current_player ) == 0 else 0 ];
# Method to print title
def print_title() :
print( '-'*5 + ' TIC TAC TOE ' + '-'*5 + '\n' );
# Function to draw board
def draw_board() :
# Loop through rows
for row in range( rows_count ) :
# Print a whitespace at the beginning of the line
print( ' ', end='' );
# Loop through cells
for cell in range( cells_per_row ) :
# print cell with right border if cell is not the last one
print( board[ cell + ( row * cells_per_row ) ] + ( ' | ' if cell < (cells_per_row - 1) else '' ), end='' );
# At the end of a row print a line of separators
# If the row is not the last one
# Otherwise print new line
if ( row < ( rows_count - 1 ) ) : print( '\n' + '-'*(3 * cells_per_row + (cells_per_row-1)) );
else : print( '\n' );
# Display results
def print_results() :
# Initialize display text
display_text = '';
# Initialize bot text
bot_text = ' [BOT]' if is_bot_turn() else '';
# If the game is over then display winner
if ( is_game_over() == True ) :
display_text = f'\'{current_player}\'{bot_text} Has Won!';
# Check if game is tied
elif ( is_game_over() == 'tie' ) :
display_text = 'TIE!';
# Otherwise show current player
else : display_text = f'Current Player: \'{current_player}\'{bot_text}';
print( display_text + '\n' );
# Get user input
def get_user_input() :
# Check if it's the bots' turn
if not is_bot_turn() :
# Get user input
user_input = input( 'Input a position on the board: ' );
# Validate user input and register move
while( not board_make_move( user_input ) ) :
user_input = input( 'Please enter a number that is on the board: ' );
else :
# Update the board for the bot with a delay
print( 'The bot is thinking (he\'s very stupid)...' );
time.sleep(1);
bot_bust_a_move();
# Switch current player if game is not over
if not is_game_over() : switch_player();
# Method to determine is game is over
def is_game_over() :
# Initialize game over flag
is_game_over = False;
# A TicTacToe game is completed when a player symbol is
# Place on three aligning spaces on the board whether
# Horizontally, Vertically, Or Diagonally
if (
all( symbol == board[0] for symbol in board[ :3 ] )
or all( symbol == board[3] for symbol in board[ 3:6 ] )
or all( symbol == board[6] for symbol in board[ 6:9 ] )
or (
( board[0] == board[3] and board[0] == board[6] )
or ( board[1] == board[4] and board[1] == board[7] )
or ( board[2] == board[5] and board[2] == board[8] )
)
or (
( board[0] == board[4] and board[0] == board[8] )
or ( board[2] == board[4] and board[2] == board[6] )
)
) : is_game_over = True;
else :
# Check if game is tied
is_game_over = 'tie' if all( symbol.isalpha() for symbol in board ) else False;
return is_game_over;
# Method to display game interface
def start_game() :
while ( True ) :
# Clear console
clear_console();
# Display title
print_title();
# Draw the board with results
draw_board();
# Display results
print_results();
# Get user input if game is not over yet
if ( not is_game_over() ) :
# Get user input
get_user_input();
else :
# Break if the game is over
break;
# Start game
start_game();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment