# mysterious buggy behavior

Discussion in 'Python' started by Sean McIlroy, Jan 9, 2005.

1. ### Sean McIlroyGuest

While fiddling with a little script I ran into a problem that baffles
me completely. Maybe I'm missing something completely obvious, and
somebody out there can diagnose the problem at a glance. Anyway,
that's the hope. Here's the code (it plays tic tac toe):

"""
Something goes wrong with the "time saver" section of the function
makeMove. The section
needs to be there to ensure that the computer makes its move in a
reasonable amount of
time when it is making the first or the second move. That section of
code is so simple
that I can't even imagine what could be going wrong with it.
"""

"""
012
345
678
"""

ex,oh,blank = range(3)
lines = [(0,3,6),(1,4,7),(2,5,8),(0,1,2),(3,4,5),(6,7,8),(0,4,8),(2,4,6)]

def subs(board,player,i):
b = board[:]
b = player
return b

def valMove(board):
winners = [x for x in (ex,oh) for L in lines if
board[L[0]]==board[L[1]]==board[L[2]]==x]
if winners: return winners[0]==ex and (+1,None) or (-1,None)
if board.count(blank)==0: return (0,None)
player = (oh,ex)[board.count(ex)==board.count(oh)]
optimal = (min,max)[player==ex]
blankIndices = [i for i in range(9) if board==blank]
return optimal([(valMove(subs(board,player,i))[0],i) for i in
blankIndices])

BOARD = [blank]*9

def clickButton(i):
def f():
BOARD = ex
(topButtons,midButtons,botButtons)[i//3][i%3]['text'] = 'X'
return f

def newGame():
BOARD = [blank]*9
for x in topButtons+midButtons+botButtons: x['text'] = ''

def makeMove():
i = None
## <time saver>
if BOARD.count(blank)>=8:
for j in [4,0,2,6,8]:
if BOARD[j]==blank: i = j; break
## </time saver>
if i==None: i = valMove(BOARD)[1]
BOARD = oh
(topButtons,midButtons,botButtons)[i//3][i%3]['text'] = 'O'

from Tkinter import *

root = Tk()
###############################################################
topRow = Frame(master=root)
topButtons = [Button(master=topRow,width=1,command=clickButton(i)) for
i in range(3)]
###############################################################
midRow = Frame(master=root)
midButtons = [Button(master=midRow,width=1,command=clickButton(3+i))
for i in range(3)]
###############################################################
botRow = Frame(master=root)
botButtons = [Button(master=botRow,width=1,command=clickButton(6+i))
for i in range(3)]
###############################################################
map(lambda x: x.pack(side=TOP),[topRow,midRow,botRow])
map(lambda x: x.pack(side=LEFT),topButtons + midButtons + botButtons)
###############################################################
dummyRow = Frame(master=root)
placeHolder = Label(master=dummyRow,text='')
dummyRow.pack(side=TOP)
placeHolder.pack(side=TOP)
###############################################################
ctrlRow = Frame(master=root)
computerMoveButton = Button(master=ctrlRow,text='computer
move',command=makeMove)
newGameButton = Button(master=ctrlRow,text='new game',command=newGame)
ctrlRow.pack(side=TOP)
computerMoveButton.pack(side=TOP)
newGameButton.pack(side=TOP)
###############################################################
root.title('tic tac toe')
root.mainloop()

Sean McIlroy, Jan 9, 2005

2. ### Nick CoghlanGuest

Sean McIlroy wrote:
> While fiddling with a little script I ran into a problem that baffles
> me completely. Maybe I'm missing something completely obvious, and
> somebody out there can diagnose the problem at a glance. Anyway,
> that's the hope. Here's the code (it plays tic tac toe):

You need to be a little more explicit than simply saying "something goes wrong".

Exception? Wrong move? What?

Cheers,
Nick.

--
Nick Coghlan | | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net

Nick Coghlan, Jan 9, 2005

3. ### Andrea GriffiniGuest

On 8 Jan 2005 20:40:37 -0800, (Sean McIlroy)
wrote:

>def newGame():
> BOARD = [blank]*9
> for x in topButtons+midButtons+botButtons: x['text'] = ''

Do you know that "BOARD" here is a local variable and has nothing
to do with the global BOARD ? You can change that by doing either

BOARD[:] = [blank]*9

or

global BOARD
BOARD = [blank]*9

HTH
Andrea

Andrea Griffini, Jan 9, 2005