tkinter callbacks stop working

namenobodywants at gmail.com namenobodywants at gmail.com
Fri Oct 21 08:26:18 EDT 2016


hello pythonistas
the script below plays tictactoe; everything works; but if i replace the block at the bottom
if True:
 <tkinter code>
with this instead
def function():
 <tkinter code>
function()
then the tkinter callbacks don't work anymore; can anybody make sense of this? thanks if you can help
peace
stm
ps: here's the code...
ex, oh, blank = 'XO '
rows = [[3*i + j for j in range(3)] for i in range(3)]
columns = [[3*i + j for i in range(3)] for j in range(3)]
diagonals = [[3+3, 4, 5-3], [3-3, 4, 5+3]]
lines = rows + columns + diagonals
putmark = lambda board, square, mark: board[:square] + mark + board[square + 1:]
getblanks = lambda board: [square for square in range(9) if board[square]==blank]
getmover = lambda board: ex if board.count(ex)==board.count(oh) else oh
getlines = lambda board: [[board[square] for square in line] for line in lines]
getwinners = lambda board: [player for player in [ex, oh] if [player] * 3 in getlines(board)]
def evaluate(board):
 winners = getwinners(board)
 mover = getmover(board)
 blanks = getblanks(board)
 value = (+1) if winners==[ex] else (-1) if winners==[oh] else 0
 optimum = max if mover == ex else min if mover == oh else None
 if winners or not blanks: return value, []
 values = [evaluate(putmark(board,square,mover))[0] for square in blanks]
 optimal = optimum(values)
 return optimal, [square for (index, square) in enumerate(blanks) if values[index]==optimal]
isvalid = lambda board: len(getwinners(board)) < 2 and board.count(ex)-board.count(oh) in {0,1}
cartesian = lambda strings: [''] if not strings else [x + ys for x in strings[0] for ys in cartesian(strings[1:])] 
getmoves = lambda: {board: evaluate(board)[1] for board in cartesian([marks] * 9) if isvalid(board)}
def getmove(board):
 from random import choice
 blanks = getblanks(board)
 evens = [square for square in blanks if (square % 2)==0]
 return choice(evaluate(board)[1]) if len(blanks)<8 else 4 if 4 in blanks else choice(evens)
def getdisplay(board):
 template = ' {} | {} | {} '
 separator = '\n-----------\n'
 return separator.join(template.format(*(board[square] for square in row)) for row in rows)
 
def getstatus(board): 
 winners = getwinners(board)
 numblanks = board.count(blank)
 if winners: return winners[0] + ' wins' 
 if numblanks==0: return 'draw'
 if numblanks==9: return 'X goes first'
 else: return getmover(board) + ' goes next'
show = lambda board: print('\n' + getdisplay(board) + '\n\n' + getstatus(board) + '\n')
def newgame():
	global board
	board = blank * 9
	show(board)
		
def makemove():
	global board
	board = board if getwinners(board) or blank not in board else putmark(board, getmove(board), getmover(board))
	show(board)
	
def takemove(square):
	global board
	board = board if getwinners(board) or board[square] != blank else putmark(board, square, getmover(board))
	show(board)	
show = lambda board: status.set(getstatus(board)) or [squares[i].set(board[i]) for i in range(9)]
if True: 
	
 from tkinter import Tk, Frame, Label, Button 
 
 window = Tk()
 status = StringVar()
 squares = [StringVar() for i in range(9)]
 statusframe = Frame(window)
 buttonframe = Frame(window)
 boardframe = Frame(window)
 statuslabel = Label(statusframe)
 newgamebutton = Button(buttonframe)
 makemovebutton = Button(buttonframe)
 rowframes = [Frame(boardframe) for i in range(3)]
 squarebuttons = [Button(rowframes[i//3]) for i in range(9)]
 
 statuslabel .configure(textvariable=status)
 newgamebutton .configure(command=newgame, text='new game')
 makemovebutton .configure(command=makemove, text='make move')
 for i in range(9): squarebuttons[i] .configure(textvariable=squares[i], command=lambda i=i:takemove(i))
 
 statuslabel .configure(padx=0, pady=10)
 boardframe .configure(padx=20, pady=20)
 for button in squarebuttons: button .configure(width=4, height=2)
 
 boardframe .pack(side=TOP)
 buttonframe .pack(side=TOP)
 statusframe .pack(side=TOP)
 newgamebutton .pack(side=LEFT)
 makemovebutton .pack(side=RIGHT)
 statuslabel .pack(side=TOP)
 for frame in rowframes: frame .pack(side=TOP) 
 for button in squarebuttons: button .pack(side=LEFT) 
		 
 newgame() 
 window.title(' tictactoe') 
 window.mainloop()
""" #)----------------------------------------
""" #)---------------------------------------- 


More information about the Python-list mailing list

AltStyle によって変換されたページ (->オリジナル) /