I have written up a Tic Tac Toe game however there seems to be an error.
None of the players have won, nor there still exists "-" in board, the game just ends to a draw after some playing.
(Please see in def check(): last elif statement.)
Could you please help me what is wrong with the code?
(Sorry I am a beginner and please excuse the lack of my code)
Here is my code below:
import sys
board = [["-","-","-"],["-","-","-"],["-","-","-"]]
def print_board():
for x in board:
print(" ".join(x))
P1X = input("Hi Player 1. What is your name? ")
P2O = input("Hi Player 2. What is your name? ")
def play_again():
answer = input("It is a draw!. Do you want to play again? Y/N ").upper()
if answer == "Y":
play_game()
else:
sys.exit()
def check():
if board[0][0] == board[0][1] == board[0][2]:
check_win(0, 0)
elif board[0][0] == board[1][0] == board[2][0]:
check_win(0, 0)
elif board[0][0] == board[1][1] == board[2][2]:
check_win(0, 0)
elif board[0][1] == board[1][1] == board[2][1]:
check_win(1, 1)
elif board[0][2] == board[1][2] == board[2][2]:
check_win(2, 2)
elif board[1][0] == board[1][1] == board[1][2]:
check_win(1, 1)
elif board[2][0] == board[2][1] == board[2][2]:
check_win(2, 2)
elif board[0][2] == board[1][1] == board[2][0]:
check_win(1, 1)
elif "-" not in board:
print("It is a draw!")
play_again()
else:
pass
def check_win(row,col):
if board[row][col] == 'X':
print_board()
print("{0} has won the game. Game Over!".format(P1X))
play_again()
elif board[row][col] == "O":
print_board()
print("{0} has won the game. Game Over!".format(P2O))
play_again()
else:
pass
count = 0
def place(row, col):
if count == 0:
board[row][col] = "X"
else:
board[row][col] = "O"
def play_game():
global count
print("Please start the game {0}".format(P1X))
while count != 892:
row_input = int(input("Please select the row ")) -1
col_input = int(input("Please select the column ")) -1
place(row_input, col_input)
check()
print_board()
if count == 0:
count = 1
print("It is now {0}'s turn".format(P2O))
else:
count = 0
print("It is now {0}'s turn".format(P1X))
play_game()
Your program doesn't define check_win, so I am not sure how it works at all. Your problem, however, is that you use a list of rows as your board representation, presumably starting with each board element as '-' to indicate unplayed spaces.
Depending on the rest of your code you might find it easier to use a dictionary as the board representation, with two-element tuples as subscripts.
As the code is now that last test would need to be modified to test that no row contains a '-', which you could do with the test:
if not any('-' in row for row in board):
At present you are comparing lists with strings. That's never going to give you equality.
Related
I've just started learning Python, and like a lot of beginners I'm working on a simple two player tic tac toe game.
I've managed to get through most of the code and debug everything EXCEPT for some reason when I try and replay the game, it's not resetting my board variable and essentially clearing the board despite re assigning the variable. I'm assuming its a simple fix and has something to do with scope that I'm just missing but I'd really appreciate if someone could give it a look over and let me know how I'd fix this issue.
Currently the code works, the player picks a symbol and goes back and forth until someone wins, then the code asks if they'd like to replay. If no is chosen, the game ends just fine, but if they select yes, the board isn't cleared from the last games markers.
I feel like I've tried a million different things and nothing seems to be clearing it!
Here's the code
#Display board function
#import clear output function - if don't will show entire history of board moves each time
from IPython.display import clear_output
def view_board(board):
clear_output()
print(display_board[6]+'|'+display_board[7]+"|"+display_board[8])
print('-----')
print(display_board[3]+'|'+display_board[4]+"|"+display_board[5])
print('-----')
print(display_board[0]+'|'+display_board[1]+"|"+display_board[2])
#OK function to ask player one if they want to be X or O
def player_icon():
#VARIABLES
icon = 'wrong'
while icon not in ['X', 'O']:
icon = input('Player 1, please choose a symbol (X or O):')
if icon not in ['X', 'O']:
print('Sorry, that is not a valid choice. Please choose either X or O.')
if icon == 'X':
print('Great! Player 1 will go first!')
elif icon == 'O':
print('Great! Player 2 will go first!')
return icon
#now we do the positioning based on the numbers on the board
#take user input position - use that as index value in blank list - replace that value with their marker
def user_position_X(board):
#board will be blank at first - make board variable
#marker will be their chosen icon from player_icon - starts with X - change to O after first move made
#position will be index value 1-9 - make sure to subtract 1 from chosen value as index will start at 0
#board(position) = marker
#VARIABLES
marker = 'X'
position = 'wrong'
while position not in board:
#ASK FOR USER POSITION
position = input('Please choose a position (1-9): ')
#IF NOT IN ACCEPTABLE VALUES (includes not digits I believe)
if position not in board:
print('Sorry! That is not an acceptable position. Please select an avaliable position.')
#MAKE POSITION INT
position_int = int(position)
#MAKING INPUT
index_position = (position_int)-1
#REPLACING ON BOARD - NOT USING X AND O SO CAN'T BE OVERWRITTEN - X=T O=P
board[index_position] = 'T'
#ADDING MARKER TO DISPLAY BOARD
for location in display_board:
display_board[index_position] = marker
return [board, display_board]
#now we do the positioning based on the numbers on the board
#take user input position - use that as index value in blank list - replace that value with their marker
def user_position_O(board):
#board will be blank at first - make board variable
#marker will be their chosen icon from player_icon - starts with X - change to O after first move made
#position will be index value 1-9 - make sure to subtract 1 from chosen value as index will start at 0
#board(position) = marker
#VARIABLES
marker = 'O'
position = 'wrong'
while position not in board:
#ASK FOR USER POSITION
position = input('Please choose a position (1-9): ')
#IF NOT IN ACCEPTABLE VALUES (includes not digits I believe)
if position not in board:
print('Sorry! That is not an acceptable position. Please select an avaliable position.')
#MAKE POSITION INT
position_int = int(position)
#MAKING INPUT
index_position = (position_int)-1
#REPLACING ON BOARD - Not using X and O so they cannot be replaced - X = T O = P
board[index_position] = 'P'
#ADDING MARKER TO DISPLAY BOARD
for location in display_board:
display_board[index_position] = marker
return [board, display_board]
#CHECK TO SEE IF WON - HOW?
#DICTIONARY OF ALL WINNING POSITIONS?
#run check win after each turn? after display board?
#in final code make player_icon = p1_icon
#check wins should jsut contain those items not be them exacly - check section 6 for the similar ones the 007 thing
#WHEN X AT CERTAIN INDEX POSITIONS WHEN O AT CERTAIN INDEX POSITIONS
#USING T AND P
def check_win(board,player1_icon):
#WHEN X AT CERTAIN INDEX POSITIONS WHEN O AT CERTAIN INDEX POSITIONS
#USING T AND P
#HORIZONTAL X
if (board[0] == 'T'and board[1] == 'T' and board[2] == 'T') or (board[3] == 'T'and board[4] == 'T' and board[5] == 'T') or (board[6] == 'T'and board[7] == 'T' and board[8] == 'T'):
if player1_icon == 'X':
win = 'yes'
print('Congrats, Player 1 has won!')
return win
elif player1_icon != 'X':
win = 'yes'
print('Congrats, Player 2 has won!')
return win
else:
pass
else:
pass
#VERTICAL X
if (board[0] == 'T'and board[3] == 'T' and board[6] == 'T') or (board[1] == 'T'and board[4] == 'T' and board[7] == 'T') or (board[2] == 'T'and board[5] == 'T' and board[8] == 'T'):
if player1_icon == 'X':
win = 'yes'
print('Congrats, Player 1 has won!')
return win
elif player1_icon != 'X':
win = 'yes'
print('Congrats, Player 2 has won!')
return win
else:
pass
else:
pass
#DIAGONAL X
if (board[0] == 'T'and board[4] == 'T' and board[8] == 'T') or (board[2] == 'T'and board[4] == 'T' and board[6] == 'T'):
win = 'yes'
if player1_icon == 'X':
win = 'yes'
print('Congrats, Player 1 has won!')
return win
elif player1_icon != 'X':
win = 'yes'
print('Congrats, Player 2 has won!')
return win
else:
pass
else:
pass
#HORIZONTAL O
if (board[0] == 'P'and board[1] == 'P' and board[2] == 'P') or (board[3] == 'P'and board[4] == 'P' and board[5] == 'P') or (board[6] == 'P'and board[7] == 'P' and board[8] == 'P'):
if player1_icon == 'O':
win = 'yes'
print('Congrats, Player 1 has won!')
return win
elif player1_icon != 'O':
win = 'yes'
print('Congrats, Player 2 has won!')
return win
else:
pass
else:
pass
#VERTICAL O
if (board[0] == 'P'and board[3] == 'P' and board[6] == 'P') or (board[1] == 'P'and board[4] == 'P' and board[7] == 'P') or (board[2] == 'P'and board[5] == 'P' and board[8] == 'P'):
if player1_icon == 'O':
win = 'yes'
print('Congrats, Player 1 has won!')
return win
elif player1_icon != 'O':
win = 'yes'
print('Congrats, Player 2 has won!')
return win
else:
pass
else:
pass
#DIAGONAL O
if (board[0] == 'P'and board[4] == 'P' and board[8] == 'P') or (board[2] == 'P'and board[4] == 'P' and board[6] == 'P'):
if player1_icon == 'O':
win = 'yes'
print('Congrats, Player 1 has won!')
return win
elif player1_icon != 'O':
win = 'yes'
print('Congrats, Player 2 has won!')
return win
else:
pass
else:
win = 'no'
return win
#Would you like to replay
def check_replay():
choice = 'wrong'
while choice not in ['Yes', 'No']:
choice = input('Would you like to play again? (Yes or No) ')
if choice not in ['Yes', 'No']:
print("Sorry, I don't understand. Please choose Yes or No.")
if choice == 'Yes':
return True
#aka game keeps playing
else:
print('Thanks for playing!')
return False
#game stops
#bc boolean values can continue to maintain some while loop
#Put it all together
from IPython.display import clear_output
def play_game():
replay = True
while replay == True:
#VARIABLES
win = 'no'
board = ['1','2','3','4','5','6','7','8','9']
display_board = [' ', ' ',' ',' ',' ',' ',' ',' ',' ']
#DISPLAY BOARD
view_board(display_board)
#ASK PLAYER 1 WHAT ICON
player1_icon = player_icon()
while win == 'no':
clear_output
#X SYMBOL POSITION
x_results = user_position_X(board)
x_results[0] = board
x_results [1] = display_board
#DISPLAY BOARD
view_board(display_board)
#CHECK IF WIN
win = check_win(board,player1_icon)
if win == 'yes':
break
#O SYMBOL POSITION
o_results = user_position_O(board)
o_results[0] = board
o_results [1] = display_board
#DISPLAY BOARD
view_board(display_board)
#CHECK IF WIN
win = check_win(board,player1_icon)
if win == 'yes':
replay = False
replay = check_replay()
if replay:
board = ['1','2','3','4','5','6','7','8','9']
display_board = [' ', ' ',' ',' ',' ',' ',' ',' ',' ']
if not replay:
print('Thanks for Playing!')
#need to have updated list with where answers are and then a second seperate list with available numbers
Sorry if its a bit messy, its my first proper big coding project! Also sorry about my notes it was just the best way for me to keep track of everything!
Like I said, everything seems to work except when check_replay() is executed, for some reason board and display_board aren't resetting despite being defined at the top of the function. I've tried moving the location of board and display_boards assignments, tried re assigning them after checking for replay, tried writing a new function that runs play game as a function and replay as its own thing. I'm really not sure why it's not resetting.
Thanks in advance!!
I have made a Tic Tac Toe game in python and when X wins it shoes that O has won and when O wins it shows that X has won. I am pretty sure that the problem is that it changes player and after that checks if someone has won, I tried making it so it will switch be before the player switch but it still didn't work.
I also tried to change player in the is_win function but that also didn't fix it.
Could someone please take a look at this and help me fix this.
initial_board = [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
board = initial_board
def empty_board(): #use board = empty_board() everytime you want to empty the board
board = [['_', '_', '_'], ['_', '_', '_'], ['_', '_', '_']]
return(board)
def switch_turn(player): #use player = switch_turn(player) everytime you want to switch players
if player == 'X':
return 'O'
return 'X'
def print_board(board):
print(*board, sep = "\n")
def is_full(board):
return all('_' not in box for box in board)
def is_valid(board, row, col):
x = board[row]
if x[col] == '_':
return True
return False
def set_cell(board, row, col, player):
x = board[row]
if is_valid(board,row,col) is True:
x[col] = player
print_board(board)
else:
print("already taken")
def get_user_input():
while True:
while True:
row = int(input("Enter the row you want (0-2): "))
if row > 2 or row < 0:
print("The number you entered is not valid")
continue
break
while True:
col = int(input("Enter the column you want (0-2): "))
if col > 2 or col < 0:
print("The number you entered is not valid")
continue
break
if is_valid(board,row,col) is True:
return row,col
else:
print("This place is taken")
continue
def is_win(board,player):
row1 = board[0]
row2 = board[1]
row3 = board[2]
if row1[0] == row1[1] == row1[2] != '_':
print(player + " Has won!")
return True
elif row2[0] == row2[1] == row2[2] != '_':
print(player + " Has won!")
return True
elif row3[0] == row3[1] == row3[2] != '_':
print(player + " Has won!")
return True
elif row1[0] == row2[0] == row3[0] != '_':
print(player + " Has won!")
return True
elif row1[1] == row2[1] == row3[1] != '_':
print(player + " Has won!")
return True
elif row1[2] == row2[2] == row3[2] != '_':
print(player + " Has won!")
return True
elif row1[0] == row2[1] == row3[2] != '_':
print(player + " Has won!")
return True
elif row1[2] == row2[1] == row3[0] != '_':
print(player + " Has won!")
return True
else:
return False
def game():
player = 'X'
print_board(board)
while is_win(board, player) is False:
if is_full(board) is True and is_win(board, player) is False:
print("draw")
break
elif is_full(board) is True and is_win(board, player) is True:
print(is_win(board, player))
break
row, col = get_user_input()
set_cell(board, row, col, player)
player = switch_turn(player)
game()
I think it is because, before your game ends, the player gets switched at the of the game() function.
player = switch_turn(player)
When X makes its winning move, the player gets switched and the current player is now player 'O'. One idea could be checking is_win before the switch.
Without re-writing too much of your code I would just re-arrange the code a bit. You don't have to check if it is win or draw at start of the loop since it will never be True at start of a game. This means you can ask for input, set the cell, and only then check for win/draw. This makes you write out the winner before you switch turns.
You also don't want to print anything in the is_win function. Since that is your while loop criteria it will run the function after the code is executed and make it run with the wrong player. Solve this by not printing in the is_win function, just print when the if statement is fulfilled.
Another problem is that in your elif (win) statement you check if board is_full AND is_win. This will only happen if you win on the last spot.
You don't really have to write out "is False" or "is True" either. I think it is easier to read if you remove them and use the word not for False instead.
Rough code for the game loop:
def game():
player = 'X'
print_board(board)
while not is_win(board, player):
row, col = get_user_input()
set_cell(board, row, col, player)
if is_full(board) and not is_win(board, player):
print("draw")
break
elif is_win(board, player):
print(player + " has won!")
break
player = switch_turn(player)
I am trying to make a tic tac toe game in the terminal with python but i cant figure out why i get the victory message after choosing the first position can anybody else see why? i have made a for loop to check if i have won in rows or columns and made 2 if statements to check if i have won by diagonal
import random
board = [[' ',' ',' '],
[' ',' ',' '],
[' ',' ',' ']]
def checkwin(board):
for row in board:
if len(set(row)) == 1:
return True
elif board[0][0] == board[1][1] == board[2][2]:
return True
elif board[2][0] == board[1][1] == board[0][2]:
return True
else:
return False
def check_space_taken(board, number):
if not choose_position(board, number) == ' ':
return True
else:
return False
def choose_position(board, number):
if number <= 3:
board[0][number-1] = 'X'
elif number <= 6:
board[1][number-4] = 'X'
elif number <= 9:
board[2][number-7] = 'X'
return board, number
def computer_position(board, computer_number):
computer_number = random.randint(0,9)
if computer_number <= 3:
board[0][computer_number-1] = 'O'
elif computer_number <= 6:
board[1][computer_number-4] = 'O'
elif computer_number <= 9:
board[2][computer_number-7] = 'O'
return board, computer_number
Game_over = False
while not Game_over:
print(board)
player_input = int(input('move to: '))
changed_board = choose_position(board, player_input)
for line in changed_board:
print(line)
if checkwin(board):
print('\n-----------------------Congrats you won-----------------------\n')
Game_over = True
In principle, your logic isn't incorrect, but you need to account for empty spaces. You also forgot to check columns:
def checkwin(board):
for i in range(3):
if board[i][0] != " " and board[i][0] == board[i][1] == board[i][2]:
return True # found a winning row
if board[0][i] != " " and board[0][i] == board[1][i] == board[2][i]:
return True # found a winning column
# winning diagonals?
if board[1][1] != " " and board[0][0] == board[1][1] == board[2][2]:
return True
if board[1][1] != " " and board[2][0] == board[1][1] == board[0][2]:
return True
return False
import random
def game():
def display_instructions():
""" Will print out instructions for how to play tic-tac-toe"""
print("Hello, and welcome to TIC-TAC-TOE! Here's how you play: you will choose whether you want to be X or O. I will tell you who is going first. When it is your turn, you will choose any number from zero to eight. The number you choose corresponds to the space you will be putting your letter in. Be careful not to choose a space already occupied by a letter! You will have to enter a new number. Your goal is to beat ME. The first one to get to three-in-a-row, sideways, up-and-down, or diagonally, wins. May the best man win.")
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("LET'S BEGIN")
display_instructions()
def assign_x_o():
""" Allows the user to choose whether to be X or O """
player_letter = input("Would you like to be X or O?")
return player_letter
player_letter = assign_x_o()
def tell_letter():
""" Tells the user who will be X and who will be O """
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("You will be", player_letter.upper() + "!")
if player_letter.upper() == "X":
print("I will be O!")
else:
print("I will be X!")
tell_letter()
not_used = [0, 1, 2, 3, 4, 5, 6, 7, 8]
def computer_letter():
""" Assigns the computer letter to whatever the player letter is not """
if player_letter.upper() == "X":
comp_letter = "O"
else:
comp_letter = "X"
return comp_letter
comp_letter = computer_letter()
board_list = ["0","1","2","3","4","5","6","7","8"]
def display_board():
""" Prints the Tic-Tac-Toe board """
print(board_list[0] + "|" + board_list[1] + "|" + board_list[2])
print("-+-+-")
print(board_list[3] + "|" + board_list[4] + "|" + board_list[5])
print("-+-+-")
print(board_list[6] + "|" + board_list[7] + "|" + board_list[8])
display_board()
def ask_num():
""" Asks the user to input a number from 0-8, corresponding to the spot to which they would like to move """
user_turn = input("Which place would you like to move to? (Input a number, 0-8)")
return user_turn
def second_board(board_list):
""" Creates a second board with which to test possible moves for the computer """
new_board = []
for i in board_list:
new_board.append(i)
return new_board
def check_win(board_list, player_letter, comp_letter):
""" Checks to see if there are three of X or O in a row (up, down, and diagonal) """
if board_list[0] == board_list[1] == board_list[2]:
return True
if board_list[3] == board_list[4] == board_list[5]:
return True
if board_list[6] == board_list[7] == board_list[8]:
return True
if board_list[0] == board_list[3] == board_list[6]:
return True
if board_list[1] == board_list[4] == board_list[7]:
return True
if board_list[2] == board_list[5] == board_list[8]:
return True
if board_list[0] == board_list[4] == board_list[8]:
return True
if board_list[2] == board_list[4] == board_list[6]:
return True
return False
def test_moves(board_list, player_letter, comp_letter, i):
""" Tests possible moves for the computer on a duplicate tic tac toe board """
new_board = second_board(board_list)
new_board[i] = player_letter.upper()
return check_win(board_list, player_letter, comp_letter)
def win_in_one(board_list):
temp_board = board_list
print(not_used)
for i in not_used:
for i in range(0, 1):
temp_board[i] = comp_letter
if check_win(temp_board, player_letter, comp_letter) == True:
win = True
if win == True:
return i
else:
win = check_win(temp_board, player_letter, comp_letter) == False
return win
def lose_in_one(board_list):
temp_board = board_list
for i in not_used:
for i in range(0, 1):
temp_board[i] = player_letter
if check_win(temp_board, player_letter, comp_letter) == True:
lose = True
if lose == True:
temp_board[i] = comp_letter
return i
else:
lose = False
return lose
def computer_turn(board_list):
""" Chooses which index value to use based on available spaces; first checks open corners, then the center, then the remaining side spaces """
win_in_one(board_list)
lose_in_one(board_list)
for i in range(0, 8):
if board_list[i] != "X" and board_list[i] != "O" and test_moves(board_list, player_letter, comp_letter, i):
return i
for i in range(0, 8):
if board_list[i] != "X" and board_list[i] != "O" and test_moves(board_list, player_letter, comp_letter, i):
return i
for i in [0, 2, 6, 8]:
if board_list[i] != "X" and board_list[i] != "O":
return i
if board_list[4] != "X" and board_list[4] != "O":
return 4
for i in [1, 3, 5, 7]:
if board_list[i] != "X" and board_list[i] != "O":
return i
def draw_message():
""" Prints a message notifying the user that the game has ended in a tie """
print("This game has ended in a tie!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
def keep_playing():
""" Calls the game function again if the user chooses to continue playing """
game()
def congrats():
""" Decides whether or not to congratulate the user or to tell them the computer won; also gives the option to play the game again """
if board_list[0] == board_list[1] == board_list[2] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
elif board_list[3] == board_list[4] == board_list[5] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
elif board_list[6] == board_list[7] == board_list[8] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
elif board_list[0] == board_list[3] == board_list[6] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
elif board_list[1] == board_list[4] == board_list[7] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
elif board_list[2] == board_list[5] == board_list[8] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
elif board_list[0] == board_list[4] == board_list[8] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
elif board_list[2] == board_list[4] == board_list[6] == player_letter.upper():
print("Congrats! You are the winner!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
else:
print("Uh oh. Looks like I won! Better luck next time!")
play_again = input("Would you like to play again? (y/n) ")
if play_again.lower() == "y":
keep_playing()
else:
print("No worries. Let's play again soon!")
tf_list = ["True", "False"]
user_first = random.choice(tf_list)
def first_turn():
""" Uses user_first random choice to decide if the computer or user goes first, then prints who will start; if user starts, user will input a number and the board will be displayed; if computer starts, computer will take turn and display board"""
if user_first == "True":
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("You will start!")
user_turn = int(ask_num())
if board_list[user_turn] != "X" and board_list[user_turn] != "O":
board_list[user_turn] = player_letter.upper()
not_used.remove(user_turn)
print(not_used)
display_board()
else:
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("The computer will start!")
if board_list[computer_turn(board_list)] != "X" and board_list[computer_turn(board_list)] != "O":
board_list[computer_turn(board_list)] = comp_letter
not_used.remove(computer_turn(board_list))
display_board()
first_turn()
def next_turn(user_first):
""" While playing, the computer and user will alternate turns. Upon either of them achieving three-in-a-row or a draw occurring, the user will be asked if they want to play again."""
turns = 1
still_playing = True
while still_playing == True:
if user_first == "True":
user_first = "False"
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("It is the computer's turn.")
if board_list[computer_turn(board_list)] != "X" or "O":
board_list[computer_turn(board_list)] = comp_letter
turns += 1
not_used.remove(computer_turn(board_list))
display_board()
if check_win(board_list, player_letter, comp_letter):
congrats()
still_playing = False
elif check_win(board_list, player_letter, comp_letter) == False:
still_playing = True
if turns == 9:
draw_message()
still_playing = False
else:
next_turn(user_first)
else:
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("It is the user's turn.")
user_turn = int(ask_num())
if board_list[user_turn] != "X" or "O":
board_list[user_turn] = player_letter.upper()
turns += 1
not_used.remove(user_turn)
display_board()
user_first = "True"
else:
print("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
print("INVALID MOVE. GO AGAIN.")
next_turn(user_first)
if check_win(board_list, player_letter, comp_letter):
congrats()
still_playing = False
elif check_win(board_list, player_letter, comp_letter) == False:
if turns == 9:
draw_message()
still_playing = False
else:
next_turn(user_first)
next_turn(user_first)
game()
Errors are popping up when the user takes their turn, and I don't know why. I'm trying to make the computer insert its letter if it can win in one move or block the user from winning. I know there is an issue with the win_in_one and lose_in_one functions, but I have done countless troubleshooting and have been unable to find a solution. If you could help me sort out my error or give suggestions to fix win_in_one and lose_in_one functions, it would be greatly appreciated.
You could use this compact Computer player function as your AI:
from random import sample
axes = [(0,1,2),(3,4,5),(6,7,8),(0,3,6),(1,4,7),(2,5,8),(0,4,8),(2,4,6)]
def isWin(board):
return any(board[a]+board[b]+board[c] in ["XXX","OOO"] for a,b,c in axes)
#level 3**3=Naive, 3**4=beginner, 3**5=intermediate, 3**6=good, 3**7=expert
def rating(position,play,board,level=3**6):
if board[position] != " " or level < 3: return 0
newBoard = board[:position]+[play]+board[position+1:]
if isWin(newBoard): return level*2
nextRatings = [rating(p,"XO"[play=="X"],newBoard,level/3) for p in range(9)]
return level-max(nextRatings,key=abs)
To make the computer play (with some randomness), use this line where computer is the letter that the computer plays ("X" or "O") and board is a list of board positions (indexed from 0 to 8) containing "X", "O" or a space character:
position = max(sample(range(9),9),key=lambda p:rating(p,computer,board))
Here is some sample code using the computer playing function:
while True:
board = [" "]*9
player,computer = sample("XOXO",2)
player = computer
print(player,computer)
while True:
for r in range(0,9,3):
print("("+") (".join(board[r:r+3])+")",list(range(r+1,r+4)))
available = [str(p+1) for p in range(9) if board[p] == " "]
if isWin(board) or not available : break
player = "XO"[player=="X"]
if player == computer:
position = max(sample(range(9),9),key=lambda p:rating(p,computer,board))
print(f"Computer plays {player} at {position+1}")
else:
while True:
position = input(f"Position to play for {player}: ")
if position not in available: print("Invalid position")
else : position = int(position)-1; break
board[position] = player
print( f"{player}'s WIN !!!\n" if isWin(board) else "DRAW.\n")
This is the first program I have tried to make. Its a simple game of noughts and crosses. Its written in Python 3.6.
I have tested it and when the game finishes, the tie/win message is printed twice but I cannot see why.
Any help regarding this or any other improvements are appreciated. Many Thanks.
I have included only the player 1 code so I can post the question.
#Grid
grid = [0, 1, 2, 3, 4, 5, 6, 7, 8]
print("Welcome to Noughts and Crosses Game")
p1_name = input("What is name of Player 1? Player 1 is 'x': ")
#Draw Grid
def draw_grid():
print("-------------")
print('|', grid[0], '|', grid[1], '|', grid[2], '|')
print("-------------")
print('|', grid[3], '|', grid[4], '|', grid[5], '|')
print("-------------")
print('|', grid[6], '|', grid[7], '|', grid[8], '|')
print("-------------")
#Move input for player 1
def p1():
try:
p1_input = int(input(p1_name + " select a space on the grid by entering a \
number to place an 'x': "))
except ValueError:
print("Error: Please enter a number, not a letter or symbol")
p1()
else:
if p1_input not in range(9):
print("Error: Please select a number on the grid 0-8 to place an 'x'")
p1()
elif grid[p1_input] == "x" or grid[p1_input] == "o":
print("Error: This spot has been taken.")
p1()
else:
grid[p1_input] = "x"
draw_grid()
#Check for three x in a row
def p1_check():
if grid[0] == "x" and grid[1] == "x" and grid[2] == "x" or \
grid[3] == "x" and grid[4] == "x" and grid[5] == "x" or \
grid[6] == "x" and grid[7] == "x" and grid[8] == "x" or \
grid[0] == "x" and grid[3] == "x" and grid[6] == "x" or \
grid[1] == "x" and grid[4] == "x" and grid[7] == "x" or \
grid[2] == "x" and grid[5] == "x" and grid[8] == "x" or \
grid[6] == "x" and grid[4] == "x" and grid[2] == "x" or \
grid[0] == "x" and grid[4] == "x" and grid[8] == "x":
print(p1_name + " Wins!")
return "End Game"
#Check for a tie
def tie_check():
if grid.count("x") + grid.count("o") == len(grid):
print("Game is a tie")
return "End Game"
def play():
draw_grid()
while True:
p1()
p1_check()
if p1_check() == "End Game":
break
tie_check()
if tie_check() == "End Game":
break
play()
p1_check()
if p1_check() == "End Game":
break
tie_check()
if tie_check() == "End Game":
break
You are running p1_check() and tie_check() twice. Store the output of p1_check() and tie_check() in variables to avoid the double print.
ended = p1_check()
if ended == "End Game":
break
tied = tie_check()
if tied == "End Game":
break
Because p1_check and tie_check are executed twice.
Once just before the if-statement and then again in the if-statement
I reccommend removing the calls just before the if-statement