基于Python實(shí)現(xiàn)五子棋游戲
本文實(shí)例為大家分享了Python實(shí)現(xiàn)五子棋游戲的具體代碼,供大家參考,具體內(nèi)容如下
了解游戲的規(guī)則是我們首先需要做的事情,如果不知曉規(guī)則,那么我們肯定寸步難行。
五子棋游戲規(guī)則:
1.對(duì)局雙方各執(zhí)一色棋子。
2.空棋盤開局。
3.黑先、白后,交替下子,每次只能下一子。
4.棋子下在棋盤的空白點(diǎn)上,棋子下定后,不得向其它點(diǎn)移動(dòng),不得從棋盤上拿掉或拿起另落別處。
5.黑方的第一枚棋子可下在棋盤任意交叉點(diǎn)上。
6.輪流下子是雙方的權(quán)利,但允許任何一方放棄下子權(quán)(即:PASS權(quán))。
五子棋對(duì)局,執(zhí)行黑方指定開局、三手可交換、五手兩打的規(guī)定。整個(gè)對(duì)局過程中黑方有禁手,白方無禁手。黑方禁手有三三禁手、四四禁手和長(zhǎng)連禁手三種。
在這篇博客中我們只實(shí)現(xiàn)了較為簡(jiǎn)單的規(guī)則,不考慮規(guī)則6以及禁手的相關(guān)規(guī)定(個(gè)人能力有限,如果有愿意研究的朋友,我們可以一起研究研究 /抱拳)。
設(shè)計(jì)思路:
1、首先我們需要使用到界面,我們先分析界面上需要實(shí)現(xiàn)什么畫面,也就是我們要進(jìn)行這個(gè)五子棋游戲要看到什么。要看到:棋盤,棋子(棋子要分顏色,黑色和白色),這些是進(jìn)行游戲的必需看到的。
2、外表做好以后我們需要去思考內(nèi)部代碼的填充,思考:
①棋子如何落到指定的位置,
②如何實(shí)現(xiàn)交替落子,實(shí)現(xiàn)顏色交替變換,并且做好記錄方便計(jì)算棋子排布情況。
③如何計(jì)算四個(gè)方位上的同色棋子達(dá)到獲勝的數(shù)量。
首先把窗口調(diào)出來,實(shí)現(xiàn)代碼:
from tkinter import *#導(dǎo)入窗口第三方庫 root = Tk()? ? ? ?#創(chuàng)建窗口 root.title("憨憨制作的五子棋")? #窗口名字 w1 = Canvas(root, width=600,height=600,background='lightcyan')#在窗口中央創(chuàng)建一個(gè)畫布,root是窗口,寬度600,高度600,背景色為lightcyan w1.pack()? ? #布局方式,全局需要統(tǒng)一。 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')
窗口的左上角坐標(biāo)為(0,0),通過調(diào)試,我們得出起始位置為(20,20)較為合適,多次調(diào)試進(jìn)行對(duì)比,我選擇線間距為40比較不錯(cuò)。當(dāng)然線寬,圓的大小,棋盤線的間距這些都是可以進(jìn)行調(diào)整的,大家可以慢慢試探(h_h)。棋盤中的五個(gè)黑點(diǎn)需要我們通過計(jì)算得出位置。
create_line(起點(diǎn),終點(diǎn)):畫直線
create_oval(x1,y1,x2,y2,fill=‘顏色’)這個(gè)是畫一個(gè)內(nèi)切圓,矩形左上角(x1,y1),右下角(x2,y2)fill為填充色,我們可以從網(wǎng)上找到turtle顏色庫,順便幫大家找了一個(gè),自行選擇自己喜歡的顏色。
效果圖:
棋盤做好了,我們開始設(shè)計(jì)落子,這里需要交替進(jìn)行顏色的改變,那我們就需要去通過一個(gè)判斷方法來進(jìn)行改變棋子的顏色。我想了兩種:①一種是用字符標(biāo)記當(dāng)前鼠標(biāo)上棋子的顏色,改變?yōu)榱硪环N。②另一種是用計(jì)數(shù)的方式來進(jìn)行改變。除此之外我們要規(guī)定已經(jīng)放了棋子的位置不能再放棋子,也就是在落子前先判斷當(dāng)前位置是否有棋子。
num=0 ? ? ?? #計(jì)算棋盤上有幾個(gè)棋子,用來判斷下一顆棋子顏色 A=np.full((15,15),0?? ?)?? ??? ?#儲(chǔ)存位置已有棋子的矩陣 B=np.full((15,15),'')?? ??? ?#用來記錄每個(gè)位置棋子的顏色 def callback(event): ? ? ? ?#輸入的是點(diǎn)擊事件,event.x和event.y是鼠標(biāo)點(diǎn)擊事件的位置 ? ? global num ,A?? ??? ??? ?#全局變量可以全局使用 ? ? for j in range (0,15):?? ?#雙重循環(huán)定位點(diǎn)擊位置最近的網(wǎng)格線交點(diǎn)(i,j),保證棋子落在線的交點(diǎn)處。 ? ? ? ? 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:#判斷現(xiàn)在這顆棋子的顏色。 ? ? ? ? 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
落子以后需要計(jì)算是否五子連珠,每個(gè)棋子的計(jì)算方向有八個(gè)形成四條線,那么就是從落子處算先向一端算,直到遇到另一種顏色的棋子,反向查詢遇到另一個(gè)顏色棋處出停止,當(dāng)達(dá)到五顆棋子時(shí)即代表一方獲勝,否則循環(huán)下一條線。當(dāng)四條線結(jié)束未達(dá)到勝利條件,即可繼續(xù)落子。
f = [[-1, 0], [-1, 1], [0, 1], [1, 1]] #四條線其中一個(gè)方向的坐標(biāo)變化規(guī)律 ? ? for z in range(0, 4): ? ? ? ? ?? ??? ?#循環(huán)方向 ? ? ? ? a, b = f[z][0], f[z][1] ? ? ? ? count1, count2 = 0, 0 ? ? ? ? x, y = i, j ? ? ? ? while B[x][y] == B[i][j]:#當(dāng)顏色相同即可進(jìn)行計(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]:#保證不超出矩陣的邊界,否則會(huì)報(bào)錯(cuò) ? ? ? ? ? ? ? ? [x, y] = np.array([x, y]) + np.array([a, b]) ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? x, y = i, j ? ?? ? ? ? ? ? ? ? ? break ? ? ? ? while B[x][y] == B[i][j]:#從落子處反向計(jì)算同色棋子個(gè)數(shù)。 ? ? ? ? ? ? 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: ? ? ? ? ? ?#計(jì)算了兩次落子處 ? ? ? ? ? ? if B[i][j] == 'b': ? ? ? ? ? ? ? ? tkinter.messagebox.showinfo('提示', '黑棋獲勝') ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? tkinter.messagebox.showinfo('提示', '白棋獲勝')
點(diǎn)擊事件,每次點(diǎn)擊以后都需要進(jìn)行一次落子和游戲結(jié)束判斷。調(diào)用函數(shù)進(jìn)行落子,判斷是否結(jié)束游戲。
w1.bind("<Button -1>",callback) w1.pack()
設(shè)置退出按鈕:
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() ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #創(chuàng)建窗口 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()
技術(shù)不精,但是喜歡做點(diǎn)小研究,從學(xué)習(xí)中找到玩耍的快樂,愿意和大家一起學(xué)習(xí)玩耍。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Python實(shí)現(xiàn)簡(jiǎn)易五子棋游戲
- 用python實(shí)現(xiàn)五子棋實(shí)例
- python實(shí)現(xiàn)單機(jī)五子棋對(duì)戰(zhàn)游戲
- python實(shí)現(xiàn)人機(jī)對(duì)戰(zhàn)的五子棋游戲
- python版本五子棋的實(shí)現(xiàn)代碼
- python實(shí)現(xiàn)五子棋小游戲
- python pygame實(shí)現(xiàn)五子棋小游戲
- python實(shí)現(xiàn)簡(jiǎn)單五子棋游戲
- python實(shí)現(xiàn)五子棋游戲(pygame版)
- Python實(shí)現(xiàn)雙人五子棋對(duì)局
相關(guān)文章
Pycharm 2to3配置,python2轉(zhuǎn)python3方式
這篇文章主要介紹了Pycharm 2to3配置,python2轉(zhuǎn)python3方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Python實(shí)現(xiàn)Excel做表自動(dòng)化的最全方法合集
Microsoft?Excel?是一款強(qiáng)大的辦公工具,廣泛用于數(shù)據(jù)分析、報(bào)告制作、預(yù)算管理等各種任務(wù),本文將深入探討如何使用?Python?進(jìn)行?Excel?表格的自動(dòng)化,需要的可以參考下2024-02-02Python中pytest命令行實(shí)現(xiàn)環(huán)境切換
在自動(dòng)化測(cè)試過程中經(jīng)常需要在不同的環(huán)境下進(jìn)行測(cè)試驗(yàn)證,所以寫自動(dòng)化測(cè)試代碼時(shí)需要考慮不同環(huán)境切換的情況,本文主要介紹了Python中pytest命令行實(shí)現(xiàn)環(huán)境切換,感興趣的可以了解一下2023-07-07Python中openpyxl實(shí)現(xiàn)vlookup函數(shù)的實(shí)例
在本篇文章里小編給大家整理的是關(guān)于Python中openpyxl實(shí)現(xiàn)vlookup函數(shù)的實(shí)例內(nèi)容,有興趣的朋友們可以學(xué)習(xí)參考下。2020-10-10詳解Tensorflow數(shù)據(jù)讀取有三種方式(next_batch)
本篇文章主要介紹了Tensorflow數(shù)據(jù)讀取有三種方式(next_batch),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-02-02