So I have got this Python code for my TicTacToe. Everything is working normal except when there is no winner the program must return 'Tie' and instead it just continues asking for X and O even if the board is already filled. I'm assuming the problem is in the check_if_tie() function but I can't figure it out.
# -------Global variables--------
# If game is still going
game_still_going = True
# Who won? Or tie
winner = None
# Whose turn it is
current_player = 'X'
# The board displaying function
board = [' '] * 10
def display_board():
print(' ' + board[6] + ' | ' + board[7] + ' | ' + board[8])
print('---+-' '--+--- ')
print(' ' + board[3] + ' | ' + board[4] + ' | ' + board[5])
print('---+-' '--+--- ')
print(' ' + board[0] + ' | ' + board[1] + ' | ' + board[2])
# Checks if game is over
def check_if_game_over():
check_if_tie()
check_if_win()
# Checks if there is a winner
def check_if_win():
global winner
if check_row():
winner = check_row()
elif check_columns():
winner = check_columns()
elif check_diagonals():
winner = check_columns()
else:
winner = None
return
def check_row():
global game_still_going
row1 = board[6] == board[7] == board[8] != " "
row2 = board[3] == board[4] == board[5] != " "
row3 = board[0] == board[1] == board[2] != " "
if row1 or row2 or row3:
game_still_going = False
if row1:
return board[6]
elif row2:
return board[3]
elif row3:
return board[0]
return
def check_columns():
global game_still_going
column1 = board[6] == board[3] == board[0] != " "
column2 = board[7] == board[4] == board[1] != " "
column3 = board[8] == board[5] == board[2] != " "
if column1 or column2 or column3:
game_still_going = False
if column1:
return board[6]
elif column2:
return board[7]
elif column3:
return board[8]
return
def check_diagonals():
global game_still_going
diagonal1 = board[6] == board[4] == board[2] != " "
diagonal2 = board[0] == board[4] == board[8] != " "
if diagonal1 or diagonal2:
game_still_going = False
elif diagonal1:
return board[6]
elif diagonal2:
return board[0]
return
def check_if_tie():
global game_still_going
if ' ' not in board:
game_still_going = False
return
def flip_player():
global current_player
if current_player == 'X':
current_player = 'O'
elif current_player == 'O':
current_player = 'X'
return
# Whose turn it is to play
def handle_turn(player):
print(player + "'s turn")
position = int(input('Please write your position from 1 - 9: ')) - 1
if position not in [0,1,2,3,4,5,6,7,8,9]:
return input('Invalid position. Please write 1-9: ')
board[position] = player
display_board()
# Main gameplay function
def play_game():
global winner
# Displays initial board
display_board()
# Loop running the game
while game_still_going:
handle_turn(current_player)
flip_player()
check_if_game_over()
if winner == 'X' or winner == 'O':
print(winner + ' won.')
elif winner:
print('Tie')
play_game()
You're having quite a lot of issues in this code and most of the problem could be avoided by avoiding the use of globals.
When you use globals you change a global state that makes it difficult to understand what's going on. You have functions that return nothing but change state that will make the game end or not.
One simple change would be to have you check_ method return an actual boolean and use that value in the loop to check if you have a tie or a win.
If you're not in a tie or a win, it means the game isn't finished. So you don't need to store a global value and certainly do not have to modify the state of the is a tie or a win anywhere else.
Keep you functions as simple as possible. I often say that but think how you actually play a game.
In a game you have 2 players and 1 board, in which you set values anywhere.
Each turn adds a piece until the game ends in a tie or a win.
Everytime you add a piece you can check the state of the game. If it's not finished then you can swith the current player and enter a new piece and repeat.
None of this requires a global state and you can always pass the game board to your methods...
In your case it would be as simple as doing this:
def is_tie():
return ' ' not in board
def is_win():
... is_win logic
return result
while not is_tie() or not is_win():
... game logic
To go a step further, instead of having globals you'd have to pass the game state as arugment like this:
def is_tie(game):
return ' ' not in game.board
And to go a step further, entering a new piece in the board would return a new state. So instead of modifying the current state you'd have a main loop that looks like this:
game = Game()
while True:
position = game.prompt_choice()
if not game.position_available(position)
# loop again to select a new position
continue
game = game.execute_turn(position)
if game.is_done()
break
else:
# if game not done switch player and move to next turn
game = game.switch_player()
# current game player is winner
game.print_winner()
The cool thing is that if you wanted to "replay" the game, you'd just have to save the state of the game just before looping again. each "game" being returned is a modified version of the previous game object so you're never modifying the actual object.
The simplest suggestion that I can think of would be to have a variable that holds the amount of available squares left and decrement it after each turn. Once it reaches 0, if there is no win, then there must a tie.
# -------Global variables--------
# If game is still going
game_still_going = True
# Who won? Or tie
winner = None
# Whose turn it is
current_player = 'X'
# The board displaying function
board = [' '] * 10
#board spaces
board_spaces = 9
def display_board():
print(' ' + board[6] + ' | ' + board[7] + ' | ' + board[8])
print('---+-' '--+--- ')
print(' ' + board[3] + ' | ' + board[4] + ' | ' + board[5])
print('---+-' '--+--- ')
print(' ' + board[0] + ' | ' + board[1] + ' | ' + board[2])
# Checks if game is over
def check_if_game_over():
check_if_win()
check_if_tie()
# Checks if there is a winner
def check_if_win():
global winner
if check_row():
winner = check_row()
elif check_columns():
winner = check_columns()
elif check_diagonals():
winner = check_columns()
else:
winner = None
return
def check_row():
global game_still_going
row1 = board[6] == board[7] == board[8] != " "
row2 = board[3] == board[4] == board[5] != " "
row3 = board[0] == board[1] == board[2] != " "
if row1 or row2 or row3:
game_still_going = False
if row1:
return board[6]
elif row2:
return board[3]
elif row3:
return board[0]
return
def check_columns():
global game_still_going
column1 = board[6] == board[3] == board[0] != " "
column2 = board[7] == board[4] == board[1] != " "
column3 = board[8] == board[5] == board[2] != " "
if column1 or column2 or column3:
game_still_going = False
if column1:
return board[6]
elif column2:
return board[7]
elif column3:
return board[8]
return
def check_diagonals():
global game_still_going
diagonal1 = board[6] == board[4] == board[2] != " "
diagonal2 = board[0] == board[4] == board[8] != " "
if diagonal1 or diagonal2:
game_still_going = False
elif diagonal1:
return board[6]
elif diagonal2:
return board[0]
return
def check_if_tie():
global game_still_going
global winner
global board_spaces
if winner == None and board_spaces == 0:
game_still_going = False
return
def flip_player():
global current_player
if current_player == 'X':
current_player = 'O'
elif current_player == 'O':
current_player = 'X'
return
# Whose turn it is to play
def handle_turn(player):
print(player + "'s turn")
position = int(input('Please write your position from 1 - 9: ')) - 1
if position not in [0,1,2,3,4,5,6,7,8,9]:
return input('Invalid position. Please write 1-9: ')
board[position] = player
display_board()
board_spaces -= 1
# Main gameplay function
def play_game():
global winner
# Displays initial board
display_board()
# Loop running the game
while game_still_going:
handle_turn(current_player)
flip_player()
check_if_game_over()
if winner == 'X' or winner == 'O':
print(winner + ' won.')
elif winner:
print('Tie')
play_game()
Related
Below is the code I used for my simple Tic Tac Toe game. I receive the following error I have no idea how to get around. This program does work in Jupyter notebook, but when I try to run the script in VScode, the error appears. I need guidance on how I can fix this error.
***THE ERROR IS AS FOLLOWS: ***
Traceback (most recent call last):
File "x:\Python\Python_Bootcamp\Complete-Python-3-Bootcamp-master\04-Milestone Project - 1\TIC_TAC_TOE.py", line 105, in <module>
display_board(board)
File "x:\Python\Python_Bootcamp\Complete-Python-3-Bootcamp-master\04-Milestone Project - 1\TIC_TAC_TOE.py", line 8, in display_board
print(board[1] + '|' + board[2] + '|' + board[3])
~~~~~^^^
IndexError: list index out of range
TIC TAC TOE GAME
`
import random
`
Display the board for the game
`def display_board(board):
# print('\n'*100) # Lets you only see one version of the board
print(board[1] + '|' + board[2] + '|' + board[3])
print('-----')
print(board[4] + '|' + board[5] + '|' + board[6])
print('-----')
print(board[7] + '|' + board[8] + '|' + board[9])`
Choose whether player 1 is X or O
`def player_input():
marker = ''
while marker != 'X' and marker != 'O':
marker = input('Player 1 choose X or O: ')
player1 = marker.upper()
if player1 == 'X':
player2 = 'O'
else:
player2 = 'X'
return(player1, player2)`
Takes a position on the board and puts a marker on position
`def place_marker(board,marker,position):
board[position] = marker`
Check to see if win
`def win_check(board, mark):
return ((board[7] == mark and board[8] == mark and board[9] == mark) or # across the bottom
(board[4] == mark and board[5] == mark and board[6] == mark) or # across the middle
(board[1] == mark and board[2] == mark and board[3] == mark) or # across the top
(board[7] == mark and board[4] == mark and board[1] == mark) or # down the left column
(board[2] == mark and board[5] == mark and board[8] == mark) or # down the middle
(board[3] == mark and board[6] == mark and board[9] == mark) or # down the right side
(board[3] == mark and board[5] == mark and board[7] == mark) or # diagonal
(board[9] == mark and board[5] == mark and board[1] == mark)) # diagonal`
Random flip to see if Player 1 or Player 2 goes first
`def choose_first():
flip = random.randint(0,1)
if flip == 0:
return ('Player 1')
else:
return ('Player 2')`
Check to see if position freely available
`def space_check(board, position):
return board[position] == ' ' # If space is empty the return value will be True`
Check to see if the board is full
`def full_board_check(board):
for i in range(1,10):
if space_check(board,i):
return False # Fales meaning the space is empty of marker
else:
return True # True meaning the board is full`
Function for player to choose their next position on the board
`def player_choice(board):
position = 0
while position not in [1,2,3,4,5,6,7,8,9]:
position = int(input('Choose your position: '))
return position
def replay():
choice = input('Do you want to play again?')
return choice == 'Yes'`
GAME SETUP
`print('Welcome to Tic Tac Toe!')
while True:
board = [' '*10]
player1_marker,player2_marker = player_input()
turn = choose_first()
print(turn + ' will go first')
game_on = ''
play_game = input('Are you ready to play Yes or No?: ')
if play_game.lower()[0] == 'y':
game_on == True
else:
game_on == False
# Player 1 Turn
if turn == 'Player 1':
# Show board
display_board(board)
# Choose a position
position = player_choice(board)
# Place marker on choosen position
place_marker(board,player1_marker,position)
# Check if they won
if win_check(board,player1_marker) == True:
display_board(board)
print('Player 1 has won the game!')
game_on = False
# Check to see if Tie
else:
if full_board_check(board):
display_board(board)
print('TIE GAME')
break
# If there's no tie turn to Player 2
else:
turn = 'Player 2'
# Player2's turn.
if turn == 'Player 2':
# Show board
# display_board(board)
# Show position
position = player_choice(board)
#Place marker on position
place_marker(board,player2_marker,position)
# Check to see if win
if win_check(board,player2_marker) == True:
display_board(board)
print('Player 2 has won the game!')
game_on = False
# Check to see if Tie
else:
full_board_check(board)
display_board(board)
print('TIE GAME')
break
else:
turn = 'Player 1'
# If players do not want to play again, quit
if not replay():
break`
I've tried to comment out different lines of code to test some of the board configurations. I can get the board to show, but once I try to play a full game I get an error.
You have init
board = [' '*10]
so board is a list of only one element. so index 1 does not exists.
maybee you wanted to write:
board = 10*[' ']
so you have a list with 10 elements ' ' (10 times one blank/space).
I tested it and it works with your code, and I managed to play my first move.
i am struggling to see how my minimax algorithm is not working. It cycles through all the best moves but it dosen't pick the best one and i can't figure out why. For example i can input 1 5 9 and win. sorry in advance if the solution is something simple
Here is the code.
board = {1: ' ', 2: ' ', 3: ' ',
4: ' ', 5: ' ', 6: ' ',
7: ' ', 8: ' ', 9: ' '}
win = False
turn = 1
depth = 1
nodeindex = 0
possibles= []
moves = []
depth = 0
targetdepth = 3
movesdone = []
#def minimax(moves, targetdepth, depth, turn, scores):
def checkForWin(mark):
if board[1] == board[2] and board[1] == board[3] and board[1] == mark:
return True
elif (board[4] == board[5] and board[4] == board[6] and board[4] == mark):
return True
elif (board[7] == board[8] and board[7] == board[9] and board[7] == mark):
return True
elif (board[1] == board[4] and board[1] == board[7] and board[1] == mark):
return True
elif (board[2] == board[5] and board[2] == board[8] and board[2] == mark):
return True
elif (board[3] == board[6] and board[3] == board[9] and board[3] == mark):
return True
elif (board[1] == board[5] and board[1] == board[9] and board[1] == mark):
return True
elif (board[7] == board[5] and board[7] == board[3] and board[7] == mark):
return True
else:
return False
def checkForWin2():
if (board[1] == board[2] and board[1] == board[3] and board[1] != ' '):
return True
elif (board[4] == board[5] and board[4] == board[6] and board[4] != ' '):
return True
elif (board[7] == board[8] and board[7] == board[9] and board[7] != ' '):
return True
elif (board[1] == board[4] and board[1] == board[7] and board[1] != ' '):
return True
elif (board[2] == board[5] and board[2] == board[8] and board[2] != ' '):
return True
elif (board[3] == board[6] and board[3] == board[9] and board[3] != ' '):
return True
elif (board[1] == board[5] and board[1] == board[9] and board[1] != ' '):
return True
elif (board[7] == board[5] and board[7] == board[3] and board[7] != ' '):
return True
else:
return False
def possiblemoves(board):
y=0
possibles.clear()
for i in board:
if board[i] == " ":
possibles.append(i)
return possibles
def botgo(possibles, mark):
bestscore = -800
bestmove = 0
for key in board.keys():
if (board[key] == ' '):
board[key] = mark
score = minimax(board,0,False)
board[key] = ' '
if(score > bestscore):
bestscore = score
bestmove = key
insert(bestmove,mark='O')
return
def printboard():
print(board[1] + '|' + board[2] + '|' + board[3])
print('-----')
print(board[4] + '|' + board[5] + '|' + board[6])
print('-----')
print(board[7] + '|' + board[8] + '|' + board[9])
def start():
turn = 1
count = 0
while count != 9:
humango()
printboard()
possiblemoves(board)
botgo(possibles, mark='O')
printboard()
count = count + 1
#minimax(depth, possibles)
def spacefree(space):
if board[space] == ' ':
return True
else:
return False
def insert(space, mark):
if spacefree(space):
board[space]=mark
if checkForWin(mark):
if mark == 'X':
printboard()
print("human win")
exit()
else:
printboard()
print("BOT WIN")
exit()
else:
print("cannot insert there!!!")
space = int(input("Enter position"))
insert(space, mark)
def checkdraw(board):
if checkForWin2():
return True
def humango():
global turn
space = int(input("Enter position"))
insert(space, mark='X')
turn = turn + 1
printboard()
def minimax(board, depth, ismax):
if checkForWin(mark='O'):
return 1
elif checkForWin(mark='X'):
return -1
elif checkdraw(board):
return 0
if ismax == True:
bestscore = -800
for key in board.keys():
if (board[key] == ' '):
board[key] = 'O'
score = minimax(board, depth + 1, False)
board[key] = ' '
if (score > bestscore):
bestscore = score
printboard()
return bestscore
else:
bestscore = 800
for key in board.keys():
if (board[key] == ' '):
board[key] = 'X'
score = minimax(board, depth + 1, True)
board[key] = ' '
if (score < bestscore):
bestscore = score
return bestscore
start()
sorry for the messy code, thank you in advance
It seems you are complicating things, it will be much easier for you to debug with less code to look at. I would first suggest that you use a list instead of a dict to simplify your code in this game: board = [' ']*9. All my suggestions/simplifications below are based on this representation.
1.. Checking for win on a 1D board is super easy. First you create a variable with all the possible winning lines:
winning_lines = ([0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 3, 6], [1, 4, 7], [2, 5, 8], [0, 4, 8], [2, 4, 6])
Then you can loop through them with a loop:
def is_win(board, player):
for pos in winning_lines:
if board[pos[0]] == board[pos[1]] == board[pos[2]] == player:
return 1
2.. Checking for draw is even simpler since you only need to check if there are empty spaces or not:
def is_draw(board):
return 0 if ' ' in board else 1
3.. You don't need the depth variable in this game since you always go to maximum depth, ending in win, draw or loss. The depth can be used to always chose the shortest path to winning if there are more than 1 path, or the longest path to loss. Then you need to add and subtract depth from your check_win return statements in the minimax loop.
4.. You can get all the possible moves with list comprehension:
possible_moves = [i for i in range(len(board)) if board[i] == ' ']
Debugging
There are a few other clean ups to do, but to figure out why it gives the wrong answer you need to do some debugging. Does your win/draw/loss function work as you think it does, i.e. does it return the correct result for a known input board? Does it loop through all the possible moves? Print things in your minimax loop and see if it behaves as you would expect.
I've decided to learn Python about 2 weeks ago, been going through various books and videos, and I've decided to try my hand at programming a tic tac toe game. I was somewhat successful (it doesn't recognize if there's already a mark in a certain spot and allows overwriting of already placed marks) and I was wondering if any more experienced programmers could give me some general feedback about how I could do things better. Thank you so much and I hope you're all staying safe.
board = ['-'] * 9
def print_board():
print (board[0] + '|' + board[1] + '|' + board[2])
print (board[3] + '|' + board[4] + '|' + board[5])
print (board[6] + '|' + board[7] + '|' + board[8])
legalMoves = [1,2,3,4,5,6,7,8,9]
print_board()
turnCount = 0
def move():
move = int(input('Pick a number 1-9:'))
while move not in legalMoves:
print('Illegal move')
move = int(input('Pick a number 1-9:'))
marks = ['X','O']
if turnCount % 2 == 0:
board[move - 1] = marks[1]
else:
board[move - 1] = marks[0]
while True:
if board[0] == board[1] == board[2] == 'X'\
or board[3] == board[4] == board[5] == 'X'\
or board[6] == board[7] == board[8] == 'X'\
or board[0] == board[3] == board[6] == 'X'\
or board[1] == board[4] == board[7] == 'X'\
or board[2] == board[5] == board[8] == 'X'\
or board[0] == board[4] == board[8] == 'X'\
or board[2] == board[4] == board[6] == 'X' \
or board[0] == board[1] == board[2] == 'O' \
or board[3] == board[4] == board[5] == 'O' \
or board[6] == board[7] == board[8] == 'O' \
or board[0] == board[3] == board[6] == 'O' \
or board[1] == board[4] == board[7] == 'O' \
or board[2] == board[5] == board[8] == 'O' \
or board[0] == board[4] == board[8] == 'O':
print('Victory')
break
else:
move()
print_board()
turnCount = turnCount + 1
well you need to check if the user has typed
an int or something else, so that breaks your
program, also prevent the user from overwriting
existed cell input, also prevent the user from
typing a number out of range which you have
already taken care of that, so I have written
this small function to give you the correct
input and deals with wrong ones, you can use it
def isInt(strInt):
for c in strInt:
if c not in "0123456789": return False
return True
def getNextMove():
while True:
moveStr = input("Pick a number 1-9: ")
if not isInt(moveStr):
print("Pls write only a number")
continue
move = int(moveStr)
if move < 1 or move > 9:
print("Pls only 1-9 numbers are allowed")
continue
if board[move - 1] != "-":
print("Pls choose an empty cell")
continue
return move
Well, if that helped, I couldn't stop my self from writing the full code for the game, I couldn't sleep anyway, so here it is, you may get some ideas, happy coding!
board = [" "] * 9
winner = ""
def printBoard():
print("-" * 7)
for i in range(3):
print(f"|{board[i * 3]}|{board[i * 3 + 1]}|{board[i * 3 + 2]}|")
print("-" * 7)
def isInt(strInt):
for c in strInt:
if c not in "0123456789": return False
return True
def getNextMove():
while True:
moveStr = input("Pick a number 1-9: ")
if not isInt(moveStr):
print("Pls write only a number")
continue
move = int(moveStr)
if move < 1 or move > 9:
print("Pls only 1-9 numbers are allowed")
continue
if board[move - 1] != " ":
print("Pls choose an empty cell")
continue
return move
def checkHVD():
for i in range(3):
if board[i * 3] == board[i * 3 + 1] == board[i * 3 + 2] and board[i * 3] != " ":
return board[i * 3]
elif board[i] == board[i + 3] == board[i + 6] and board[i] != " ":
return board[i]
if (board[0] == board[4] == board[8] or board[2] == board[4] == board[6]) and board[4] != " ":
return board[4]
return False
for i in range(9):
board[getNextMove() - 1] = i % 2 == 0 and "X" or "O"
printBoard()
winner = checkHVD();
if winner:
identity = winner == "X" and "first" or "second"
print(f"The {identity} player({winner}) won")
break
if not winner:
print("It's a tie")
I don't know where the mistake to the winner is, it doesn't recognize, but it still recognizes a tie, please help, I'm still a beginner, thanks.
I've been starring to the screen for 3 hours and still couldn't solve this particular problem, also, I've looked in the forum, but found nothing.
#------Global variables -------
# Will hold our game board data
board = ["-", "-", "-",
"-", "-", "-",
"-", "-", "-",]
#If game is still going
game_still_going = True
#Tell us who won
winner = None
#Tell us who goes first, x goes first
current_player = "X"
#---------------FUNCTIONS---------------
#Play a game of tic tac toe
def play_game():
#Display initial board
display_board()
#While the game is still going
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 single turn of an arbitrary player
def handle_turn(player):
#get position from player
print(player + "'s turn. ")
position = input("Choose a position from 1-9: ")
print()
# 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 correct
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. ")
print()
# 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 if someone won the game
def check_for_winner():
# Set global variable
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
#Looking for winner in rows
def check_rows():
#Set up global variables
global game_still_going
#Checking if the rows got the same value and are 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 X or O
if row_1:
return board[0]
elif row_2:
return board[3]
elif row_3:
return board[6]
else:
return None
#Looking for winner in columns
def check_columns():
#Set up global variables
global game_still_going
#Checking if the column got the same value and are 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 column 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 X or O
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
#Looking for a winner in diagonals
def check_diagonals():
#Set up global variables
global game_still_going
#Checking if the diagonal got the same value and are not empty
diagonal_1 = board[0] == board[4] == board[8] != "-"
diagonal_2 = board[2] == board[4] == board[6] != "-"
#If any diagonal does have a match, flag that there is a win
if diagonal_1 or diagonal_2:
game_still_going = False
#return the winner X or O
if diagonal_1:
return board[0]
elif diagonal_2:
return board[2]
else:
return None
#Looking if there's a tie
def check_for_tie():
#Global variable
global game_still_going
#if the board is full
if "-" not in board:
game_still_going = False
# Else there is no tie
else:
return False
#Changing players time a time
def flip_player():
#Global variable we need
global current_player
#If the current player was x, then change it to O
if current_player == "X":
current_player = "O"
elif current_player == "O":
current_player = "X"
#--------Start the application----------
play_game()
You have missed global [variable] in most of the functions, I have find some missing variables please refer below code line by line:
#------Global variables -------
# Will hold our game board data
board = ["-", "-", "-",
"-", "-", "-",
"-", "-", "-",]
#If game is still going
game_still_going = True
#Tell us who won
winner = None
#Tell us who goes first, x goes first
current_player = "X"
#---------------FUNCTIONS---------------
#Play a game of tic tac toe
def play_game():
global winner #this is new
#Display initial board
display_board()
#While the game is still going
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():
global 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 single turn of an arbitrary player
def handle_turn(player):
#get position from player
print(player + "'s turn. ")
position = input("Choose a position from 1-9: ")
print()
# 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 correct
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. ")
print()
# 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 if someone won the game
def check_for_winner():
# Set global variable
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
#Looking for winner in rows
def check_rows():
#Set up global variables
global game_still_going
#Checking if the rows got the same value and are 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 X or O
if row_1:
return board[0]
elif row_2:
return board[3]
elif row_3:
return board[6]
else:
return None
#Looking for winner in columns
def check_columns():
#Set up global variables
global game_still_going
#Checking if the column got the same value and are 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 column 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 X or O
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
#Looking for a winner in diagonals
def check_diagonals():
#Set up global variables
global game_still_going
#Checking if the diagonal got the same value and are not empty
diagonal_1 = board[0] == board[4] == board[8] != "-"
diagonal_2 = board[2] == board[4] == board[6] != "-"
#If any diagonal does have a match, flag that there is a win
if diagonal_1 or diagonal_2:
game_still_going = False
#return the winner X or O
if diagonal_1:
return board[0]
elif diagonal_2:
return board[2]
else:
return None
#Looking if there's a tie
def check_for_tie():
#Global variable
global game_still_going
#if the board is full
if "-" not in board:
game_still_going = False
# Else there is no tie
else:
return False
#Changing players time a time
def flip_player():
#Global variable we need
global current_player
#If the current player was x, then change it to O
if current_player == "X":
current_player = "O"
elif current_player == "O":
current_player = "X"
#--------Start the application----------
play_game()
You can read this for more information about global :
https://www.google.com/url?sa=t&source=web&rct=j&url=https://www.geeksforgeeks.org/global-keyword-in-python/amp/&ved=2ahUKEwi2gbeo_fDoAhVo7XMBHZvjAHIQFjAPegQICxAy&usg=AOvVaw0fpoalAG4dROAIz3PlXcQo&cf=1
In your check_if_game_over function, you are not calling the check_for_winner function correctly. You need to add parenthesis afterward to call it correctly.
def check_if_game_over():
check_for_winner()
check_for_tie()
I'm trying to learn python and have been writing a (very) simple tic-tac-toe program. However, I've got stuck because it won't seem to execute beyond letting the user enter a number. After that, nothing happens. I can't figure out where I have gone wrong. Sure there are tons of errors, but help much appreciated!
Thanks!
import random
board = range(0,9)
def print_board():
print board[0], "|", board[1], "|", board[2]
print board[3], "|", board[4], "|", board[5]
print board[6], "|", board[7], "|", board[8]
def checkAll():
if board[0] == board[1] == board[2]:
True
if board[3] == board[4] == board[5]:
True
if board[6] == board[7] == board[8]:
True
if board[0] == board[3] == board[6]:
True
if board[1] == board[4] == board[7]:
True
if board[2] == board[5] == board[8]:
True
if board[0] == board[4] == board[8]:
True
if board[6] == board[4] == board[2]:
True
print_board()
while True:
input = int(raw_input("Choose a number to place your X: "))
if input <= 8:
if board[input] != "x" or board[input] != "o":
board[input] = "x" # places x if board[input] is neither x or o
# Check for winner
if checkAll() == True:
"The game is over!"
break;
finding = True
while finding:
random.seed() # gives a random generator
opponent = random.randrange(0,8) # generates a random integer between 1 and 8
if board[opponent] != "x" or board[opponent] != "o":
board[opponent] = "o"
# Check for winner
if checkAll() == True:
"The game is over!"
break;
else:
print "This spot is taken."
print_board()
else: "Please choose a number between O and 8."
Well there're many things which need improvement in your code (you have to rewrite your CheckAll function at least so it could check board of any size), but two things will help you to debug - first, you have to actually return something from your CheckAll function:
...
if board[0] == board[1] == board[2]:
return True
if board[3] == board[4] == board[5]:
return True
...
second, you may actually want to print output:
if checkAll() == True:
print "The game is over!"
break;