Tkinter實現五子棋小遊戲
阿新 • • 發佈:2022-05-11
用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()
趕緊來試一試效果吧