1. 程式人生 > 其它 >Tkinter實現五子棋小遊戲

Tkinter實現五子棋小遊戲

用Tkinter做一個五子棋遊戲,但是我在做的時候心血來潮,決定稍微改變一下規則,於是在五子棋的基礎上開發出了“四五棋”,具體規則如下:

一方連成四子得一分;
一方連成五子及以上得五分;
當棋盤落滿後,比較雙方得分,較高的一方獲勝。

接下來就是用tkinter來實現它了,具體流程主要分為幾部分:

(1)棋盤繪製:15x15;

(2)落子的相應判斷:先判斷點選的位置是否是棋盤線交叉點,然後判斷是黑方還是白方,若落子點上沒有棋子,則落子;

(3)得分判斷:每次落子後,從當前棋子的橫、豎、斜三個方向尋找連子(不包括該棋子本身),找到三個則加一分,找到四個及以上則加五分;

(4)勝負判斷:若棋盤落滿,根據雙方得分判斷勝負;

(5)悔棋:刪除上一步繪製的棋子,並將其移除棋子列表,減去相應分數;

(6)資訊顯示:顯示當前執子方和得分。

與tkinter相關的部分主要用到了canvas.create_oval繪製棋子,以及Label顯示資訊,其餘大多是各種判斷的演算法。下面是完整程式碼:

from tkinter import *
window = Tk()
window.title("四五棋")
#畫棋盤
canvas = Canvas(window, bg = "SandyBrown", width = 480, height = 480)
canvas.grid(row = 0, column = 0, rowspan = 10)

#畫線條
for i in range(15):
    canvas.create_line(30, (30 * i + 30), 450, (30 * i + 30))
    canvas.create_line((30* i + 30), 30, (30 * i + 30), 450)

#畫初始的五個星
point_x = [3, 3, 11, 11, 7]
point_y = [3, 11, 3, 11, 7]
for i in range(5):
    canvas.create_oval(30 * point_x[i] + 27, 30 * point_y[i] + 27, 
                       30 * point_x[i] + 33, 30 * point_y[i] + 33, fill = "black")

#設定必要引數
r = 10
click_x=0                 #定義x軸座標
click_y=0                 #定義y軸座標
piece_color = "black"     #當前棋子顏色
person_flag = 1           #棋子標誌,1為白子,-1為黑子
a_flag = 1                #當一方獲勝後,無法在棋盤上點選
mouse_black = []          #黑子座標儲存列表
mouse_white = []          #白子座標儲存列表
mouse = []                #所有棋子座標儲存列表
totala=0
totalb=0
ret=1
#返回滑鼠位置
def mouseBack(event):     
    global click_x, click_y
    click_x = event.x
    click_y = event.y
    mouseJudge()
    
#單擊左鍵,返回當前位置    
canvas.bind("<Button-1>",mouseBack) 

#使落點在交叉點處
def mouseJudge():
    global click_x, click_y, person_flag, mouse
    mouse = mouse_black + mouse_white   #將棋子(黑白)座標全部存進去
    i=0
    j=0
    while click_x > (30+15*i):     #確定滑鼠點選位置所在的格子
        i+=1
    while click_y > (30+15*j):
        j+=1
    if ((i%2)==1 and (j%2)==1):      #將一個格子分成四個區域,根據滑鼠點選位置所在區域分得格子的頂點
        click_x=30+15*(i-1)                      
        click_y=30+15*(j-1)
    if ((i%2)==1 and (j%2)==0):
        click_x=30+15*(i-1)
        click_y=30+15*j
    if ((i%2)==0 and (j%2)==1):
        click_x=30+15*i
        click_y=30+15*(j-1)
    if ((i%2)==0 and (j%2)==0):
        click_x=30+15*i
        click_y=30+15*j
    if person_flag ==1:
        putPiece("black")
    elif person_flag ==-1:
        putPiece("white")
    
