I am working on one of my first codes (Tic Tac Toe), and I cannot figure out why I'm getting a name error.
First I have a list (board).
Then I have a function (possible_victory_for() ) that I define. It is supposed to to something with a list (temp_board) that will be defined later, within the next function.
The next function (computer_move() ) says temp_board = board and then calls the possible_victory_for().
In my understanding, seeing as "board" seems to work fine, the temp_board = board should be enough of a definition for temp_board. But Python disagrees.
I tried to recreate the error on a simple example, like this:
board = [1, 2, 3]
temp_board = board
if temp_board[0] == 1:
print("it works")
But this works fine and doesn't produce the error. So maybe it's something related to communication between functions (or simply a typo somewhere)?
As I fail to shorten the code and get the same error, I am attaching everything I made for now. Sorry for a long post.
(if you decide to run the code, go for Medium difficulty, that's where the error happens).
# I need these functions to make everything work
# clear_output was imported by Google Colab, not sure if it's standard
# all mentions of clear_output can be deleted if needed, the code will work
# but it will show every turn made by computer/human, not just the current board
from IPython.core.display import clear_output
from random import randrange
# Sets the board at the beginning
board = [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Just displays the current board
def display_board():
print(
"\n+-------+-------+-------+",
"\n| | | |",
"\n| ",board[0]," | ",board[1]," | ",board[2]," |",
"\n| | | |",
"\n+-------+-------+-------+",
"\n| | | |",
"\n| ",board[3]," | ",board[4]," | ",board[5]," |",
"\n| | | |",
"\n+-------+-------+-------+",
"\n| | | |",
"\n| ",board[6]," | ",board[7]," | ",board[8]," |",
"\n| | | |",
"\n+-------+-------+-------+"
)
# Asks player to define who plays first (human or computer). Impacts the order of turns.
def who_plays_first():
global first_player
while True:
first_player = int(input("Choose who plays first: 1 for human, 2 for computer"))
if first_player == 1 or first_player == 2:
break
print("invalid input, read the instruction")
if first_player == 1:
first_player = "human"
else:
first_player = "computer"
return(first_player)
# Asks player to set difficulty. Impacts how computer decides on its move.
def choose_difficulty():
global difficulty
while True:
difficulty = int(input("Choose difficulty: 1 = easy, 2 = medium, 3 = hard"))
if difficulty == 1 or difficulty == 2 or difficulty == 3:
break
print("invalid input, read the instruction")
if difficulty == 1:
difficulty = "easy"
elif difficulty == 2:
difficulty = "medium"
else:
difficulty = "hard"
return(difficulty)
# Makes a list of free fields. Used in other functions.
def make_list_of_free_fields():
list_of_free_fields = []
for field in range(1,10):
if field in board:
list_of_free_fields.append(field)
return(list_of_free_fields)
# Checks whether the player (defined by the sign) won.
def victory_for(sign):
if (board[0] == sign and board[1] == sign and board[2] == sign or
board[3] == sign and board[4] == sign and board[5] == sign or
board[6] == sign and board[7] == sign and board[8] == sign or
board[0] == sign and board[3] == sign and board[6] == sign or
board[1] == sign and board[4] == sign and board[7] == sign or
board[2] == sign and board[5] == sign and board[8] == sign or
board[0] == sign and board[4] == sign and board[8] == sign or
board[2] == sign and board[4] == sign and board[6] == sign):
return True
else:
return False
# Same as victory_for, but only used to help computer make its move on medium/hard.
def possible_victory_for(sign):
if (temp_board[0] == sign and temp_board[1] == sign and temp_board[2] == sign or
temp_board[3] == sign and temp_board[4] == sign and temp_board[5] == sign or
temp_board[6] == sign and temp_board[7] == sign and temp_board[8] == sign or
temp_board[0] == sign and temp_board[3] == sign and temp_board[6] == sign or
temp_board[1] == sign and temp_board[4] == sign and temp_board[7] == sign or
temp_board[2] == sign and temp_board[5] == sign and temp_board[8] == sign or
temp_board[0] == sign and temp_board[4] == sign and temp_board[8] == sign or
temp_board[2] == sign and temp_board[4] == sign and temp_board[6] == sign):
return True
else:
return False
# Asks the human player to make their move.
def human_move():
while True:
human_input = int(input("Choose a field"))
if human_input in make_list_of_free_fields():
break
print("You must choose one of the free fields on the board by typing 1-9")
board[human_input-1] = "O"
# This is how the computer makes its move.
# Depends on the difficulty.
# Easy is completely random.
# Medium checks whether:
# a) there's a (list of) move(s) that could guarantee computer's victory
# b) there's a (list of) move(s) that could guarantee human's victory
# - then play a random move out of that list (computer victory has priority)
# Hard is yet to be defined.
def computer_move():
if difficulty == "easy":
while True:
computer_input = randrange(10)
if computer_input in make_list_of_free_fields():
break
board[computer_input-1] = "X"
# elif difficulty == "medium":
else:
brings_computer_victory = []
brings_human_victory = []
for field in make_list_of_free_fields():
temp_board = board
temp_move = field
temp_board[temp_move-1] = "X"
if possible_victory_for("X") == True:
brings_computer_victory.append(temp_move)
if brings_computer_victory != []:
computer_input = randrange(1, len(brings_computer_victory) + 1)
board[computer_input-1] = "X"
for field in make_list_of_free_fields():
temp_board = board
temp_move = field
temp_board[temp_move-1] = "O"
if possible_victory_for("O") == True:
brings_human_victory.append(temp_move)
if brings_human_victory != []:
computer_input = randrange(1, len(brings_human_victory) + 1)
board[computer_input-1] = "X"
# This is the final piece of code that connects all the functions.
who_plays_first()
choose_difficulty()
clear_output()
if first_player == "human":
display_board()
while True:
human_move()
clear_output()
display_board()
if victory_for("O") == True:
print("You won!")
break
if len(make_list_of_free_fields()) == 0:
print("it's a tie")
break
computer_move()
clear_output()
display_board()
if victory_for("X") == True:
print("You lost!")
break
else:
while True:
computer_move()
clear_output()
display_board()
if victory_for("X") == True:
print("You lost!")
break
if len(make_list_of_free_fields()) == 0:
print("it's a tie")
break
human_move()
clear_output()
display_board()
if victory_for("O") == True:
print("You won!")
break
Here's the error traceback:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
<ipython-input-11-322daee905b6> in <module>
28
29 while True:
---> 30 computer_move()
31 clear_output()
32 display_board()
1 frames
<ipython-input-10-6530342ed281> in computer_move()
24 temp_move = field
25 temp_board[temp_move-1] = "X"
---> 26 if possible_victory_for("X") == True:
27 brings_computer_victory.append(temp_move)
28 if brings_computer_victory != []:
<ipython-input-8-bd71fed33fb4> in possible_victory_for(sign)
1 # Same as victory_for, but only used to help computer make its move on medium/hard.
2 def possible_victory_for(sign):
----> 3 if (temp_board[0] == sign and temp_board[1] == sign and temp_board[2] == sign or
4 temp_board[3] == sign and temp_board[4] == sign and temp_board[5] == sign or
5 temp_board[6] == sign and temp_board[7] == sign and temp_board[8] == sign or
NameError: name 'temp_board' is not defined
temp_board is local to computer_move, but you're treating it as if it were a global. You should make it a parameter to possible_victory_for:
def possible_victory_for(sign, temp_board):
# if (temp_board[0] ...
and then pass it from computer_move as an argument:
if possible_victory_for("X", temp_board) == True:
In general I'd recommend passing variables to your functions as arguments rather than relying on pulling them implicitly from an outer scope; it makes the dependencies between different parts of your code more obvious (in this case possible_victory_for depends on not only sign but the current values of temp_board), which makes it easier to change and extend.
Related
--------- Global Variables -----------
# Will hold our game board data
board = ["-", "-", "-",
"-", "-", "-",
"-", "-", "-"]
# Lets us know if the game is over yet
game_still_going = True
# Tells us who the winner is
winner = None
# Tells us who the current player is (X goes first)
current_player = "X"
# ------------- Functions ---------------
# Play a game of tic tac toe
def play_game():
# Show the initial game board
display_board()
# Loop until the game stops (winner or tie)
while game_still_going:
# Handle a turn
handle_turn(current_player)
# Check if the game is over
check_if_game_over()
# Flip to the other player
flip_player()
# Since the game is over, print the winner or tie
if winner == "X" or winner == "O":
print(winner + " won.")
elif winner == None:
print("Tie.")
# Display the game board to the screen
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")
# Handle a turn for an arbitrary player
def handle_turn(player):
# Get position from player
print(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: ")
# 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
else:
print("You can't go there. Go again.")
# Put the game piece on the board
board[position] = player
# Show the game board
display_board()
# Check if the game is over
def check_if_game_over():
check_for_winner()
check_for_tie()
# Check to see if somebody has won
def check_for_winner():
# Set global variables
global winner
# Check if there was a winner anywhere
row_winner = check_rows()
column_winner = check_columns()
diagonal_winner = check_diagonals()
# Get the winner
if row_winner:
winner = row_winner
elif column_winner:
winner = column_winner
elif diagonal_winner:
winner = diagonal_winner
else:
winner = None
# Check the rows for a win
def check_rows():
# Set global variables
global game_still_going
# Check if any of the rows have all the same value (and is not empty)
row_1 = board[0] == board[1] == board[2] != "-"
row_2 = board[3] == board[4] == board[5] != "-"
row_3 = board[6] == board[7] == board[8] != "-"
# If any row does have a match, flag that there is a win
if row_1 or row_2 or row_3:
game_still_going = False
# Return the winner
if row_1:
return board[0]
elif row_2:
return board[3]
elif row_3:
return board[6]
# Or return None if there was no winner
else:
return None
# Check the columns for a win
def check_columns():
# Set global variables
global game_still_going
# Check if any of the columns have all the same value (and is not empty)
column_1 = board[0] == board[3] == board[6] != "-"
column_2 = board[1] == board[4] == board[7] != "-"
column_3 = board[2] == board[5] == board[8] != "-"
# If any row does have a match, flag that there is a win
if column_1 or column_2 or column_3:
game_still_going = False
# Return the winner
if column_1:
return board[0]
elif column_2:
return board[1]
elif column_3:
return board[2]
# Or return None if there was no winner
else:
return None
# Check the diagonals for a win
def check_diagonals():
# Set global variables
global game_still_going
# Check if any of the columns have all the same value (and is not empty)
diagonal_1 = board[0] == board[4] == board[8] != "-"
diagonal_2 = board[2] == board[4] == board[6] != "-"
# If any row does have a match, flag that there is a win
if diagonal_1 or diagonal_2:
game_still_going = False
# Return the winner
if diagonal_1:
return board[0]
elif diagonal_2:
return board[2]
# Or return None if there was no winner
else:
return None
# Check if there is a tie
def check_for_tie():
# Set global variables
global game_still_going
# If board is full
if "-" not in board:
game_still_going = False
return True
# Else there is no tie
else:
return False
# Flip the current player from X to O, or O to X
def flip_player():
# Global variables we need
global current_player
# If the current player was X, make it O
if current_player == "X":
current_player = "O"
# Or if the current player was O, make it X
elif current_player == "O":
current_player = "X"
# ------------ Start Execution -------------
# Play a game of tic tac toe
play_game()
So I am trying to write a unit test for this code, so for example I am trying to check the def check_columns() function.
So far I came up with:
import unittest
import Tic_tac_toe
class TestGame(unittest.TestCase):
def test_check_for_column(self):
columns_1 = None
self.assertEqual(Tic_tac_toe.check_columns(), columns_1)
This checks out because initially, there is no input so I get None but I am trying to input "x" in the column and see if it returns the winner. How would I do that?
So basically I am trying to build a Tic-Tac-Toe game with both single and multiplayer difficulty levels but I am stuck on what code should I write for player vs computer and I am stuck in a forever loop in the def play_game() function. I can't keep the previous stats of the game as well. I really need help with this.
# --------- Global Variables -----------
# Will hold our game board data
board = ["-", "-", "-",
"-", "-", "-",
"-", "-", "-"]
# Lets us know if the game is over yet
game_still_going = True
# Tells us who the winner is
winner = None
# Tells us who the current player is (X goes first)
current_player = "X"
# ------------- Functions ---------------
# Play a game of tic tac toe
def play_game():
# Show the initial game board
display_board()
game_on = True
while True:
print("1.Single Player")
print("2.Multiplayer")
print("3.Game Stats")
print("4.Quit")
input_1 = int(input("Please Select An Option"))
if input_1 == "3" :
print('reading database...')
read_log()
elif input_1 == "4" :
exit()
elif input_1 == "2" :
Player_1 = input("Enter First Player Name:")
Player_2 = input("Enter Second Player Name:")
display_board()
while game_on:
position = input("Choose a position from 1-9: ")
check_for_winner()
display_board()
# Loop until the game stops (winner or tie)
while game_still_going:
# Handle a turn
handle_turn(current_player)
# Check if the game is over
check_if_game_over()
# Flip to the other player
flip_player()
# Since the game is over, print the winner or tie
if winner == "X" or winner == "O":
print(winner + " won.")
elif winner == None:
print("Tie.")
# Display the game board to the screen
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")
# Handle a turn for an arbitrary player
def handle_turn(player):
# Get position from player
print(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: ")
# 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
else:
print("You can't go there. Go again.")
# Put the game piece on the board
board[position] = player
# Show the game board
display_board()
# Check if the game is over
def check_if_game_over():
check_for_winner()
check_for_tie()
# Check to see if somebody has won
def check_for_winner():
# Set global variables
global winner
# Check if there was a winner anywhere
row_winner = check_rows()
column_winner = check_columns()
diagonal_winner = check_diagonals()
# Get the winner
if row_winner:
winner = row_winner
elif column_winner:
winner = column_winner
elif diagonal_winner:
winner = diagonal_winner
else:
winner = None
# Check the rows for a win
def check_rows():
# Set global variables
global game_still_going
# Check if any of the rows have all the same value (and is not empty)
row_1 = board[0] == board[1] == board[2] != "-"
row_2 = board[3] == board[4] == board[5] != "-"
row_3 = board[6] == board[7] == board[8] != "-"
# If any row does have a match, flag that there is a win
if row_1 or row_2 or row_3:
game_still_going = False
# Return the winner
if row_1:
return board[0]
elif row_2:
return board[3]
elif row_3:
return board[6]
# Or return None if there was no winner
else:
return None
# Check the columns for a win
def check_columns():
# Set global variables
global game_still_going
# Check if any of the columns have all the same value (and is not empty)
column_1 = board[0] == board[3] == board[6] != "-"
column_2 = board[1] == board[4] == board[7] != "-"
column_3 = board[2] == board[5] == board[8] != "-"
# If any row does have a match, flag that there is a win
if column_1 or column_2 or column_3:
game_still_going = False
# Return the winner
if column_1:
return board[0]
elif column_2:
return board[1]
elif column_3:
return board[2]
# Or return None if there was no winner
else:
return None
# Check the diagonals for a win
def check_diagonals():
# Set global variables
global game_still_going
# Check if any of the columns have all the same value (and is not empty)
diagonal_1 = board[0] == board[4] == board[8] != "-"
diagonal_2 = board[2] == board[4] == board[6] != "-"
# If any row does have a match, flag that there is a win
if diagonal_1 or diagonal_2:
game_still_going = False
# Return the winner
if diagonal_1:
return board[0]
elif diagonal_2:
return board[2]
# Or return None if there was no winner
else:
return None
# Check if there is a tie
def check_for_tie():
# Set global variables
global game_still_going
# If board is full
if "-" not in board:
game_still_going = False
return True
# Else there is no tie
else:
return False
# Flip the current player from X to O, or O to X
def flip_player():
# Global variables we need
global current_player
# If the current player was X, make it O
if current_player == "X":
current_player = "O"
# Or if the current player was O, make it X
elif current_player == "O":
current_player = "X"
def read_log():
log = open('log.txt', 'r')
log.seek(0)
print('\n\n')
print(log.read(),'\n\n')
# ------------ Start Execution -------------
# Play a game of tic tac toe
play_game()
If I understood correctly You can do it like this:
Define functions:
handle_player_move()
handle_computer_move()
as names suggests when you call the function either human player or computer will make a move (make sure that it's certain or add some Errorcodes/Exceptions when player do something unexpected and you want to end program)
Define function:
game_is_over() # returns True if it's the end of game False other wise
Then Your game is just:
Human vs Human:
whos_move = 0 # number of player ( 0 or 1 )
while not game_is_over():
if whos_move == 0:
handle_player_move(player1)
if whos_move == 1:
handle_player_move(player2)
whos_move = (whos_move + 1) % 2
Quite similarly Human vs Bot:
whos_move = 0 # number of player ( 0 or 1 )
while not game_is_over():
if whos_move == 0:
handle_player_move(player1)
if whos_move == 1:
handle_computer_move(player2)
whos_move = (whos_move + 1) % 2
Instead of this you can also check for end of game with your function, and do:
whos_move = 0 # number of player ( 0 or 1 )
while game_still_going:
if whos_move == 0:
handle_player_move(player1)
if whos_move == 1:
handle_computer_move(player2)
whos_move = (whos_move + 1) % 2
check_if_game_over()
if statement: # your ending statement here
game_is_still_going = False
Your method with flip_player() is also good I just put if statements to both so that they are familiar in truth if you would are able to distinguish in handle_turn() between bot and human player you can do it for both cases ;)
As implementing computer moves can be hard here are some tips:
Easiest way you can just randomly choose number between 1 and 9 check if it's unoccupied if it's free computer makes move there if it is not you pick again. Maybe it sounds like being potentially endless loop but statisticly computer shouldn't have any problems with making a move.
You can also create list of free squares and then randomly choose an index (probably better way)
You can also try to add some logic f.e. if there are two in a row block third square.
too choose random integer from given interval you can use:
import random
random.randint(1,9) # choose integer x such that: 1 <= x <= 9
Of course you can and even maybe should use your own function names (name them as you wish!)
Hope that helps, good luck!
I am currently learning python and trying to build a tic tac toe game. I wrote a program to prevent the user repeating the same input but when I repeat the same number two times, the program starts looping continuously without stopping. Could someone give me advice on how to rectify this issue? see below the code:
from tabulate import tabulate
# define the board
board = ["_", "_", "_",
"_", "_", "_",
"_", "_", "_"]
# Current player
current_player = "X"
winner = None
game_still_on = True
def play_game():
while game_still_on:
position()
board_display()
handle_player()
winner_check()
winner_check2()
def handle_player():
global current_player
if current_player == "X":
current_player = "O"
elif current_player == "O":
current_player = "X"
def board_display():
board_row1 = [board[0], board[1], board[2]]
board_row2 = [board[3], board[4], board[5]]
board_row3 = [board[6], board[7], board[8]]
com_board = [board_row1,
board_row2,
board_row3]
print(tabulate(com_board, tablefmt="grid"))
# position input
def position():
global board
print(current_player+"'s turn")
positions = input("enter 1-9")
valid = False
while not valid:
while int(positions) >= 10 or 0 >= int(positions):
positions = input("Choose a position from 1 -9")
positions = int(positions)
if board[positions-1] == "_":
valid = True
else:
print("Choose another")
board[positions - 1] = current_player
def winner_check():
if board[0] == board[1] == board[2] != "_":
return board[0]
elif board[3] == board[4] == board[5] != "_":
return board[3]
elif board[6] == board[7] == board[8] != "_":
return board[6]
elif board[0] == board[3] == board[6] != "_":
return board[0]
elif board[1] == board[4] == board[7] != "_":
return board[1]
elif board[2] == board[5] == board[8] != "_":
return board[2]
elif board[0] == board[4] == board[8] != "_":
return board[0]
elif board[2] == board[4] == board[6] != "_":
return board[1]
else:
return None
def winner_check2():
row_winner = winner_check()
if row_winner:
global game_still_on
global winner
winner = row_winner
print((winner+ " won"))
game_still_on = False
play_game()
Let's look at this function:
# position input
def position():
global board
print(current_player+"'s turn")
positions = input("enter 1-9")
valid = False
while not valid:
while int(positions) >= 10 or 0 >= int(positions):
positions = input("Choose a position from 1 -9")
positions = int(positions)
if board[positions-1] == "_":
valid = True
else:
print("Choose another")
board[positions - 1] = current_player
This has nested validation loops. The inner one checks the range of the input integer (if it is an integer -- otherwise it throws an exception) and requests input until it's in range. That's fine.
Then in the outer validation loop, it checks if the requested space is unoccupied. If so, fine. If not, it prompts the user to choose another. But the input call is before the outer loop, so it just tries again to validate the same input that already failed.
Try moving the input into the outer loop:
# position input
def position():
global board
print(current_player+"'s turn")
valid = False
while not valid:
positions = input("enter 1-9")
while int(positions) >= 10 or 0 >= int(positions):
positions = input("Choose a position from 1 -9")
positions = int(positions)
if board[positions-1] == "_":
valid = True
else:
print("Choose another")
board[positions - 1] = current_player
I'd probably also change the inner loop to be just an if with a continue and make the handling of non-integer input more robust.
I am attempting to prompt the user the option to save the game, after the first move, during gameplay?
After the game is completed I want to prompt the user to reset the game(Y or N) then call the play game function(with a loop)?
However, I am unsure how to organize the code to accomplish these tasks. I am a beginner to python.
def play_game():
game = True
while game == True:
game_choice = menu()
if game_choice == 1:
choice_one()
elif game_choice ==2:
player1VSai()
elif game_choice ==3:
save_and_exit()
elif game_choice==4:
load_game()
#After the game is completed I want to reset the game and call the play game function(with a loop).
# reset_game()
# play_game()
def choice_one():
# Display initial board
display_board()
while game_still_playing:
# handle a single turn of a arbitrary player
handle_turn(current_player)
# check if win or tie
check_if_game_over()
# flip to other player
alternate_player()
# The game has ended
if winner == 'X' or winner == 'O':
print(winner + " won.")
elif winner == None:
print("Tie.")
# handle a single turn of a random player
def handle_turn(player):
print(player + "'s turn.")
position = input("Choose a position from 1 to 9: ")
# I can index into position with int instead of string
valid = False
while not valid:
while position not in ["1", "2", "3", "4", "5", "6", "7", "8", "9"] or position ==0:
position = input("Choose a position from 1-9: ")
if position == 0:
save_and_exit()
pass
# convert from string to int
position = int(position) - 1
if board[position] == '':
valid = True
else:
print("Space filled. Go again.")
# Board at position equals X
board[position] = player
display_board()
print("Press 0 to save & exit game.")
#then if? or loop? prompt user to save game?
For saving code, your Game has things that you should save:
The state of the board, variable player
Whose turn it is, variable
board
This means you would have to write a function that takes these 2 variables as input argument and writes the content to a file.
#Remy this is what I have for the save function,
which I believe works properly as I've saved the data I need.
def save_and_exit():
global current_player
#save and end loop
turn=current_player
option = menu()
file=open("HW3game.txt", "w")
for x in board:
file.write(x)
file.write(turn)
file.write(str(option))
file.close()
print("You have saved the game and exited")
return
import random
# functions
# board
# display board
# ask if you want to be x or O
# menu
# play game
# take input & alternate turns
# check win
# check rows
# check columns
# check diagonals
# check tie
# is board full
# ---- Global Variables -----
# Game Board
board = [''] * 9
# If game is still going
game_still_playing = True
# Who won? Or Tie?
winner = None
# Prompt user to choose X's or O's
letter = input("Choose a letter X or O: ").upper()
current_player = letter
# Input validation
while current_player not in ('x', 'o', 'X', 'O'):
letter = input("Try again. Choose a letter X or O:").upper()
current_player = letter
if letter.upper() not in ('X', 'O'):
print("Not an appropriate choice.")
else:
break
print("Player 1 will be ", current_player + "'s.\n")
def display_board():
print(board[6], "\t|", board[7] + " | " + board[8])
print("--------------")
print(board[3], "\t|", board[4] + " | " + board[5])
print("--------------")
print(board[0], "\t|", board[1] + " | " + board[2])
# ("1) Player 1 vs Player 2\n2) Player 1 vs AI\n3) Load Game\n0) Save & Exit")
# play tic tac toe
def play_game():
begin = "Y"
while begin == "Y":
game_choice = menu()
if game_choice == 1:
choice_one()
elif game_choice ==2:
player1VSai()
elif game_choice ==3:
save_and_exit()
elif game_choice==4:
load_game()
def choice_one():
# Display initial board
display_board()
while game_still_playing:
# handle a single turn of a arbitrary player
handle_turn(current_player)
# check if win or tie
check_if_game_over()
# flip to other player
alternate_player()
# The game has ended
if winner == 'X' or winner == 'O':
print(winner + " won.")
clear_board = reset_game()
play_game()
elif winner == None:
print("Tie.")
reset_game()
play_game()
# handle a single turn of a random player
def handle_turn(player):
print(player + "'s turn.")
position = input("Choose a position from 1 to 9: ")
# I can index into position with int instead of string
valid = False
while not valid:
while position not in ["1", "2", "3", "4", "5", "6", "7", "8", "9"] or position ==0:
position = input("Choose a position from 1-9: ")
if position == 0:
save_and_exit()
pass
# convert from string to int
position = int(position) - 1
if board[position] == '':
valid = True
else:
print("Space filled. Go again.")
# Board at position equals X
board[position] = player
display_board()
print("Press 0 to save & exit game.")
#then if? or loop? prompt user to save game?
def check_if_game_over():
# 3 in a row
check_for_winner()
# full board
check_if_tie()
def check_for_winner():
# Set up global variables
global winner
# check rows
row_winner = check_rows()
# check columns
column_winner = check_columns()
# check diagonals
diagonal_winner = check_diagonals()
if row_winner:
winner = row_winner
print("There was a ROW win!")
elif column_winner:
winner = column_winner
print("There was a COLUMN win!")
elif diagonal_winner:
winner = diagonal_winner
print("There was a DIAGONAL win!")
else:
winner = None
def check_rows():
# Set up global variables
global game_still_playing
# check rows for all the same values & is not an empty ''
row_1 = board[6] == board[7] == board[8] != ''
row_2 = board[3] == board[4] == board[5] != ''
row_3 = board[0] == board[1] == board[2] != ''
# if any row does have a match, flag that there is a win
if row_1 or row_2 or row_3:
game_still_playing = False
# Return the winner (X or O)
if row_1:
return board[6]
elif row_2:
return board[3]
elif row_3:
return board[0]
# return X or O if winner
# then flag game still playing to false to end loop
def check_columns():
# Set up global variables
global game_still_playing
# check columns for all the same values & is not an empty ''
column_1 = board[6] == board[3] == board[0] != ''
column_2 = board[7] == board[4] == board[1] != ''
column_3 = board[8] == board[5] == board[2] != ''
# if any column does have a match, flag that there is a win
if column_1 or column_2 or column_3:
game_still_playing = False
# Return the winner (X or O)
if column_1:
return board[6]
elif column_2:
return board[7]
elif column_3:
return board[8]
# return X or O if winner
# then flag game still playing to false to end loop
def check_diagonals():
# Set up global variables
global game_still_playing
# check columns for all the same values & is not an empty ''
diagonal_1 = board[0] == board[4] == board[8] != ''
diagonal_2 = board[6] == board[4] == board[2] != ''
# if any row does have a match, flag that there is a win
if diagonal_1 or diagonal_2:
game_still_playing = False
# Return the winner (X or O)
if diagonal_1:
return board[0]
elif diagonal_2:
return board[6]
# return X or O if winner
# then flag game still playing to false to end loop
def check_if_tie():
# declare global variable
global game_still_playing
# check if board full
if '' not in board:
game_still_playing = False
return
def alternate_player():
global current_player
# if current player is == to X then change it to O
if current_player == "X":
current_player = 'O'
# if current player is == to O then change it to X
elif current_player == "O":
current_player = 'X'
def player1VSai():
#random number
return
def save_and_exit():
global current_player
#save and end loop
turn=current_player
option = menu()
file=open("HW3game.txt", "w")
for x in board:
file.write(x)
file.write(turn)
file.write(str(option))
file.close()
print("You have saved the game and exited")
return
def menu():
print("Welcome to Tic Tac Toe")
print("1) Player 1 vs Player 2\n2) Player 1 vs AI\n3) Save & Exit\n4) Load Game")
game_choice = int(input("Choose an option, 0-4: "))
#
return game_choice
def load_game():
#setup global
global current_player
file = open("HW3game.txt", "r")
for i in range(0,8):
board[i]=file.read(1)
current_player=file.read(1)
#current choice of game.
game_choice=int(file.read(1))
file.close()
print("You have called the load function.")
return
def reset_game():
global board
#erase contents in current board
#replay game
clear_board = board.clear()
return clear_board
play_game()
I am making a tic-tac-toe program in python.
I have two questions:
How to create a trick to terminate the move() when we have created a diagonal or a line(xxx or OOO) in the game.
In my program some error is occurring::in line 28::(UnboundLocalError: local variable 'stop' referenced before assignment)
My code is::
import random
board = {"top-l":" ","top-m":" ","top-r":" ","mid-l":" ","mid-m":" ","mid-r":" ","low-l":" ","low-m":" ","low-r":" "}
def print_board(board):
print( board["top-l"] + "|" + board["top-m"] + "|" + board["top-r"])
print("--------")
print( board["mid-l"] + "|" + board["mid-m"] + "|" + board["mid-r"])
print("--------")
print( board["low-l"] + "|" + board["low-m"] + "|" + board["low-r"])
if random.randint(0,1) == 1:
turn = "X"#user
else:
turn = "O"# computer
def instructions():
print("TYPE top FOR TOP ROW, mid FOR MIDDLE ROW AND low FOR LOWEST ROW")
print(" ")
print("TYPE -l FOR LEFT CORNER, -m FOR MIDDLE CORNER AND -r FOR RIGHT CORNER")
print(" ")
print("SO COMMAND FOR TOP RIGHT CORNER SHOULD BE top-r ")
print("AN EMPTY BOARD LOOKS LIKE::")
print_board(board)
def move():
for i in range(10):
print_board(board)
print("CHANCE NO. " + str(i))
if turn == "O":
if i == 1:
print("COMPUTER WILL TAKE THE FIRST TURN(FOR " + turn + ")")
else:
print("IT'S COMPUTER TURN NOW")
y = random.randint(0,9)
move = str(board_list[y])
elif turn == "x":
if i == 1:
print("USER WILL TAKE THE FIRST TURN(FOR " + turn + "). PLEASE ENTER YOUR MOVE")
else:
print("IT'S USERS TURN NOW. PLEASE ENTER YOUR MOVE")
move = input()
print("STEP TAKEN IS ::" + move)
board["move"] = turn
if turn == "x":
tu = 0
turn = "O"
elif turn == "O":
tu = 1
turn = "X"
if board["top-l"] == board["top-m"] == board["top-r"] or board["mid-l"] == board["mid-m"] == board["mid-r"] or board["low-l"] == board["low-m"] == board["low-r"] or board["mid-l"] == board["top-l"] == board["low-l"] or board["mid-m"] == board["top-m"] == board["low-m"] or board["mid-r"] == board["top-r"] == board["low-r"] or board["top-l"] == board["mid-m"] == board["low-r"] or board["top-r"] == board["mid-m"] == board["low-l"]:
stop = 1
else:
stop = 0
if __name__ == "__main__":
board_list = list(board.keys())
tu = int(0)# 0 for computer
# 1 for user
stop = int(0)# 0 = continue
print("PRESENTING YOU TIC-TAC-TOE GAME v1.0 BY DK SHARAMA")
print("PLEASE ENTER YOUR NAME::")
user = str(input())
print("WELCOME " + user)
instructions()
print("TO PLAY PRESS 1 ELSE 0")
play = int(input())
if play == 1:
move()
if stop == 1:
print("GAME OVER")
if tu == 0:
print("COMPUTER WON")
elif tu == 1:
print("USER WON")
elif stop == 0:
print("IT'S A TIE :: NO ONE WON")