mysterious buggy behavior

Sean McIlroy sean_mcilroy at yahoo.com
Sun Jan 9 05:40:37 CET 2005


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[i] = 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[i]==blank]
    return optimal([(valMove(subs(board,player,i))[0],i) for i in
blankIndices])

BOARD = [blank]*9

def clickButton(i):
    def f():
        BOARD[i] = 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[i] = 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()



More information about the Python-list mailing list