-4

I have been trying to get this to work for over a week now and cant seem to get it to choose the best possible move. Can someone take a look and help me out? I feel like I have missed something stupid.

Thanks!

from tkinter import *

import tkinter.messagebox
tk = Tk()
tk.title("Tic Tac Toe")

click = True

X = "X"
O = "O"
EMPTY = " "
TIE = "TIE"
NUM_SQUARES = 9

def new_board():
    """Create new game board."""
    board = []
    for square in range(NUM_SQUARES):
        board.append(EMPTY)
    return board



def Player1Win(board, i):

    if(board[0]==1 and board[1]==1 and board[2]==1)or(board[0]==1 and board[3]==1 and board[6]==1)or(board[2]==1 and board[5]==1 and board[8]==1)or(board[3]==1 and board[4]==1 and board[5]==1)or(board[6]==1 and board[7]==1 and board[8]==1)or(board[0]==1 and board[4]==1 and board[8]==1)or(board[2]==1 and board[4]==1 and board[6]==1)or(board[1]==1 and board[4]==1 and board[7]==1)or(board[0]==1 and board[3]==1 and board[6]==1):

        if(i==0):
          tkinter.messagebox.showinfo("Winner X won")

        return True
    else:
      return False

def Player2Win(board, i):
    if(board[0]==0 and board[1]==0 and board[2]==0)or(board[0]==0 and board[3]==0 and board[6]==0)or(board[2]==0 and board[5]==0 and board[8]==0)or(board[3]==0 and board[4]==0 and board[5]==0)or(board[6]==0 and board[7]==0 and board[8]==0)or(board[0]==0 and board[4]==0 and board[8]==0)or(board[2]==0 and board[4]==0 and board[6]==0)or(board[1]==0 and board[4]==0 and board[7]==0):

        if(i==0):
          tkinter.messagebox.showinfo("Winner O won")

        return True
    else:
        return False



board2=new_board()
board=new_board()

def legal_moves(board):
    """Create list of legal moves."""
    moves = []
    count = 0
    for square in range(NUM_SQUARES):
        if board[square] == EMPTY:
            count += 1
            moves.append(square)
    print(count)
    return moves

def minimax(board2):
  global click

  #Get all possible steps
  moves=legal_moves(board2)

  #Check copy board to win
  if(Player1Win(board2,2) == True):
    return 10
  if(Player2Win(board2,2) == True):
    return -10
  if(len(moves)==0):
    return 0

  j = 1000

  for i in moves:
    if click:
      click=True #change to Player X
      board2[i]=0 #This is a copy of the board is not the main
    else:
      click=False #to change Player O
      board2[i]=1 #This is a copy of the board is not the main

    v = minimax(board2) # Recursive call functions
    #  # Select the minimum number for O and maximum for X
    if j == 1000 or (click == False and j < v) or (click == True and v < j):
      j = v

    if click:
      return j-1 # If player O
    else:
      return j+1 # If player X





def bestMove():
  global click

  # Get all possible steps
  moves=legal_moves(board)

  # Move all the data from the main board
  for k in range(NUM_SQUARES):
      board2.append(board[k])

  j = 1000
  best  = -1
  for i in moves:
    if click:
      click = False #change to Player X
      board2[i]=0
    else:
      click = True #change to Player O
      board2[i]=1
    v = minimax(board2)
    # Select the minimum number for O and maximum for X
    if j == 1000 or (click == False and j < v) or (click == True and v < j):
      j = v
      best = i

  return best

def Update(board):
  global click

  if button1["text"]=="X":
    board[0]=1
  if button2["text"]=="X":
      board[1]=1
  if button3["text"]=="X":
      board[2]=1
  if button4["text"]=="X":
      board[3]=1
  if button5["text"]=="X":
      board[4]=1
  if button6["text"]=="X":
      board[5]=1
  if button7["text"]=="X":
      board[6]=1
  if button8["text"]=="X":
      board[7]=1
  if button9["text"]=="X":
      board[8]=1

  if button1["text"]=="O":
      board[0]=0
  if button2["text"]=="O":
      board[1]=0
  if button3["text"]=="O":
      board[2]=0
  if button4["text"]=="O":
      board[3]=0
  if button5["text"]=="O":
      board[4]=0
  if button6["text"]=="O":
      board[5]=0
  if button7["text"]=="O":
      board[6]=0
  if button8["text"]=="O":
      board[7]=0
  if button9["text"]=="O":
      board[8]=0



def move(i):
  global click

  click = False
  if i == 0:
    button1["text"] = "O"
    board[0]=0
  elif i == 1:
    button2["text"] = "O"
    board[1]=0
  elif i == 2:
    button3["text"] = "O"
    board[2]=0
  elif i == 3:
    button4["text"] = "O"
    board[3]=0
  elif i == 4:
    button5["text"] = "O"
    board[4]=0
  elif i == 5:
    button6["text"] = "O"
    board[5]=0
  elif i == 6:
    button7["text"] = "O"
    board[6]=0
  elif i == 7:
    button8["text"] = "O"
    board[7]=0
  elif i == 8:
    button9["text"] = "O"
    board[8]=0


def checker(buttons):
    global click
    if buttons["text"] == " ":
        buttons["text"] = "X"
        click = True

    Update(board)
    best = bestMove()
    move(best)
    Player1Win(board, 0)
    Player2Win(board, 0)

buttons = StringVar()

button1 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button1))

button1.grid(row=1,column=0,sticky = S+N+E+W)

button2 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button2))

button2.grid(row=1,column=1,sticky = S+N+E+W)

button3 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button3))

button3.grid(row=1,column=2,sticky = S+N+E+W)

button4 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button4))

button4.grid(row=2,column=0,sticky = S+N+E+W)

button5 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button5))

button5.grid(row=2,column=1,sticky = S+N+E+W)

button6 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button6))

button6.grid(row=2,column=2,sticky = S+N+E+W)

button7 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button7))

button7.grid(row=3,column=0,sticky = S+N+E+W)

button8 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button8))

button8.grid(row=3,column=1,sticky = S+N+E+W)

button9 = Button(tk,text=" ",font=('Times 26 bold'), height = 4, width = 8, command =lambda:checker(button9))

button9.grid(row=3,column=2,sticky = S+N+E+W)

tk.mainloop()



print ("Please Begin Play")
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
Nick
  • 1
  • 1
  • Please read [mcve] (at the absolute minimum, *how does the GUI help?!*) – jonrsharpe Aug 10 '15 at 20:19
  • 1
    I don't know. But what I do know is you SHOULDN'T create 9 individual buttons but an array of 9 buttons in a for loop. Or write a line 425 characters long. – Eric Levieil Aug 11 '15 at 14:07

1 Answers1

3

I would suggest you add print statements to see what is happening. Start with printing "click" for each pass through the for() loop and also print what the return (j +- 1) and the value for "i" right before the return statements (and please don't use "i", "l", or "O" as single digit variable names as they can look like numbers, i.e, o=1, o=l). You can handle the really, really long and really, really, confusing line a lot better with a list of win combinations.

## a simple example that will require some modification by you
def check_for_winner(player, board):
    ## fill in the rest yourself
    win_combos=[[0, 1, 2], [3, 4, 5], [6, 7, 8], [0, 4, 8], [0, 3, 6]]

    for x, y, z in win_combos:
        print "checking", x, y, z
        if board[x] == board[y] == board[z]:
            print "**** We have a winner", player, x, y, z
            return True
    return False