網站首頁 編程語言 正文
本文實例為大家分享了Python實現五子棋游戲的具體代碼,供大家參考,具體內容如下
了解游戲的規則是我們首先需要做的事情,如果不知曉規則,那么我們肯定寸步難行。
五子棋游戲規則:
1.對局雙方各執一色棋子。
2.空棋盤開局。
3.黑先、白后,交替下子,每次只能下一子。
4.棋子下在棋盤的空白點上,棋子下定后,不得向其它點移動,不得從棋盤上拿掉或拿起另落別處。
5.黑方的第一枚棋子可下在棋盤任意交叉點上。
6.輪流下子是雙方的權利,但允許任何一方放棄下子權(即:PASS權)。
五子棋對局,執行黑方指定開局、三手可交換、五手兩打的規定。整個對局過程中黑方有禁手,白方無禁手。黑方禁手有三三禁手、四四禁手和長連禁手三種。
在這篇博客中我們只實現了較為簡單的規則,不考慮規則6以及禁手的相關規定(個人能力有限,如果有愿意研究的朋友,我們可以一起研究研究 /抱拳)。
設計思路:
1、首先我們需要使用到界面,我們先分析界面上需要實現什么畫面,也就是我們要進行這個五子棋游戲要看到什么。要看到:棋盤,棋子(棋子要分顏色,黑色和白色),這些是進行游戲的必需看到的。
2、外表做好以后我們需要去思考內部代碼的填充,思考:
①棋子如何落到指定的位置,
②如何實現交替落子,實現顏色交替變換,并且做好記錄方便計算棋子排布情況。
③如何計算四個方位上的同色棋子達到獲勝的數量。
首先把窗口調出來,實現代碼:
from tkinter import *#導入窗口第三方庫
root = Tk()? ? ? ?#創建窗口
root.title("憨憨制作的五子棋")? #窗口名字
w1 = Canvas(root, width=600,height=600,background='lightcyan')#在窗口中央創建一個畫布,root是窗口,寬度600,高度600,背景色為lightcyan
w1.pack()? ? #布局方式,全局需要統一。
mainloop()
五子棋棋盤是由15條橫線15條豎線組成的。
畫出棋盤:
for i in range(0, 15):
? ? w1.create_line(i * 40 + 20, 20, i * 40 + 20, 580)
? ? w1.create_line(20, i * 40 + 20, 580, i * 40 + 20)
w1.create_oval(135, 135, 145, 145,fill='black')
w1.create_oval(135, 455, 145, 465,fill='black')
w1.create_oval(465, 135, 455, 145,fill='black')
w1.create_oval(455, 455, 465, 465,fill='black')
w1.create_oval(295, 295, 305, 305,fill='black')
窗口的左上角坐標為(0,0),通過調試,我們得出起始位置為(20,20)較為合適,多次調試進行對比,我選擇線間距為40比較不錯。當然線寬,圓的大小,棋盤線的間距這些都是可以進行調整的,大家可以慢慢試探(h_h)。棋盤中的五個黑點需要我們通過計算得出位置。
create_line(起點,終點):畫直線
create_oval(x1,y1,x2,y2,fill=‘顏色’)這個是畫一個內切圓,矩形左上角(x1,y1),右下角(x2,y2)fill為填充色,我們可以從網上找到turtle顏色庫,順便幫大家找了一個,自行選擇自己喜歡的顏色。
效果圖:
棋盤做好了,我們開始設計落子,這里需要交替進行顏色的改變,那我們就需要去通過一個判斷方法來進行改變棋子的顏色。我想了兩種:①一種是用字符標記當前鼠標上棋子的顏色,改變為另一種。②另一種是用計數的方式來進行改變。除此之外我們要規定已經放了棋子的位置不能再放棋子,也就是在落子前先判斷當前位置是否有棋子。
num=0 ? ? ?? #計算棋盤上有幾個棋子,用來判斷下一顆棋子顏色
A=np.full((15,15),0?? ?)?? ??? ?#儲存位置已有棋子的矩陣
B=np.full((15,15),'')?? ??? ?#用來記錄每個位置棋子的顏色
def callback(event): ? ? ? ?#輸入的是點擊事件,event.x和event.y是鼠標點擊事件的位置
? ? global num ,A?? ??? ??? ?#全局變量可以全局使用
? ? for j in range (0,15):?? ?#雙重循環定位點擊位置最近的網格線交點(i,j),保證棋子落在線的交點處。
? ? ? ? for i in range (0,15):
? ? ? ? ? ? if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2 * 20 ** 2:
? ? ? ? ? ? ? ? break
? ? ? ? if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2*20 ** 2:
? ? ? ? ? ? break
? ? if num % 2 == 0 and A[i][j] != 1:#判斷現在這顆棋子的顏色。
? ? ? ? w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='black')
? ? ? ? A[i][j] = 1
? ? ? ? B[i][j] = 'b'
? ? ? ? num += 1
? ? if num % 2 != 0 and A[i][j] != 1 :
? ? ? ? w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='white')
? ? ? ? A[i][j] = 1
? ? ? ? B[i][j] = 'w'
? ? ? ? num += 1
落子以后需要計算是否五子連珠,每個棋子的計算方向有八個形成四條線,那么就是從落子處算先向一端算,直到遇到另一種顏色的棋子,反向查詢遇到另一個顏色棋處出停止,當達到五顆棋子時即代表一方獲勝,否則循環下一條線。當四條線結束未達到勝利條件,即可繼續落子。
f = [[-1, 0], [-1, 1], [0, 1], [1, 1]] #四條線其中一個方向的坐標變化規律
? ? for z in range(0, 4): ? ? ? ? ?? ??? ?#循環方向
? ? ? ? a, b = f[z][0], f[z][1]
? ? ? ? count1, count2 = 0, 0
? ? ? ? x, y = i, j
? ? ? ? while B[x][y] == B[i][j]:#當顏色相同即可進行計算
? ? ? ? ? ? count1 += 1
? ? ? ? ? ? if x + a > 0 and y + b > 0 and x + a < 15 and y + b < 15 and B[x + a][y + b] == B[i][j]:#保證不超出矩陣的邊界,否則會報錯
? ? ? ? ? ? ? ? [x, y] = np.array([x, y]) + np.array([a, b])
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? x, y = i, j ? ??
? ? ? ? ? ? ? ? break
? ? ? ? while B[x][y] == B[i][j]:#從落子處反向計算同色棋子個數。
? ? ? ? ? ? count2 += 1
? ? ? ? ? ? if x - a < 15 and y - b < 15 and x - a > 0 and y - b > 0 and B[x - a][y - b] == B[i][j]:
? ? ? ? ? ? ? ? [x, y] = np.array([x, y]) - np.array([a, b])
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? if count1 + count2 == 6: ? ? ? ? ? ?#計算了兩次落子處
? ? ? ? ? ? if B[i][j] == 'b':
? ? ? ? ? ? ? ? tkinter.messagebox.showinfo('提示', '黑棋獲勝')
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? tkinter.messagebox.showinfo('提示', '白棋獲勝')
點擊事件,每次點擊以后都需要進行一次落子和游戲結束判斷。調用函數進行落子,判斷是否結束游戲。
w1.bind("<Button -1>",callback)
w1.pack()
設置退出按鈕:
u=Button(root,text="退出",width=10,height=1,command=quit,font=('楷體',15))
u.pack()
完整代碼:
from tkinter import *
import tkinter.messagebox ?# 彈窗庫
import numpy as np
root = Tk() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #創建窗口
root.title("憨憨制作的五子棋") ? ? ? ? ? ? ? ? ?#窗口名字
w1 = Canvas(root, width=600,height=600,background='lightcyan')
w1.pack()
for i in range(0, 15):
? ? w1.create_line(i * 40 + 20, 20, i * 40 + 20, 580)
? ? w1.create_line(20, i * 40 + 20, 580, i * 40 + 20)
w1.create_oval(135, 135, 145, 145,fill='black')
w1.create_oval(135, 455, 145, 465,fill='black')
w1.create_oval(465, 135, 455, 145,fill='black')
w1.create_oval(455, 455, 465, 465,fill='black')
w1.create_oval(295, 295, 305, 305,fill='black')
num=0
A=np.full((15,15),0)
B=np.full((15,15),'')
def callback(event):
? ? global num ,A
? ? for j in range (0,15):
? ? ? ? for i in range (0,15):
? ? ? ? ? ? if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2 * 20 ** 2:
? ? ? ? ? ? ? ? break
? ? ? ? if (event.x - 20 - 40 * i) ** 2 + (event.y - 20 - 40 * j) ** 2 <= 2*20 ** 2:
? ? ? ? ? ? break
? ? if num % 2 == 0 and A[i][j] != 1:
? ? ? ? w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='black')
? ? ? ? A[i][j] = 1
? ? ? ? B[i][j] = 'b'
? ? ? ? num += 1
? ? if num % 2 != 0 and A[i][j] != 1 :
? ? ? ? w1.create_oval(40*i+5, 40*j+5, 40*i+35, 40*j+35,fill='white')
? ? ? ? A[i][j] = 1.
? ? ? ? B[i][j] = 'w'
? ? ? ? num += 1
? ? f = [[-1, 0], [-1, 1], [0, 1], [1, 1]]
? ? for z in range(0, 4):
? ? ? ? a, b = f[z][0], f[z][1]
? ? ? ? count1, count2 = 0, 0
? ? ? ? x, y = i, j
? ? ? ? while B[x][y] == B[i][j]:
? ? ? ? ? ? count1 += 1
? ? ? ? ? ? if x + a > 0 and y + b > 0 and x + a < 15 and y + b < 15 and B[x + a][y + b] == B[i][j]:
? ? ? ? ? ? ? ? [x, y] = np.array([x, y]) + np.array([a, b])
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? x, y = i, j
? ? ? ? ? ? ? ? break
? ? ? ? while B[x][y] == B[i][j]:
? ? ? ? ? ? count2 += 1
? ? ? ? ? ? if x - a < 15 and y - b < 15 and x - a > 0 and y - b > 0 and B[x - a][y - b] == B[i][j]:
? ? ? ? ? ? ? ? [x, y] = np.array([x, y]) - np.array([a, b])
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? break
? ? ? ? if count1 + count2 == 6:
? ? ? ? ? ? if B[i][j] == 'b':
? ? ? ? ? ? ? ? tkinter.messagebox.showinfo('提示', '黑棋獲勝')
? ? ? ? ? ? else:
? ? ? ? ? ? ? ? tkinter.messagebox.showinfo('提示', '白棋獲勝')
w1.bind("<Button -1>",callback)
w1.pack()
def quit():
? ? root.quit()
u=Button(root,text="退出",width=10,height=1,command=quit,font=('楷體',15))
u.pack()
mainloop()
技術不精,但是喜歡做點小研究,從學習中找到玩耍的快樂,愿意和大家一起學習玩耍。
原文鏈接:https://blog.csdn.net/qq_44793283/article/details/110096666
相關推薦
- 2023-10-14 C/C++ 批量梯度下降法實現一元線性回歸
- 2022-09-25 面向對象和面向過程:兩種程序設計思想的基礎介紹和對比
- 2022-09-25 阿里云服務器如何部署ssl證書即https的設置,以及為ip部署ssl
- 2022-04-21 使用mongoshake實現mongodb數據同步的操作方法_MongoDB
- 2022-07-27 C++中this指針理解及作用_C 語言
- 2022-06-23 基于Flutter制作一個心碎動畫特效_Android
- 2022-06-11 Python?tkinter庫繪圖實例分享_python
- 2022-10-10 scrapy框架ItemPipeline的使用_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支