Though not related to data analysis or visualization, the very basic Tic-Tac-Toe game I made while leaning was my favorite project so far. My kids and I have have had so much fun playing and enjoyed watching them go from losses to wins and then constantly to ties as they learnt the rules, applied them, and kept track of them. When, I have a chance in the future, I plan to return to this project to retrieve inputs, create profiles, keep historical track of scores, have a better user interface, and add sounds for the kids.
I started first by defining the board on which the game will be played.
board = ["-", "-", "-",
"-", "-", "-",
"-", "-", "-"]
And then, I wrote a parameter that that will be True when the game is ongoing. The will be set to None when the game starts and in a very simplistic way, the first player will always be "X".
# If game is still going
game_still_going = True
# Who Won? Or Tie?
winner = None
# Who's turn is it
current_player = "X"
# When I have a chance to go back to update this project, I will probably use inputs and players' name.
Next, I wrote a function that will display the board. I added a static help guide on the side to display the digits number on the board.
def display_board():
print("\n")
print(" | " + board[0] + " | " + board[1] + " | " + board[2] + " | " + " | 1 | 2 | 3 |")
print(" | " + board[3] + " | " + board[4] + " | " + board[5] + " | " + " ---> | 4 | 5 | 6 |")
print(" | " + board[6] + " | " + board[7] + " | " + board[8] + " | " + " | 7 | 8 | 9 |")
print("\n")
Next, I create the function that will run the game itself.
def play_game():
display_board() # Display Initial Board
while game_still_going:
handle_turn(current_player) # Handle turns between players
check_if_game_over() # Check if the game has ended
flip_player() # Flip to the other player
# The game has ended
if winner == "X" or winner == "O":
print(winner + " won!")
elif winner == None:
print("Oh, oh, that's a tie.")
Next, I defined the handle_turn() function defined in the play_game() function.
def handle_turn(current_player):
# Get position from player
print(current_player + "'s turn.")
position = input("Choose a position from 1-9: ")
# Whatever the user inputs, make sure it is a valid input, and the spot is open
valid = False
while not valid:
# Make sure the input is valid
while position not in ["1", "2", "3", "4", "5", "6", "7", "8", "9"]:
position = input("Choose a position from 1-9: ")
# The issue with only the if statement is that it asks only once. Error after another wrong input.
# While loop will go over and over again.
# Get correct index in our board list
position = int(position) - 1
# Then also make sure the spot is available on the board
if board[position] == "-":
valid = True
# So we can jump out of the While Loop and proceed to board[position] = current_player
else:
print("Sorry, you can't go there. Try again please.")
# It will go back to the While Loop
# Put the game piece on the board
board[position] = current_player
# Show the game board
display_board()
Next, I defined the functions that will check whether whether the game is over, either a player win, or there is a tie when all spots are filled with no winner.
def check_if_game_over():
# Here you call in two other functions
check_if_win()
check_if_tie()
def check_if_tie():
global game_still_going
# Check if all cells filled with no winner
if "-" not in board:
game_still_going = False
return
def flip_player():
global current_player
# Change player after one input their choice
if current_player == "X":
current_player = "O"
elif current_player == "O":
current_player = "X"
return
def check_if_win():
# Set up Global Variable
global winner
# Check Rows
row_winner = check_rows()
# Check Columns
column_winner = check_columns()
# Check Diagonal
diagonal_winner = check_diagonals()
if row_winner:
# There is a win
winner = row_winner
elif column_winner:
# There is a win
winner = column_winner
elif diagonal_winner:
# THere is a win
winner = diagonal_winner
else:
# There is no win
winner = None
return
Next, I defined the functions to check ways a player can win.
def check_rows():
# Set up global variables
global game_still_going
row1 = board[0] == board[1] == board[2] != "-"
row2 = board[3] == board[4] == board[5] != "-"
row3 = board[6] == board[7] == board[8] != "-"
# End game if win
if row1 or row2 or row3:
game_still_going = False
print("game over!")
# Get the winner
if row1:
return board[0]
elif row2:
return board[3]
elif row3:
return board[6]
return
def check_columns():
# Set up global variables
global game_still_going
column1 = board[0] == board[3] == board[6] != "-"
column2 = board[1] == board[4] == board[7] != "-"
column3 = board[2] == board[5] == board[8] != "-"
# End game if win
if column1 or column2 or column3:
game_still_going = False
# Get the winner
if column1:
return board[0]
elif column2:
return board[1]
elif column3:
return board[2]
return
def check_diagonals():
# Set up global variables
global game_still_going
diagonal1 = board[0] == board[4] == board[8] != "-"
diagonal2 = board[2] == board[4] == board[6] != "-"
# End game if win
if diagonal1 or diagonal2:
game_still_going = False
# Get the winner
if diagonal1:
return board[0]
elif diagonal2:
return board[2]
return
play_game()