我尝试使用tkinter对连接4游戏进行编码,其中计算机进行随机移动。我对python很新,所以我的代码非常低效和笨重。我的主要问题是当用户点击一列以在其中放置一块时,tkinter窗口崩溃。这似乎是由第二个while循环引起的,但没有它,程序不会等待用户在计算机移动之前选择一个列。这是我的代码:
import random
from tkinter import *
def setUpStacks():
return [[],[],[],[],[],[],[]]
def getStack(prompt,allStacks):
validInput=False
while validInput==False:
stack=int(input(prompt))-1
if len(allStacks[stack])<6:
if stack in range(7):
validInput=True
else:
print('Please enter a value from 1 to 7.')
else:
print('That stack is full.')
return stack
def putInStack(stack,allStacks,player):
allStacks[stack]+=[player]
return allStacks
def changePlayer(player):
if player=='red':
player='blue'
elif player=='blue':
player='red'
return player
def checkForWin(stack,allStacks):
play=True
pos=len(allStacks[stack])-1
if len(allStacks[stack])>3:
if allStacks[stack][-1]==allStacks[stack][-2]==allStacks[stack][-3]==allStacks[stack][-4]:
play=False
if stack>2: ##XXXO
if len(allStacks[stack-1])>=pos+1 and len(allStacks[stack-2])>=pos+1 and len(allStacks[stack-3])>=pos+1:
if diagonalCheck(0,-1,pos,stack,allStacks)==False:
play=False
if len(allStacks[stack-1])>=pos+2 and len(allStacks[stack-2])>=pos+3 and len(allStacks[stack-3])>=pos+4:
if diagonalCheck(1,-1,pos,stack,allStacks)==False:
play=False
if 2<len(allStacks[stack-1])>=pos and 1<len(allStacks[stack-2])>=pos-1 and 0<len(allStacks[stack-3])>=pos-2:
if diagonalCheck(-1,-1,pos,stack,allStacks)==False:
play=False
if 1<stack<6: ##XXOX
if len(allStacks[stack-1])>=pos+1 and len(allStacks[stack-2])>=pos+1 and len(allStacks[stack+1])>=pos+1:
if middleCheck(0,-1,pos,stack,allStacks)==False:
play=False
if len(allStacks[stack-1])>=pos+2 and len(allStacks[stack-2])>=pos+3 and 1<=len(allStacks[stack+1])>=pos:
if middleCheck(1,-1,pos,stack,allStacks)==False:
play=False
if 2<=len(allStacks[stack-1])>=pos and 1<=len(allStacks[stack-2])>=pos-1 and 4<=len(allStacks[stack+1])>=pos+2:
if middleCheck(-1,-1,pos,stack,allStacks)==False:
play=False
if stack<4: ##OXXX
if len(allStacks[stack+1])>=pos+1 and len(allStacks[stack+2])>=pos+1 and len(allStacks[stack+3])>=pos+1:
if diagonalCheck(0,1,pos,stack,allStacks)==False:
play=False
if len(allStacks[stack+1])>=pos+2 and len(allStacks[stack+2])>=pos+3 and len(allStacks[stack+3])>=pos+4:
if diagonalCheck(1,1,pos,stack,allStacks)==False:
play=False
if 2<len(allStacks[stack+1])>=pos and 1<len(allStacks[stack+2])>=pos-1 and 0<len(allStacks[stack+3])>=pos-2:
if diagonalCheck(-1,1,pos,stack,allStacks)==False:
play=False
if 0<stack<5: ##XOXX
if len(allStacks[stack+1])>=pos+1 and len(allStacks[stack+2])>=pos+1 and len(allStacks[stack-1])>=pos+1:
if middleCheck(0,1,pos,stack,allStacks)==False:
play=False
if len(allStacks[stack+1])>=pos+2 and len(allStacks[stack+2])>=pos+3 and len(allStacks[stack-1])>=pos:
if middleCheck(1,1,pos,stack,allStacks)==False:
play=False
if 2<=len(allStacks[stack+1])>=pos and 1<=len(allStacks[stack+2])>=pos-1 and 4<=len(allStacks[stack-1])>=pos+1:
if middleCheck(-1,1,pos,stack,allStacks)==False:
play=False
return play
def diagonalCheck(dirUp,dirAcross,pos,stack,allStacks):
if allStacks[stack][pos]==allStacks[stack+dirAcross][pos+dirUp]==allStacks[stack+(2*dirAcross)][pos+(2*dirUp)]==allStacks[stack+(3*dirAcross)][pos+(3*dirUp)]:
return False
else:
return True
def middleCheck(dirUp,dirAcross,pos,stack,allStacks):
if allStacks[stack][pos]==allStacks[stack-dirAcross][pos-dirUp]==allStacks[stack+dirAcross][pos+dirUp]==allStacks[stack+(2*dirAcross)][pos+(2*dirUp)]:
return False
else:
return True
def compMove():
return random.randint(0,6)
def c1Click(click):
global num
num=0
def c2Click(click):
global num
num=1
def c3Click(click):
global num
num=2
def c4Click(click):
global num
num=3
def c5Click(click):
global num
num=4
def c6Click(click):
global num
num=5
def c7Click(click):
global num
num=6
window=Tk()
window.title("Connect 4")
c1=Canvas(window,width=100,height=600,background='gray')
c2=Canvas(window,width=100,height=600,background='gray')
c3=Canvas(window,width=100,height=600,background='gray')
c4=Canvas(window,width=100,height=600,background='gray')
c5=Canvas(window,width=100,height=600,background='gray')
c6=Canvas(window,width=100,height=600,background='gray')
c7=Canvas(window,width=100,height=600,background='gray')
circ11=c1.create_oval(0,500,100,600,fill="white")
circ12=c1.create_oval(0,400,100,500,fill="white")
circ13=c1.create_oval(0,300,100,400,fill="white")
circ14=c1.create_oval(0,200,100,300,fill="white")
circ15=c1.create_oval(0,100,100,200,fill="white")
circ16=c1.create_oval(0,0,100,100,fill="white")
circ21=c2.create_oval(0,500,100,600,fill="white")
circ22=c2.create_oval(0,400,100,500,fill="white")
circ23=c2.create_oval(0,300,100,400,fill="white")
circ24=c2.create_oval(0,200,100,300,fill="white")
circ25=c2.create_oval(0,100,100,200,fill="white")
circ26=c2.create_oval(0,0,100,100,fill="white")
circ31=c3.create_oval(0,500,100,600,fill="white")
circ32=c3.create_oval(0,400,100,500,fill="white")
circ33=c3.create_oval(0,300,100,400,fill="white")
circ34=c3.create_oval(0,200,100,300,fill="white")
circ35=c3.create_oval(0,100,100,200,fill="white")
circ36=c3.create_oval(0,0,100,100,fill="white")
circ41=c4.create_oval(0,500,100,600,fill="white")
circ42=c4.create_oval(0,400,100,500,fill="white")
circ43=c4.create_oval(0,300,100,400,fill="white")
circ44=c4.create_oval(0,200,100,300,fill="white")
circ45=c4.create_oval(0,100,100,200,fill="white")
circ46=c4.create_oval(0,0,100,100,fill="white")
circ51=c5.create_oval(0,500,100,600,fill="white")
circ52=c5.create_oval(0,400,100,500,fill="white")
circ53=c5.create_oval(0,300,100,400,fill="white")
circ54=c5.create_oval(0,200,100,300,fill="white")
circ55=c5.create_oval(0,100,100,200,fill="white")
circ56=c5.create_oval(0,0,100,100,fill="white")
circ61=c6.create_oval(0,500,100,600,fill="white")
circ62=c6.create_oval(0,400,100,500,fill="white")
circ63=c6.create_oval(0,300,100,400,fill="white")
circ64=c6.create_oval(0,200,100,300,fill="white")
circ65=c6.create_oval(0,100,100,200,fill="white")
circ66=c6.create_oval(0,0,100,100,fill="white")
circ71=c7.create_oval(0,500,100,600,fill="white")
circ72=c7.create_oval(0,400,100,500,fill="white")
circ73=c7.create_oval(0,300,100,400,fill="white")
circ74=c7.create_oval(0,200,100,300,fill="white")
circ75=c7.create_oval(0,100,100,200,fill="white")
circ76=c7.create_oval(0,0,100,100,fill="white")
circs=[[circ11,circ12,circ13,circ14,circ15,circ16],[circ21,circ22,circ23,circ24,circ25,circ26],[circ31,circ32,circ33,circ34,circ35,circ36],[circ41,circ42,circ43,circ44,circ45,circ46],[circ51,circ52,circ53,circ54,circ55,circ56],[circ61,circ62,circ63,circ64,circ65,circ66],[circ71,circ72,circ73,circ74,circ75,circ76]]
bottomCirc=[0,0,0,0,0,0,0]
c1.grid(row=1,column=1)
c2.grid(row=1,column=2)
c3.grid(row=1,column=3)
c4.grid(row=1,column=4)
c5.grid(row=1,column=5)
c6.grid(row=1,column=6)
c7.grid(row=1,column=7)
c1.bind("<Button-1>",c1Click)
c2.bind("<Button-1>",c2Click)
c3.bind("<Button-1>",c3Click)
c4.bind("<Button-1>",c4Click)
c5.bind("<Button-1>",c5Click)
c6.bind("<Button-1>",c6Click)
c7.bind("<Button-1>",c7Click)
play=True
player='red'
stacks=setUpStacks()
num=8
chooseStack=num
while play==True:
player=changePlayer(player)
while chooseStack==8:
window.update_idletasks()
window.update()
if player=="blue":
chooseStack=num
else:
chooseStack=compMove()
if chooseStack==0:
if bottomCirc[0]<6:
c1.itemconfig(circs[0][(bottomCirc[0])], fill=player)
bottomCirc[0]+=1
if chooseStack==1:
if bottomCirc[1]<6:
c2.itemconfig(circs[1][(bottomCirc[1])], fill=player)
bottomCirc[1]+=1
if chooseStack==2:
if bottomCirc[2]<6:
c3.itemconfig(circs[2][(bottomCirc[2])], fill=player)
bottomCirc[2]+=1
if chooseStack==3:
if bottomCirc[3]<6:
c4.itemconfig(circs[3][(bottomCirc[3])], fill=player)
bottomCirc[3]+=1
if chooseStack==4:
if bottomCirc[4]<6:
c5.itemconfig(circs[4][(bottomCirc[4])], fill=player)
bottomCirc[4]+=1
if chooseStack==5:
if bottomCirc[5]<6:
c6.itemconfig(circs[5][(bottomCirc[5])], fill=player)
bottomCirc[5]+=1
if chooseStack==6:
if bottomCirc[6]<6:
c7.itemconfig(circs[6][(bottomCirc[6])], fill=player)
bottomCirc[6]+=1
print(chooseStack)
num=8
## stacks=putInStack(chooseStack,stacks,player)
## play=checkForWin(chooseStack,stacks)
就像我说的那样,我对python非常陌生,所以我从有限的知识开始工作,但我希望你能理解并帮助我:)
答案 0 :(得分:0)
你不应该使用while
- 循环。如果没有此循环,您可以执行所有操作 - 在c1Click
,c2Click
等内部
这是如何使用按钮单击来执行此操作的示例。它还显示了如何使用for
- 循环和列表来缩短代码。
代码尚未完成,但它已经为人类和计算机绘制并更改了圆形颜色。
import random
import tkinter as tk
def make_move(player, choose_stack):
print('[DEBUG] make_move:', player, choose_stack)
if bottom_circles[choose_stack] >= 6:
return False # can't make move
col = choose_stack
row = bottom_circles[col]
circle = circles[col][row]
print('[DEBUG] col/row/circles:', col, row, circle)
canvases[col].itemconfig(circle, fill=player)
bottom_circles[col] += 1
return True # move was OK
def on_click(event, number):
global player
# --- human ---
player = 'red'
choose_stack = number
if not make_move(player, choose_stack):
print("Wrong move - full stack")
return # skip computer move
# TODO: check if human wins
#if sum(bottom_circles) == 7*6:
if all(x == 6 for x in bottom_circles):
print("Board is full")
return # skip computer move
# --- computer ---
player = 'blue'
while True:
choose_stack = random.randint(0, 6)
if not make_move(player, choose_stack):
print("Wrong move - full stack")
else:
break
# TODO: check if computer wins
#if sum(bottom_circles) == 7*6:
if all(x == 6 for x in bottom_circles):
print("Board is full")
# --- main ---
window = tk.Tk()
window.title("Connect 4")
player = 'blue'
bottom_circles = [0]*7
canvases = []
circles = []
for col in range(7):
canvas = tk.Canvas(window, width=100, height=600, background='gray')
canvas.grid(row=0, column=col)
canvas.bind("<Button-1>", lambda event, number=col:on_click(event, number))
canvases.append(canvas)
circles_column = []
for row in range(5, -1, -1):
circle = canvas.create_oval(0, row*100, 100, (row+1)*100, fill="white")
circles_column.append(circle)
circles.append(circles_column)
window.mainloop()