连接4和tkinter有问题

时间:2016-12-20 14:37:21

标签: python-3.x tkinter

我尝试使用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非常陌生,所以我从有限的知识开始工作,但我希望你能理解并帮助我:)

1 个答案:

答案 0 :(得分:0)

你不应该使用while - 循环。如果没有此循环,您可以执行所有操作 - 在c1Clickc2Click等内部

这是如何使用按钮单击来执行此操作的示例。它还显示了如何使用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()