#落子        
def putPiece(piece_color):
    global mouse_black, mouse_white, person_flag, mouse,ret
    ret=1
    if (click_x>=30)and(click_x<=450)and(click_y>=30)and(click_y<=450): #只能在棋譜內產生棋子
        if (click_x, click_y) not in mouse:   #一個點只能產生一個棋子
            if a_flag == 0:
                canvas.create_oval(click_x - r, click_y - r,
                                   click_x + r, click_y + r, 
                                   fill = piece_color, tags = ("piece"))
                person_flag *= -1
                if piece_color == "white":
                    Show(mouse)
                    mouse_white.append( (click_x, click_y) )   #將白子座標放進白子列表中
                    Judge1(mouse_white) 
                    Tips(mouse)
                elif piece_color == "black":
                    Show(mouse)
                    mouse_black.append( (click_x, click_y) )   #將黑子座標放進黑子列表中
                    Judge1(mouse_black)
                    Tips(mouse)
            else:
                return 0

#根據連子數判斷輸贏
def pieceCount(mouse,pieces_count,p,q):
    global piece_count
    if person_flag==-1:   #判斷黑子
        for i in range(1,5):
            (x, y) = (click_x + p * 30 * i, click_y + q * 30 * i)
            if (x, y) in mouse_black:
                piece_count+=1
            else:
                break
        return piece_count
    if person_flag==1:   #判斷白子
        for i in range(1,5):
            (x, y) = (click_x + p * 30 * i, click_y + q * 30 * i)
            if (x, y) in mouse_white:
                piece_count+=1
            else:
                break
        return piece_count

#從橫豎斜三個方向判斷輸贏
def Judge1(mouse):
    global piece_count, piece_color
    piece_count = 0
    piece_count = pieceCount(mouse,piece_count,-1,0)              #從該落點座標往左判斷
    piece_count = pieceCount(mouse,piece_count,1,0)               #從該落點座標往右判斷
    #除了剛落下的棋子,還連線了三個,則連成了四子
    if  piece_count == 3:
        return 1
    elif  piece_count > 3:
        return 5
    else:
        piece_count = 0
        piece_count = pieceCount(mouse,piece_count,0,-1)          #從該落點座標往上判斷
        piece_count = pieceCount(mouse,piece_count,0,1)           #從該落點座標往下判斷
        if piece_count== 3:
            return 1
        elif  piece_count > 3:
            return 5
        else:
            piece_count = 0
            piece_count = pieceCount(mouse,piece_count,-1,-1)     #從該落點座標往左上角判斷
            piece_count = pieceCount(mouse,piece_count,1,1)       #從該落點座標往右下角判斷
            if piece_count == 3:
                return 1
            elif  piece_count > 3:
                return 5
            else:
                piece_count = 0
                piece_count = pieceCount(mouse,piece_count,1,-1)  #從該落點座標往右上角判斷
                piece_count = pieceCount(mouse,piece_count,-1,1)  #從該落點座標往左下角判斷
                if piece_count ==3:
                    return 1
                elif  piece_count > 3:
                    return 5
                else:
                    return 0


#走棋提示
def Show(mouse):
    var1 = StringVar()
    if person_flag==1:
        piece_canvas = Canvas(window, width = 200, height = 50)
        piece_canvas.grid(row = 0, column = 1)
        piece_canvas.create_oval(100 - r, 30 - r,
                                100 + r, 30 + r,
                                fill = 'black')
        var1.set("執黑輪次")
        label = Label(window, textvariable=var1, font=("宋體",16))
        label.grid(row = 1,column = 1) 
    if person_flag==-1:
        piece_canvas = Canvas(window, width = 200, height = 50)
        piece_canvas.grid(row = 0, column = 1)
        piece_canvas.create_oval(100 - r, 30 - r,
                                100 + r, 30 + r,
                                fill = 'white')
        var1.set("執白輪次")
        label = Label(window, textvariable=var1, font=("宋體",16))
        label.grid(row = 1,column = 1)

