So, I was trying to make a basic Tic-Tac-Toe game with python, And I created one which works perfectly fine, but my code is not so good, as it has a lot of code for checking the list indexes(Winner Of The Game), which kinda bothers me. So, How I avoid using the left index for checking the winner of the game?
My Code:
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
def show_board():# for showing the tic-tac-toe board
print(' | ' + str(board[0]) + ' | ' +
str(board[1]) + ' | ' + str(board[2]) + ' | ')
print(' | ' + str(board[3]) + ' | ' +
str(board[4]) + ' | ' + str(board[5]) + ' | ')
print(' | ' + str(board[6]) + ' | ' +
str(board[7]) + ' | ' + str(board[8]) + ' | ')
def main():
one = 1
flag = 1
show_board()
while one == 1:
if flag == 1:
x_o = 'X'
if flag == 2:
x_o = 'O'
pos = int(input('Player "' + x_o + '" Turn: '))
if x_o == 'o':
x_o = 'O'
if x_o == 'x':
x_o = 'X'
if board[pos - 1] == 'O' or board[pos - 1] == 'O':
print('That Place Is Already Filled By Player "0"')
if board[pos - 1] == 'X' or board[pos - 1] == 'X':
print('That Place Is Already Filled By Player "X"')
else:
try:
board[pos - 1] = x_o
except IndexError:
print('Type Numbers Between Only 1 And 9')
if flag == 1:
flag = 2
elif flag == 2:
flag = 1
show_board()
# Checking The Winner Of The Game
# for horizontal X
if board[0] == board[1] == board[2] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[3] == board[4] == board[5] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[6] == board[7] == board[8] == 'X':
one = 2
print('The Winner Is Player "X"!')
# for Daigonal X
elif board[0] == board[4] == board[8] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[2] == board[4] == board[6] == 'X':
one = 2
print('The Winner Is Player "X"!')
# for Vertical X
elif board[1] == board[4] == board[7] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[2] == board[5] == board[8] == 'X':
one = 2
print('The Winner Is Player "X"!')
elif board[0] == board[3] == board[6] == 'X':
one = 2
print('The Winner Is Player "X"!')
# for horizontal O
elif board[0] == board[1] == board[2] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[3] == board[4] == board[5] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[6] == board[7] == board[8] == 'O':
one = 2
print('The Winner Is Player "O"!')
# for Diagonal O
elif board[0] == board[4] == board[8] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[2] == board[4] == board[6] == 'O':
one = 2
print('The Winner Is Player "O"!')
# for Vertical 0
elif board[1] == board[4] == board[7] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[2] == board[5] == board[8] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[0] == board[3] == board[6] == 'O':
one = 2
print('The Winner Is Player "O"!')
elif board[0] != ' ' and board[1] != ' ' and board[2] != ' ' and board[3] != ' ' and board[4] != ' ' and board[5] != ' ' and board[6] != ' ' and board[7] != ' ' and board[8] != ' ':
print('The Match Is A Tie!')
one = 2
main()
So, as you can see I'm using a lot of if statements for checking the winner of the game. How can I avoid that and do it in fewer lines.
You can replace them with some loops like:
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
def show_board():# for showing the tic-tac-toe board
print(' | ' + str(board[0]) + ' | ' +
str(board[1]) + ' | ' + str(board[2]) + ' | ')
print(' | ' + str(board[3]) + ' | ' +
str(board[4]) + ' | ' + str(board[5]) + ' | ')
print(' | ' + str(board[6]) + ' | ' +
str(board[7]) + ' | ' + str(board[8]) + ' | ')
def main():
one = 1
flag = 1
show_board()
while one == 1:
if flag == 1:
x_o = 'X'
if flag == 2:
x_o = 'O'
pos = int(input('Player "' + x_o + '" Turn: '))
if x_o == 'o':
x_o = 'O'
if x_o == 'x':
x_o = 'X'
if board[pos - 1] == 'O' or board[pos - 1] == 'O':
print('That Place Is Already Filled By Player "0"')
if board[pos - 1] == 'X' or board[pos - 1] == 'X':
print('That Place Is Already Filled By Player "X"')
else:
try:
board[pos - 1] = x_o
except IndexError:
print('Type Numbers Between Only 1 And 9')
if flag == 1:
flag = 2
elif flag == 2:
flag = 1
show_board()
# Checking The Winner Of The Game
won = False
for turn in ('X', 'O'):
# horizontal
if not won:
for i in (0, 3, 6):
if all(board[i + k] == turn for k in range(3)):
won = True
break
# vertical
if not won:
for i in range(3):
if all(board[i + k] == turn for k in (0, 3, 6)):
won = True
break
# diagonal
if not won:
if all(board[k] == turn for k in (0, 4, 8)) or \
all(board[k] == turn for k in (2, 4, 6)):
won = True
# handle winning
if won:
one = 2
print(f'The Winner Is Player "{turn}"!')
break
# handle a tie
if not won and all(square != ' ' for square in board):
one = 2
print('The Match Is A Tie!')
main()
(You can probably also polish/simplify the rest of the code quite a bit)
EDIT
Here is some similar code simplified / polished / expanded to:
handle boards of arbitrary sizes
correctly handle non-numerical input
use more functions
get rid of redundant variables
NUM_ROWS = 3
NUM_COLS = 3
NUM_WIN = 3
BOARD_SIZE = NUM_ROWS * NUM_COLS
EMPTY = ' '
BOARD = [EMPTY] * BOARD_SIZE
TURNS = 'X', 'O'
def show_board(board):
"""Show the tic-tac-toe board."""
for i in range(0, BOARD_SIZE, NUM_COLS):
print(' | ' + ' | '.join(board[i:i + NUM_COLS]) + ' | ')
def ij(i, j):
"""Convert (row, col) to board index."""
return i + NUM_COLS * j
def check_winner(board, turn):
"""Check if there is a winner."""
# horizontal
for i in range(NUM_ROWS):
for j in range(NUM_COLS - NUM_WIN + 1):
if all(board[ij(i, j + k)] == turn for k in range(NUM_WIN)):
return True
# vertical
for i in range(NUM_ROWS - NUM_WIN + 1):
for j in range(NUM_COLS):
if all(board[ij(i + k, j)] == turn for k in range(NUM_WIN)):
return True
# diagonal
for i in range(NUM_ROWS - NUM_WIN + 1):
for j in range(NUM_COLS - NUM_WIN + 1):
K = NUM_WIN
if all(board[ij(i + k, j + k)] == turn for k in range(NUM_WIN)):
return True
if all(board[ij(i + NUM_WIN - k - 1, j + k)] == turn
for k in range(NUM_WIN)):
return True
def check_tie(board):
"""Check if tie."""
return all(square != EMPTY for square in board)
def next_turn(turn):
"""Advance to next turn."""
return TURNS[(TURNS.index(turn) + 1) % 2]
def main():
"""Tic-tac-toe game."""
turn = TURNS[0]
show_board(BOARD)
while True:
valid_input = False
while not valid_input:
try:
choice = int(input(f'Player `{turn}` turn: '))
valid_input = (1 <= choice <= BOARD_SIZE)
if not valid_input:
raise ValueError
except ValueError:
print(f'Type numbers between 1 and {BOARD_SIZE} only.')
else:
idx = choice - 1
if BOARD[idx] != EMPTY:
print(f'Position `{idx}` already taken by `{BOARD[idx]}`')
else:
BOARD[idx] = turn
show_board(BOARD)
won = check_winner(BOARD, turn)
if won:
print(f'The winner is player `{turn}`!')
break
# handle a tie
if not won and check_tie(BOARD):
print('The match is a tie!')
break
turn = next_turn(turn)
if __name__ == '__main__':
main()
Please check mnk-game's source code for a similar implementation using NumPy and classes (especially Board.py). DISCLAIMER: I am the author of the package.
EDIT 2
Note that for tic-tac-toe only, check_winner() could be shortend using an approach similar to what #rusu_ro1 proposed :
WIN_CASES = [
[0, 1, 2], [3, 4, 5], [6, 7, 8], # horizontal
[0, 3, 6], [1, 4, 7], [2, 5, 8], # vertical
[0, 4, 8], [2, 4, 6], # diagonal
]
def check_winner(board, turn, win_cases=WIN_CASES):
"""Check if there is a winner."""
for win_case in win_cases:
if all(board[i] == turn for i in win_case):
return True
import random as rnd
size = 3
## random board to test
board = [[rnd.choice(["X", "O"]) for _ in range(size)] for _ in range(size)]
print(board)
def check_winner(board):
for mark in ["X", "O"]:
## count mark in all rows
count_in_rows = [row.count(mark) for row in board]
## count mark in all columns
count_in_columns = [ [board[row_n][col_n] for row_n in range(size)].count(mark) for col_n in range(size)]
## count mark in fwd diagonal
count_in_diag = [[board[i][i] for i in range(size)].count(mark)]
## count in backward diagonal
count_in_diag.append([board[i][size-i-1] for i in range(size)].count(mark))
print((count_in_rows + count_in_columns + count_in_diag))
## if there is 3 count of mark in any rows, columns or diagonal
if 3 in (count_in_rows + count_in_columns + [count_in_diag]):
print(f"winner is {mark}")
return mark
return
check_winner(board)
you can definition o_list =['o', 'o', 'o'] and x_list = ['x', 'x', 'x']
and then just comparison them like:
#l = board
if(l[0:3] == o_list or l[3:6] == o_list or l[6:9] == o_list or l[0:9:3] == o_list or l[1:9:3] == o_list or l[8:0:-3] == o_list):
print('The Winner Is Player "O"!')
same as for x_list.
;)
o_list =['o', 'o', 'o']
x_list =['x', 'x', 'x']
board = [' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
def show_board():# for showing the tic-tac-toe board
print(' | ' + str(board[0]) + ' | ' +
str(board[1]) + ' | ' + str(board[2]) + ' | ')
print(' | ' + str(board[3]) + ' | ' +
str(board[4]) + ' | ' + str(board[5]) + ' | ')
print(' | ' + str(board[6]) + ' | ' +
str(board[7]) + ' | ' + str(board[8]) + ' | ')
def main():
one = 1
flag = 1
o_list =['o', 'o', 'o']
x_list =['x', 'x', 'x']
show_board()
while one == 1:
if flag == 1:
x_o = 'X'
if flag == 2:
x_o = 'O'
pos = int(input('Player "' + x_o + '" Turn: '))
if x_o == 'o':
x_o = 'O'
if x_o == 'x':
x_o = 'X'
if board[pos - 1] == 'O' or board[pos - 1] == 'O':
print('That Place Is Already Filled By Player "0"')
if board[pos - 1] == 'X' or board[pos - 1] == 'X':
print('That Place Is Already Filled By Player "X"')
else:
try:
board[pos - 1] = x_o
except IndexError:
print('Type Numbers Between Only 1 And 9')
if flag == 1:
flag = 2
elif flag == 2:
flag = 1
show_board()
# Checking The Winner Of The Game
# for horizontal X
if(board[0:3] == x_list or board[3:6] == x_list or board[6:9] == x_list or board[0:9:3] == x_list or board[1:9:3] == x_list or board[8:0:-3] == x_list):
one = 2
print('The Winner Is Player "X"!')
if(board[0:3] == o_list or board[3:6] == o_list or board[6:9] == o_list or board[0:9:3] == o_list or board[1:9:3] == o_list or board[8:0:-3] == o_list):
one = 2
print('The Winner Is Player "O"!')
elif board[0] != ' ' and board[1] != ' ' and board[2] != ' ' and board[3] != ' ' and board[4] != ' ' and board[5] != ' ' and board[6] != ' ' and board[7] != ' ' and board[8] != ' ':
print('The Match Is A Tie!')
one = 2
main()
You can use this functions(input:board and a player's letter, output: True if that player has won):
def isWinner(board, letter):
return (
(board[1] == board[2] == board[3] == letter) or
(board[4] == board[5] == board[6] == letter) or
(board[7] == board[8] == board[9] == letter) or
(board[7] == board[4] == board[1] == letter) or
(board[8] == board[5] == board[2] == letter) or
(board[9] == board[6] == board[3] == letter) or
(board[7] == board[5] == board[3] == letter) or
(board[9] == board[5] == board[1] == letter))
for checking the winner you can use:
from operator import itemgetter
from itertools import chain
winning_cases = {'diags' : [[0, 4, 8], [2, 4, 6]],
'rows': [[0, 1, 2], [3, 4, 5], [6, 7, 8]],
'cols': [[0, 3, 6], [1, 4, 7], [2, 5, 8]]}
def check_winner(board=board):
for case in chain(*winning_cases.values()):
candidates = set(itemgetter(*case)(board))
if len(candidates) == 1 and '' not in candidates: # check if a diag, row or col has only one charcter
winner, = candidates
return winner
return None
for example:
board = ['X', 'X', 'O', 'X', 'O','O', 'X', 'O', 'X']
check_winner(board)
output:
X
the method check_winner will return the winner if there is one, otherwise None
Related
I recently tried creating a simple Tic Tac Toe AI with minimax (with help from YouTube), but I can't get it to work. The algorithm just spits out the first value it checks instead of going through all of them and giving the best one.
I tried copying the code from the YouTube video but it still doesn't work, can someone tell me what's wrong?
import math
import random
print()
board = {1: ' ', 2: ' ', 3: ' ',
4: ' ', 5: ' ', 6: ' ',
7: ' ', 8: ' ', 9: ' '}
computerLetter = 'X'
playerLetter = 'O'
def print_board(board=board):
for i in range(1, 8, 3):
print('|' + board[i] + '|' + board[i + 1] + '|' + board[i + 2] + '|')
if i < 7:
print('-' * 13)
print()
def space_is_free(position):
if board[position] == ' ':
return True
else:
return False
def free_spaces(board=board):
freeSpaces = 0
for key in board.keys():
if key == ' ':
freeSpaces += 1
return freeSpaces
def make_move(letter, position):
if space_is_free(position):
board[position] = ' ' + letter + ' '
print_board(board)
if check_for_win(board):
if letter == 'O':
print("You win!!")
exit()
else:
print("The computer wins. Better luck next time!")
exit()
elif check_for_tie(board):
print("It's a tie! Well played.")
exit()
else:
print("Invalid choice.")
position = int(input("Enter new position: "))
make_move(letter, position)
def check_for_win(board=board):
if board[1] == board[2] == board[3] != ' ' or board[4] == board[5] == board[6] != ' ' or board[7] == board[8] \
== board[9] != ' ' or board[1] == board[4] == board[7] != ' ' or board[2] == board[5] == board[6] != \
' ' or board[3] == board[6] == board[9] != ' ' or board[1] == board[5] == board[9] != ' ' or board[3]\
== board[5] == board[7] != ' ':
return True
else:
return False
def check_for_win_letter(letter):
if board[1] == board[2] == board[3] == ' ' + letter + ' ' or board[4] == board[5] == board[6] == ' ' + letter + ' '\
or board[7] == board[8] == board[9] == ' ' + letter + ' ' or board[1] == board[4] or board[7] == ' ' +\
letter + ' ' or board[2] == board[5] or board[6] == ' ' + letter + ' ' or board[3] == board[6] or board[9]\
== ' ' + letter + ' ' or board[1] == board[5] == board[9] == ' ' + letter + ' ' or board[3] == board[5] ==\
board[7] == ' ' + letter + ' ':
return True
else:
return False
def check_for_tie(board=board):
for key in board.keys():
if board[key] == ' ':
return False
else:
return True
def player_move(playerLetter='O'):
if free_spaces(board) >= 9:
print_board(board)
position = int(input("Enter position (1-9): "))
make_move(playerLetter, position)
def computer_move(computerLetter='X'):
if free_spaces(board) == 9:
make_move(computerLetter, 5)
else:
bestScore = -math.inf
bestPosition = 0
for key in board.keys():
if space_is_free(key):
board[key] = ' ' + computerLetter + ' '
score = minimax(board, 0, False)
board[key] = ' '
if score > bestScore:
bestScore = score
bestPosition = key
make_move(computerLetter, bestPosition)
print(f"Computer moves to {bestPosition}.")
def minimax(board, depth, isMaximising):
if check_for_win_letter('X'):
return 1 * (free_spaces(board) + 1)
elif check_for_win_letter('O'):
return -1 * (free_spaces(board) + 1)
elif check_for_tie(board):
return 0
if isMaximising:
bestScore = -math.inf
for key in board.keys():
if space_is_free(key):
board[key] = ' ' + computerLetter + ' '
score = minimax(board, depth + 1, False)
board[key] = ' '
bestScore = max(score, bestScore)
return bestScore
else:
bestScore = math.inf
for key in board.keys():
if space_is_free(key):
board[key] = ' ' + playerLetter + ' '
score = minimax(board, depth + 1, True)
board[key] = ' '
bestScore = min(score, bestScore)
return bestScore
while not check_for_win(board):
computer_move('X')
player_move('O')
# gameState = input("Would you like to play again? (y/n)")
#
# if gameState.lower() == 'y':
# main()
# elif gameState.lower() == 'n':
# exit()
# else:
# print("Invalid choice.")
I tried changing the computer and player letters, and whether the computer was maximising or minimising but it didn't work.
I think I have found what is wrong with your code, in the minmax function the first if, elif, else statement always ends with a return statement.
def minimax(board, depth, isMaximising):
if check_for_win_letter('X'):
return 1 * (free_spaces(board) + 1)
elif check_for_win_letter('O'):
return -1 * (free_spaces(board) + 1)
elif check_for_tie(board):
return 0
The else statement is the reason it is failing.
When a return statement is called, it ends the function returning the variable stated, in this case it will always be a number between -9 and 9, and does not run the next block of code, ruining the computer's process to find the best/worst place to play. the else statement means that even if the previous statements are false, it will always return zero, ending the function and halting the process of the next block of code.
I hope this helps! :)
Okay I figured out the problem, it was actually a bunch of logical errors in the functions which were checking for a winner and the winner letter, a few typos per say.
Error 1:
def check_for_win(board=board):
if board[1] == board[2] == board[3] != ' ' or board[4] == board[5] == board[6] != ' ' or board[7] == board[8] \
== board[9] != ' ' or board[1] == board[4] == board[7] != ' ' or ****board[2] == board[5] == board[6]**** != \ # board[6] should be board[8]
' ' or board[3] == board[6] == board[9] != ' ' or board[1] == board[5] == board[9] != ' ' or board[3]\
== board[5] == board[7] != ' ':
return True
Error 2:
def check_for_win_letter(letter):
if board[1] == board[2] == board[3] == ' ' + letter + ' ' or board[4] == board[5] == board[6] == ' ' + letter + ' '\
or board[7] == board[8] == board[9] == ' ' + letter + ' ' or board[1] == board[4] ****or board[7]**** == ' ' +\
letter + ' ' or board[2] == board[5] ****or board[6]**** == ' ' + letter + ' ' or board[3] == board[6] ****or board[9]****\
== ' ' + letter + ' ' or board[1] == board[5] == board[9] == ' ' + letter + ' ' or board[3] == board[5] ==\
board[7] == ' ' + letter + ' ':
return True
The statements within asterisks (*) are the errors, the or statements should be == and the board[6] should again be board[8].
I try to make a tic tac toe game and I get:
'str' object is not callable
as error. No idea what to do.
from IPython.display import clear_output
def display_board (board):
clear_output()
print (' ' + board [7] + '|' + board [8] + '|' + board[9])
print (' ' + board [4] + '|' + board [5] + '|' + board[6])
print (' ' + board [1] + '|' + board [2] + '|' + board[3])
def player_input():
marker = " "
while marker != "X" and marker != "O":
marker = input ('Igralec 1: izberi X ali O: ').upper()
if marker == 'X':
return ('X', 'O')
else:
return ('O', 'X')
def place_marker (board, marker, position):
board[position]= marker
def win_check (board, mark):
return ((board[1] == board[2] == board[3] == mark) or #vrsta 1
(board[4] == board[5] == board[6] == mark) or #vrsta 2
(board[5] == board[6] == board[7] == mark) or #vrsta 3
(board[8] == board[5] == board[2] == mark) or #stolpec 2
(board[9] == board[6] == board[3] == mark) or #stolpec 3
(board[7] == board[4] == board[1] == mark) or #stolpec 4
(board[3] == board[5] == board[7] == mark) or #diagonala
(board[1] == board[5] == board[9] == mark)) #diagonala
import random
def choose_first():
flip= random.randint (0,1)
if flip== 0:
return 'Igralec 1'
else:
return 'Player 2'
def space_check (board, position):
board[position] ==' '
def full_board_check (board):
for i in range (1,10):
if space_check (board, i):
return False
return True
def player_choice (board):
position= 0
while position not in [1,2,3,4,5,6,7,8,9] or not space_check (board, position):
position = int(input('Izberi pozicijo: (1-9) '))
return position
def replay():
choice = input ('Želiš še enkrat igrat (Y or N)? ')
return choice ('Y')
print (' Hello, pri tri v vrsto!')
while True:
the_board=[""] *10
player1_marker,player2_marker = player_input()
turn= choose_first()
print= (turn+ ' je prvi igralec!')
play_game= input (' Pripravljeni za igro? y or n ')
if play_game== 'y':
game_on= True
else:
game_on= False
##game time
while game_on:
#igralec 1
if turn== 'Player 1':
display_board(the_board)
position= player_choice(the_board)
place_marker(the_board,player1_marker,position)
#check if they won
if win_check(the_board,player1_marker):
display_board(the_board)
print ('Igralec 1 je zmagovalec!')
game_on = False
else:
if full_board_check(the_board):
display_board(the_board)
print ("Izanačeno!")
game_on= False
else:
turn = 'Igralec 2'
else:
#igralec 2
display_board(the_board)
position= player_choice(the_board)
place_marker(the_board,player2_marker,position)
#check if they won
if win_check(the_board,player2_marker):
display_board(the_board)
print ('Igralec 2 je zmagovalec!')
game_on = False
else:
if full_board_check(the_board):
display_board(the_board)
print ("Izanačeno!")
game_on= False
else:
turn = 'Igralec 1'
if not replay():
break
Errors are:
49 display_board(the_board)
\AppData\Local\Temp/ipykernel_10492/3794783463.py in display_board(board)
print (' ' + board [7] + '|' + board [8] + '|' + board[9])
TypeError: 'str' object is not callable
TypeError
1 print (' Hello pri tri v vrsto!')
2
3 while True:
TypeError: 'str' object is not callable
This line of code:
print= (turn+ ' je prvi igralec!')
Should be written like this:
print(turn+ ' je prvi igralec!')
You can find what goes wrong with the error description hints ;)
You have the typo = in print(), the fix would be:
print(turn + ' je prvi igralec!')
to prevent such cases install the linter, like flake8 or pylint, they could help you to improve your code. Also check the black formatting tool to improve readability.
I am a complete beginner with Python and coding in general. I am making a Tic Tac Toe game in Python as part of the online course I am studying.
I've struggled with getting my head around the nitty gritty of how functions work and can be utilised. I have had to follow the course notes quite closely to try and understand what is happening once the code starts fitting together. Can't find similar problems on here so it can't be an issue with the course notes!
When I run the programme, it skips my position_choice() function, displays the empty board and then asks to replay. I feel I'm missing some basic issue like indentation, but would really appreciate if anyone is able to spot a problem with the function itself or the code set up? It follows the course notes structure almost identically and I'm at a loss!
Here are the functions:
from IPython.display import clear_output
import random
def display_board(board):
clear_output()
print(' ' + board[7] + ' ' + '|' + ' ' + board[8] + ' ' + '|' + ' ' + board[9] + ' ')
print('- - - - - -')
print(' ' + board[4] + ' ' + '|' + ' ' + board[5] + ' ' + '|' + ' ' + board[6] + ' ')
print('- - - - - -')
print(' ' + board[1] + ' ' + '|' + ' ' + board[2] + ' ' + '|' + ' ' + board[3] + ' ')
def player_choice():
player1 = input('Choose your marker: '.upper())
while True:
if player1.upper() == 'X':
player2 = 'O'
print('\nPlayer 1 is ' + player1.upper() + '\nPlayer 2 is ' + player2 + '.')
return player1.upper(), player2
elif player1.upper() == 'O':
player2 = 'X'
print('\nPlayer 1 is ' + player1.upper() + '\nPlayer 2 is ' + player2 + '.')
return player1.upper(), player2
else:
print('Sorry, that is not a valid marker. Please choose either O or X.')
player1 = input('Choose your marker: '.upper())
def place_marker(board, marker, position):
board[position] = marker
def win_check(position, mark):
return ((position[7] == position[8] == position[9] == mark)
or (position[4] == position[5] == position[6] == mark)
or (position[1] == position[2] == position[3] == mark)
or (position[1] == position[5] == position[9] == mark)
or (position[7] == position[5] == position[3] == mark)
or (position[7] == position[4] == position[1] == mark)
or (position[8] == position[5] == position[2] == mark)
or (position[9] == position[6] == position[3] == mark))
def choose_first():
rand_int = random.randint(1,2)
if rand_int == 1:
print('Player 1 goes first')
return '1'
if rand_int == 2:
print('Player 2 goes first')
return '2'
def space_check(board, position):
return board[position] == ' '
def full_board_check(board):
for position in range(1,10):
if space_check(board, position):
return False
return True
def position_choice(board):
position = 0
while position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position):
position = int(input('Please choose your position: '))
return position
def replay():
return input('Do you want to play again?').lower().startswith('y')
def play_game():
play_game = input('Do you want to play?')
if play_game.lower()[0] == 'y':
return True
else:
return False
And here's the programme code. Why does it just display the empty board, skip asking for the position, and ask for the replay? Any help would keep up my stalling motivation!!
print('Welcome to Tic Tac Toe!')
while play_game():
theboard = [' '] * 10
player1_marker, player2_marker = player_choice()
turn = choose_first()
if turn == 1:
display_board(theboard)
position = position_choice(theboard)
place_marker(theboard, player1_marker, position)
if win_check(theboard, player1_marker):
display_board(theboard)
print('Player 1 is the winner!')
replay()
else:
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
replay()
else:
turn == 2
else:
display_board(theboard)
position = position_choice(theboard)
place_marker(theboard, player2_marker, position)
if win_check(theboard, player2_marker):
display_board(theboard)
print('Player 2 is the winner!')
replay()
else:
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
replay()
else:
turn == 1
if not replay():
break
There are several problems :
The choose_first returns a String instead of an integer.
The method called in the while, always ask if you want to play.
You recreate a new board on each loop, you have to declare it before the loop if you don't want to lose it.
At the end of each loop you ask each times if you want to replay
to change the turn variable you should do turn = 2 instead of using double equals witch is comparing equality.
And when you want to "replay", don't forget to reset the board.
To debug this, you should comment a part of your code. And run it step by step. By doing this, you will find were are the errors.
Here is the code, the game will works but you may still want to ad some improvements.
theboard = [' '] * 10
if play_game():
player1_marker, player2_marker = player_choice()
turn = choose_first()
while not full_board_check(theboard):
display_board(theboard)
position = position_choice(theboard)
if turn == 1:
place_marker(theboard, player1_marker, position)
if win_check(theboard, player1_marker):
display_board(theboard)
print('Player 1 is the winner!')
if replay():
theboard = [' '] * 10
else:
break
turn = 2
else:
place_marker(theboard, player2_marker, position)
if win_check(theboard, player2_marker):
display_board(theboard)
print('Player 2 is the winner!')
if replay():
theboard = [' '] * 10
else:
break
turn = 1
if full_board_check(theboard):
display_board(theboard)
print('The game is a tie!')
if replay():
theboard = [' '] * 10
else:
break
Why does it just display the empty board, skip asking for the position, and ask for the replay?
position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position) - this condition isn't working, the logic is wrong.
>>> theboard = [' '] * 10
>>> theboard
[' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ']
>>> position = 0
>>> position not in [1,2,3,4,5,6,7,8,9] and not space_check(theboard, position)
False
>>>
Here is one way to refactor position_choice
def position_choice(board):
#print(board)
#position = 0
valid = False
# keep asking till thay give a valid answer
while not valid:
position = int(input('Please choose your position (1-9): '))
valid = position in [1,2,3,4,5,6,7,8,9]
valid = valid and space_check(board, position)
return position
## OLD STUFF
## while position not in [1,2,3,4,5,6,7,8,9] and not space_check(board, position):
## position = int(input('Please choose your position: '))
##
## return position
Asking the user for input until they give a valid response
How to debug small programs
This is my first ever post on here, as usually I just follow tutorials on Youtube or whatever, but I really wanted to do a project mainly by myself. I made a little Tic Tac Toe game I was pretty proud of today in Python, but there is one thing that doesn't work. The win conditions. I put in the winLoseCondition() in different spots before, but it doesn't work. Once it gets to there, it either says I lose or win. I don't know how it decides before there is enough information. One other thing, sometimes the computer overwrites one of the places the player has gone, and I don't know why. I know I probably did 100 things wrong programming this and there is a way easier way of doing it, but there are many like it but this one is mine. So, the question I really am asking here is: How do I fix my code so that my win conditions, when fulfilled correctly, actually end the game at the correct time, and not at a random time when I place the function somewhere. Also, as a bonus, why is my computer/random O placing bot overwriting some of where the player places their X's? I know I could improve the thing that places the O's, but that is for another night.
import random
import sys
winCondition = False
def winLoseCondition():
if board[1] and board[2] and board[3] == 'X':
print('You win!')
sys.exit()
if board[1] and board[2] and board[3] == 'O':
print('You lose...')
sys.exit()
if board[1] and board[5] and board[9] == 'X':
print('You win!')
sys.exit()
if board[1] and board[5] and board[9] == 'O':
print('You lose...')
sys.exit()
if board[3] and board[5] and board[7] == 'X':
print('You win!')
sys.exit()
if board[3] and board[5] and board[7] == 'O':
print('You lose...')
sys.exit()
if board[1] and board[4] and board[7] == 'X':
print('You win!')
sys.exit()
if board[1] and board[4] and board[7] == 'O':
print('You lose...')
sys.exit()
if board[2] and board[5] and board[8] == 'X':
print('You win!')
sys.exit()
if board[2] and board[5] and board[8] == 'O':
print('You lose...')
sys.exit()
if board[3] and board[6] and board[9] == 'O':
print('You lose...')
sys.exit()
if board[3] and board[6] and board[9] == 'X':
print('You win!')
sys.exit()
if board[4] and board[5] and board[6] == 'O':
print('You lose...')
sys.exit()
if board[4] and board[5] and board[6] == 'X':
print('You win!')
sys.exit()
if board[7] and board[8] and board[9] == 'X':
print('You win!')
sys.exit()
if board[7] and board[8] and board[9] == 'O':
print('You lose...')
sys.exit()
while winCondition == False:
board = {1: ' ',2: ' ',3: ' ',
4: ' ',5: ' ', 6: ' ',
7: ' ', 8: ' ', 9: ' '}
print('We are going to play Tic Tac Toe')
firstPlayerMove = input('What is your first move? (Input a number 1:9. 1 is the top left box. 9 is the bottom right box.)')
#Player's First Move
if int(firstPlayerMove) == 1:
board[1] = 'X'
if int(firstPlayerMove) == 2:
board[2] = 'X'
if int(firstPlayerMove) == 3:
board[3] = 'X'
if int(firstPlayerMove) == 4:
board[4] = 'X'
if int(firstPlayerMove) == 5:
board[5] = 'X'
if int(firstPlayerMove) == 6:
board[6] = 'X'
if int(firstPlayerMove) == 7:
board[7] = 'X'
if int(firstPlayerMove) == 8:
board[8] = 'X'
if int(firstPlayerMove) == 9:
board[9] = 'X'
#Computer's First Move:
firstComputerMove = random.randint(1,9)
while firstComputerMove == int(firstPlayerMove):
firstComputerMove = random.randint(1,9)
while firstComputerMove != int(firstPlayerMove):
if firstComputerMove == 1:
board[1] = 'O'
break
if firstComputerMove == 2:
board[2] = 'O'
break
if firstComputerMove == 3:
board[3] = 'O'
break
if firstComputerMove == 4:
board[4] = 'O'
break
if firstComputerMove == 5:
board[5] = 'O'
break
if firstComputerMove == 6:
board[6] = 'O'
break
if firstComputerMove == 7:
board[7] = 'O'
break
if firstComputerMove == 8:
board[8] = 'O'
break
if firstComputerMove == 9:
board[9] = 'O'
break
#Player's Second Move
print('This is what the board looks like:')
print(board[1] + '|' + board[2] + '|' + board[3])
print('_ _ _')
print(board[4] + '|' + board[5] + '|' + board[6])
print('_ _ _')
print(board[7] + '|' + board[8] + '|' + board[9])
secondPlayerMove = input('What is your second move? ')
while int(secondPlayerMove) == int(firstPlayerMove):
secondPlayerMove = input('That space is already occupied. Please input a different number ')
while int(secondPlayerMove) == firstComputerMove:
secondPlayerMove = input('That space is already occupied. Please input a different number ')
while int(secondPlayerMove) != int(firstPlayerMove) or firstComputerMove:
if int(secondPlayerMove) == 1:
board[1] = 'X'
break
if int(secondPlayerMove) == 2:
board[2] = 'X'
break
if int(secondPlayerMove) == 3:
board[3] = 'X'
break
if int(secondPlayerMove) == 4:
board[4] = 'X'
break
if int(secondPlayerMove) == 5:
board[5] = 'X'
break
if int(secondPlayerMove) == 6:
board[6] = 'X'
break
if int(secondPlayerMove) == 7:
board[7] = 'X'
break
if int(secondPlayerMove) == 8:
board[8] = 'X'
break
if int(secondPlayerMove) == 9:
board[9] = 'X'
break
#Computer's Second Move
secondComputerMove = random.randint(1,9)
while int(secondComputerMove) == int(firstPlayerMove):
secondComputerMove = random.randint(1,9)
while int(secondComputerMove) == firstComputerMove:
secondComputerMove = random.randint(1,9)
while int(secondComputerMove) == int(secondPlayerMove):
secondComputerMove = random.randint(1,9)
while int(secondComputerMove) != int(firstPlayerMove) or firstComputerMove or int(secondPlayerMove):
if int(secondComputerMove) == 1:
board[1] = 'O'
break
if int(secondComputerMove) == 2:
board[2] = 'O'
break
if int(secondComputerMove) == 3:
board[3] = 'O'
break
if int(secondComputerMove) == 4:
board[4] = 'O'
break
if int(secondComputerMove) == 5:
board[5] = 'O'
break
if int(secondComputerMove) == 6:
board[6] = 'O'
break
if int(secondComputerMove) == 7:
board[7] = 'O'
break
if int(secondComputerMove) == 8:
board[8] = 'O'
break
if int(secondComputerMove) == 9:
board[9] = 'O'
break
#Player's Third Move
print('This is what the board looks like:')
print(board[1] + '|' + board[2] + '|' + board[3])
print('_ _ _')
print(board[4] + '|' + board[5] + '|' + board[6])
print('_ _ _')
print(board[7] + '|' + board[8] + '|' + board[9])
thirdPlayerMove = input('Please say where you want to move.')
while int(thirdPlayerMove) == int(firstPlayerMove):
thirdPlayerMove = input('Sorry, that space is taken, please try again.')
while int(thirdPlayerMove) == firstComputerMove:
thirdPlayerMove = input('Sorry, that space is taken, please try again.')
while int(thirdPlayerMove) == int(secondPlayerMove):
thirdPlayerMove = input('Sorry, that space is taken, please try again.')
while int(thirdPlayerMove) == secondComputerMove:
thirdPlayerMove = input('Sorry, that space is taken, please try again.')
while int(thirdPlayerMove) != int(firstPlayerMove) or firstComputerMove or int(secondPlayerMove) or secondComputerMove:
if int(thirdPlayerMove) == 1:
board[1] = 'X'
break
if int(thirdPlayerMove) == 2:
board[2] = 'X'
break
if int(thirdPlayerMove) == 3:
board[3] = 'X'
break
if int(thirdPlayerMove) == 4:
board[4] = 'X'
break
if int(thirdPlayerMove) == 5:
board[5] = 'X'
break
if int(thirdPlayerMove) == 6:
board[6] = 'X'
break
if int(thirdPlayerMove) == 7:
board[7] = 'X'
break
if int(thirdPlayerMove) == 8:
board[8] = 'X'
break
if int(thirdPlayerMove) == 9:
board[9] = 'X'
break
#Computer's Third Move
thirdComputerMove = random.randint(1,9)
while int(thirdComputerMove) == int(firstPlayerMove):
thirdComputerMove = random.randint(1,9)
while int(thirdComputerMove) == firstComputerMove:
thirdComputerMove = random.randint(1,9)
while int(thirdComputerMove) == int(secondPlayerMove):
thirdComputerMove = random.randint(1,9)
while int(thirdComputerMove) == secondComputerMove:
thirdComputerMove = random.randint(1,9)
while int(thirdComputerMove) == int(thirdPlayerMove):
thirdComputerMove = random.randint(1,9)
while int(thirdComputerMove) != int(firstPlayerMove) or firstComputerMove or int(secondPlayerMove) or secondComputerMove or int(thirdPlayerMove):
if int(thirdComputerMove) == 1:
board[1] = 'O'
break
if int(thirdComputerMove) == 2:
board[2] = 'O'
break
if int(thirdComputerMove) == 3:
board[3] = 'O'
break
if int(thirdComputerMove) == 4:
board[4] = 'O'
break
if int(thirdComputerMove) == 5:
board[5] = 'O'
break
if int(thirdComputerMove) == 6:
board[6] = 'O'
break
if int(thirdComputerMove) == 7:
board[7] = 'O'
break
if int(thirdComputerMove) == 8:
board[8] = 'O'
break
if int(thirdComputerMove) == 9:
board[9] = 'O'
break
#Player's Fourth Move
print('This is what the board looks like:')
print(board[1] + '|' + board[2] + '|' + board[3])
print('_ _ _')
print(board[4] + '|' + board[5] + '|' + board[6])
print('_ _ _')
print(board[7] + '|' + board[8] + '|' + board[9])
fourthPlayerMove = input('Where do you want to move?')
while int(fourthPlayerMove) == int(firstPlayerMove):
fourthPlayerMove = input('Sorry, that space is taken, please try again.')
while int(fourthPlayerMove) == firstComputerMove:
fourthPlayerMove = input('Sorry, that space is taken, please try again.')
while int(fourthPlayerMove) == int(secondPlayerMove):
fourthPlayerMove = input('Sorry, that space is taken, please try again.')
while int(fourthPlayerMove) == secondComputerMove:
fourthPlayerMove = input('Sorry, that space is taken, please try again.')
while int(fourthPlayerMove) == int(thirdPlayerMove):
fourthPlayerMove = input('Sorry, that space is taken, please try again.')
while int(fourthPlayerMove) == thirdComputerMove:
fourthPlayerMove = input('Sorry, that space is taken, please try again.')
while int(fourthPlayerMove) != int(firstPlayerMove) or firstComputerMove or int(secondPlayerMove) or secondComputerMove or int(thirdPlayerMove) or thirdComputerMove:
if int(fourthPlayerMove) == 1:
board[1] = 'X'
break
if int(fourthPlayerMove) == 2:
board[2] = 'X'
break
if int(fourthPlayerMove) == 3:
board[3] = 'X'
break
if int(fourthPlayerMove) == 4:
board[4] = 'X'
break
if int(fourthPlayerMove) == 5:
board[5] = 'X'
break
if int(fourthPlayerMove) == 6:
board[6] = 'X'
break
if int(fourthPlayerMove) == 7:
board[7] = 'X'
break
if int(fourthPlayerMove) == 8:
board[8] = 'X'
break
if int(fourthPlayerMove) == 9:
board[9] = 'X'
break
#Computer's Fourth Move
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) == int(firstPlayerMove):
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) == firstComputerMove:
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) == int(secondPlayerMove):
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) == secondComputerMove:
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) == int(thirdPlayerMove):
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) == thirdComputerMove:
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) == int(fourthPlayerMove):
fourthComputerMove = random.randint(1,9)
while int(fourthComputerMove) != int(firstPlayerMove) or firstComputerMove or int(secondPlayerMove) or secondComputerMove or int(thirdPlayerMove) or thirdComputerMove or int(fourthPlayerMove):
if int(fourthComputerMove) == 1:
board[1] = 'O'
break
if int(fourthComputerMove) == 2:
board[2] = 'O'
break
if int(fourthComputerMove) == 3:
board[3] = 'O'
break
if int(fourthComputerMove) == 4:
board[4] = 'O'
break
if int(fourthComputerMove) == 5:
board[5] = 'O'
break
if int(fourthComputerMove) == 6:
board[6] = 'O'
break
if int(fourthComputerMove) == 7:
board[7] = 'O'
break
if int(fourthComputerMove) == 8:
board[8] = 'O'
break
if int(fourthComputerMove) == 9:
board[9] = 'O'
break
#Player's Last Move
print('This is what the board looks like:')
print(board[1] + '|' + board[2] + '|' + board[3])
print('_ _ _')
print(board[4] + '|' + board[5] + '|' + board[6])
print('_ _ _')
print(board[7] + '|' + board[8] + '|' + board[9])
print('There is only one last spot.')
if board[1] == ' ':
print('You had to move to spot 1')
board[1] = 'X'
if board[2] == ' ':
print('You had to move to spot 2')
board[2] = 'X'
if board[3] == ' ':
print('You had to move to spot 3')
board[3] == 'X'
if board[4] == ' ':
print('You had to move to spot 4')
board[4] = 'X'
if board[5] == ' ':
print('You had to move to spot 5')
board[5] = 'X'
if board[6] == ' ':
print('You had to move to spot 6')
board[6] = 'X'
if board[7] == ' ':
print('You had to move to spot 7')
board[7] = 'X'
if board[8] == ' ':
print('You had to move to spot 8')
board[8] = 'X'
if board[9] == ' ':
print('You had to move to spot 9')
board[9] = 'X'
#Final Board
print('The final board looks like:')
print(board[1] + '|' + board[2] + '|' + board[3])
print('_ _ _')
print(board[4] + '|' + board[5] + '|' + board[6])
print('_ _ _')
print(board[7] + '|' + board[8] + '|' + board[9])
winCondition = True
print('The final board looks like:')
print(board[1] + '|' + board[2] + '|' + board[3])
print('_ _ _')
print(board[4] + '|' + board[5] + '|' + board[6])
print('_ _ _')
print(board[7] + '|' + board[8] + '|' + board[9])
I'm not that new to programming, but I haven't tried making too many things without following a tutorial before. This is my first attempt at a REAL project without following a video or copy-pasting code. I created a simple tic tac toe game, it works fine if both players manually choose positions, but when I tried to implement a simple AI using the minimax algorithm, it will play all of the AI moves at once and I have no idea why.
I reviewed the code so many times but I can't figure out why the AI can keep placing pieces/making moves when the player can only make 1 move. According to the code, only 1 move at a time should be allowed. What is going on? When it gets to the AI's turn, the AI places pieces until it wins, no regard for turn or anything. Player pieces are placed too, which is strange because Player needs to be prompted for selection input. I think the problem lies in the minimax function itself, but I can't pinpoint where. Any help would be greatly appreciated! Thank you so much. Full file:
import random
from time import sleep
from math import inf
PLAYER = 0
AI = 1
BOARD = [[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']]
#AVAILABLE = [[0,0],[0,1],[0,2],[1,0],[1,1],[1,2],[2,0],[2,1],[2,2]]
AVAILABLE = [1,2,3,4,5,6,7,8,9]
SELECTION = 0
TURN = random.randint(0, 1)
def display_board(board):
print(f'\t[{board[0][0]}] [{board[0][1]}] [{board[0][2]}]\n\t[{board[1][0]}] [{board[1][1]}] [{board[1][2]}]\n\t[{board[2][0]}] [{board[2][1]}] [{board[2][2]}]')
def convert_position(available_locations, position):
if position in available_locations:
available_locations.remove(position)
position -= 1
converted = (position // 3, position % 3)
return converted
def is_valid_location(board):
pass
def place_piece(board, position, player):
a, b = position
if a in [0, 1, 2] and b in [0, 1, 2]:
if board[a][b] == ' ' and player == PLAYER:
board[a][b] = 'X'
if board[a][b] == ' ' and player == AI:
board[a][b] = 'O'
def clear_board(board):
board = [[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']]
return board
def is_win_player(board):
if board[0][0] != ' ' and board[0][1] == board[0][0] and board[0][2] == board[0][0]:
if board[0][0] == 'X':
return True
if board[1][0] != ' ' and board[1][1] == board[1][0] and board[1][2] == board[1][0]:
if board[1][0] == 'X':
return True
if board[2][0] != ' ' and board[2][1] == board[2][0] and board[2][2] == board[2][0]:
if board[2][0] == 'X':
return True
if board[0][0] != ' ' and board[1][1] == board[0][0] and board[2][2] == board[0][0]:
if board[0][0] == 'X':
return True
if board[2][0] != ' ' and board[1][1] == board[2][0] and board[0][2] == board[2][0]:
if board[2][0] == 'X':
return True
if board[0][0] != ' ' and board[1][0] == board[0][0] and board[2][0] == board[0][0]:
if board[0][0] == 'X':
return True
if board[0][1] != ' ' and board[1][1] == board[0][1] and board[2][1] == board[0][1]:
if board[0][1] == 'X':
return True
if board[0][2] != ' ' and board[1][2] == board[0][2] and board[2][2] == board[0][2]:
if board[0][2] == 'X':
return True
def is_win_ai(board):
if board[0][0] != ' ' and board[0][1] == board[0][0] and board[0][2] == board[0][0]:
if board[0][0] == 'O':
return True
if board[1][0] != ' ' and board[1][1] == board[1][0] and board[1][2] == board[1][0]:
if board[1][0] == 'O':
return True
if board[2][0] != ' ' and board[2][1] == board[2][0] and board[2][2] == board[2][0]:
if board[2][0] == 'O':
return True
if board[0][0] != ' ' and board[1][1] == board[0][0] and board[2][2] == board[0][0]:
if board[0][0] == 'O':
return True
if board[2][0] != ' ' and board[1][1] == board[2][0] and board[0][2] == board[2][0]:
if board[2][0] == 'O':
return True
if board[0][0] != ' ' and board[1][0] == board[0][0] and board[2][0] == board[0][0]:
if board[0][0] == 'O':
return True
if board[0][1] != ' ' and board[1][1] == board[0][1] and board[2][1] == board[0][1]:
if board[0][1] == 'O':
return True
if board[0][2] != ' ' and board[1][2] == board[0][2] and board[2][2] == board[0][2]:
if board[0][2] == 'O':
return True
def score_eval(board):
for row in range(0, 3):
if board[row][0] == board[row][1] and board[row][1] == board[row][2]:
if board[row][0] == 'O':
return 10
if board[row][0] == 'X':
return -10
for col in range(0, 3):
if board[0][col] == board[1][col] and board[1][col] == board[2][col]:
if board[row][0] == 'O':
return 10
if board[row][0] == 'X':
return -10
if board[0][0] == board[1][1] and board[1][1] == board[2][2]:
if board[0][0] == 'O':
return 10
if board[0][0] == 'X':
return -10
if board[2][0] == board[1][1] and board[1][1] == board[0][2]:
if board[2][0] == 'O':
return 10
if board[2][0] == 'X':
return -10
def is_tie(board):
counter = 0
for array in board:
for index in array:
if index == ' ':
counter += 1
if counter == 0:
return True
def is_terminal(board):
return is_tie(board) or is_win_player(board) or is_win_ai(board)
def minimax(board, depth, maximizingPlayer, available_positions):
valid_locations = available_positions
print(valid_locations)
terminal = is_terminal(board)
if depth == 0 or terminal:
if terminal:
if is_win_ai(board):
return None, 99999999
if is_win_player(board):
return None, -99999999
if is_tie(board):
return None, 1
else:
return None, score_eval(board)
if maximizingPlayer:
value = -inf
selection = random.choice(valid_locations)
for num in valid_locations:
board_copy = board.copy()
position = convert_position(valid_locations, num)
place_piece(board_copy, position, AI)
new_score = minimax(board_copy, depth-1, False, valid_locations)[1]
if new_score > value:
value = new_score
selection = num
return selection, value
else:
value = inf
selection = random.choice(valid_locations)
for num in valid_locations:
board_copy = board.copy()
position = convert_position(valid_locations, num)
place_piece(board_copy, position, PLAYER)
new_score = minimax(board_copy, depth-1, True, valid_locations)[1]
if new_score < value:
value = new_score
selection = num
return selection, value
while SELECTION != 'QUIT':
print('\t< Tic Tac Toe >\n')
print('\tPlease make a selection:')
print("\t'PLAY' to play a game")
print("\t'QUIT' to exit application\n")
SELECTION = input('> ').upper()
if SELECTION != 'QUIT' and SELECTION != 'PLAY':
print(SELECTION)
print('Please enter a valid selection.')
elif SELECTION == 'PLAY':
game_over = False
while not game_over:
display_board(BOARD)
if is_tie(BOARD):
print('Tie game. No winner.')
input('Press any key to continue...')
game_over = True
elif TURN == PLAYER:
print("Player's turn!")
position = int(input('Please enter a number 1 - 9 to make a mark: '))
selection = convert_position(AVAILABLE, position)
place_piece(BOARD, selection, PLAYER)
if is_win_player(BOARD):
print('Player has won the game!')
display_board(BOARD)
game_over = True
elif TURN == AI:
print("AI's turn!")
sleep(0.9)
x, y = minimax(BOARD, 7, True, AVAILABLE) #x = position, y = score
selection = convert_position(AVAILABLE, x)
place_piece(BOARD, selection, AI)
if is_win_ai(BOARD):
print('AI has won the game!')
display_board(BOARD)
game_over = True
TURN += 1
TURN = TURN % 2
print(AVAILABLE)
BOARD = clear_board(BOARD)
AVAILABLE = [1,2,3,4,5,6,7,8,9]
One of the possible culprits is the bit which attempts to "clone" the board in your minimax function:
board_copy = board.copy()
In Python, list.copy method returns a shallow copy of a list, which is essentially a new list with 3 elements which are references to the "rows" in your original board. Try using copy.deepcopy() documentation
import copy
...
board_copy = copy.deepcopy(board)