#勝方提示
def Tips(mouse):
    var2 = StringVar()
    global a_flag,totala,totalb
    if len(mouse)==224:  #如果棋盤鋪滿
        if totala>totalb:
            var2.set("黑方%s:%s白方,黑方勝"%(totala,totalb))
            label = Label(window, textvariable=var2, font=("宋體",16))
            label.grid(row = 2,column = 1) 
            a_flag = 1
            return a_flag
        elif totala<totalb:
            var2.set("黑方%s:%s白方,白方勝"%(totala,totalb))
            label = Label(window, textvariable=var2, font=("宋體",16))
            label.grid(row = 2,column = 1) 
            a_flag = 1  
            return a_flag
        else:
            var2.set("黑方%s:%s白方,和棋"%(totala,totalb))
            label = Label(window, textvariable=var2, font=("宋體",16))
            label.grid(row = 2,column = 1)   
            a_flag = 1
            return a_flag
    if  person_flag==-1:
        totala+=Judge1(mouse)
        var2.set("黑方%s:%s白方"%(totala,totalb))
        label = Label(window, textvariable=var2, font=("宋體",16))
        label.grid(row = 2,column = 1) 
        #a_flag = 1
        return a_flag
    if  person_flag==1:
        totalb+=Judge1(mouse)
        var2.set("黑方%s:%s白方"%(totala,totalb))
        label = Label(window, textvariable=var2, font=("宋體",16))
        label.grid(row = 2,column = 1) 
        #a_flag = 1
        return a_flag

#重新開始後,輸方先下
def click_reset():
    var3 = StringVar()
    global a_flag, mouse_black, mouse_white, mouse,totala,totalb
    canvas.delete("piece")
    mouse_black = []
    mouse_white = []
    mouse = []
    a_flag=0
    totala,totalb=0,0
    var3.set("          ")
    label = Label(window, textvariable=var3, font=("宋體",16))
    label.grid(row = 2,column = 1) 

#悔棋
def click_return():
    global mouse_black, mouse_white, mouse,person_flag,totala,totalb,ret
    if ret==0:
        return
    canvas.delete("piece")
    ret=0
    var2 = StringVar()
    if person_flag==-1:
        mouse_black.pop()
        mouse=mouse_black+mouse_white
        totala-=Judge1(mouse)
        var2.set("黑方%s:%s白方"%(totala,totalb))
        label = Label(window, textvariable=var2, font=("宋體",16))
        label.grid(row = 2,column = 1)
        
        for i in range(len(mouse_black)):
            canvas.create_oval(mouse_black[i][0]-r,mouse_black[i][1]-r
                              ,mouse_black[i][0]+r,mouse_black[i][1]+r,fill="black",tags="piece")
        for i in range(len(mouse_white)):
            canvas.create_oval(mouse_white[i][0]-r,mouse_white[i][1]-r
                              ,mouse_white[i][0]+r,mouse_white[i][1]+r,fill="white",tags="piece")
        
    if person_flag==1:      
        for i in range(len(mouse_black)):
            canvas.create_oval(mouse_black[i][0]-r,mouse_black[i][1]-r
                              ,mouse_black[i][0]+r,mouse_black[i][1]+r,fill="black",tags="piece")
        mouse_white.pop()
        mouse=mouse_black+mouse_white
        totalb-=Judge1(mouse)
        var2.set("黑方%s:%s白方"%(totala,totalb))
        label = Label(window, textvariable=var2, font=("宋體",16))
        label.grid(row = 2,column = 1)
        
        for i in range(len(mouse_white)):
            canvas.create_oval(mouse_white[i][0]-r,mouse_white[i][1]-r
                              ,mouse_white[i][0]+r,mouse_white[i][1]+r,fill="white",tags="piece")
    person_flag *= -1
    Show(mouse)
    

button1 = Button(window,text="開始/重來",font=('黑體', 10),fg='blue',width=10,height=2,command = click_reset)
button1.grid(row = 4,column = 1)
button2 = Button(window,text="悔 棋",font=('黑體', 10),fg='red',width=10,height=2,command = click_return)
button2.grid(row = 6,column = 1)
var = StringVar()
piece_canvas = Canvas(window, width = 200, height = 50)
piece_canvas.grid(row = 0, column = 1)
piece_canvas.create_oval(100 - r, 30 - r,100 + r, 30 + r,fill = 'black')
var.set("黑棋輪次")
label = Label(window, textvariable=var, font=("宋體",16))
label.grid(row = 1,column = 1) 
window.mainloop()

  

趕緊來試一試效果吧