python實(shí)現(xiàn)簡(jiǎn)單的井字棋小游戲
Python做三子棋游戲,這個(gè)是我剛開始了解做Python小游戲的時(shí)候第一個(gè)項(xiàng)目,因?yàn)楹?jiǎn)單好入手,實(shí)現(xiàn)它的過(guò)程是我開始摸索Python的GUI界面的入門之路。這個(gè)設(shè)計(jì)也都是按照自己對(duì)于這個(gè)游戲的理解,一步一步去實(shí)現(xiàn)它。
窗口
萬(wàn)能的窗口,實(shí)現(xiàn)窗口都可以進(jìn)行簡(jiǎn)單的修改進(jìn)行使用:
from tkinter import *
root = Tk() ? ? ? ? #窗口名稱
root.title("憨憨制作的三子棋")
f1=Frame(root)
f1.pack()
w1 = Canvas(f1, width=580,height=580,background='lightcyan')#創(chuàng)建一個(gè)畫布,設(shè)置大小和背景顏色
w1.pack()
root.mainloop()
畫出棋盤
#畫出棋盤 for i in range(0, 4): ? ? w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560) ? ? w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)

分別畫橫豎線,四條橫線四條豎線,生成九個(gè)格子。也可以畫出兩橫兩豎,更加貼近井字形狀。少畫幾條線就好,例如:
for i in range(1, 3): ? ? w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560) ? ? w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)

num = 0?? ????#記錄點(diǎn)擊的次數(shù),用來(lái)決定點(diǎn)擊后該畫哪種圖形 A = np.full((3, 3), 0)?? ??? ??? ?#記錄每個(gè)位置的圖形
算法
每一次點(diǎn)擊以后我們都要進(jìn)行畫圖和判斷是否達(dá)到獲勝的條件。
設(shè)置函數(shù)
def dawn(event):
? ? global w1
? ? global num, A
? ? for i in range(0, 3):
? ? ? ? for j in range(0, 3):
? ? ? ? ? ? if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180:
? ? ? ? ? ? ? ? break
? ? ? ? if 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180:
? ? ? ? ? ? break
? ? if num % 2 == 0 and A[i][j] == 0:
? ? ? ? A[i][j] = 1
? ? ? ? w1.create_line(110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),
? ? ? ? ? ? ? ? ? ? ? ?110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2))
? ? ? ? w1.create_line(110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),
? ? ? ? ? ? ? ? ? ? ? ?110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2))
? ? ? ? num += 1
? ? if num % 2 != 0 and A[i][j] == 0:
? ? ? ? A[i][j] = 2
? ? ? ? w1.create_oval(20 + 180 * i, 20 + 180 * j, 20 + 180 * (i + 1), 20 + 180 * (j + 1))
? ? ? ? num += 1
? ? if A[0][0] == A[0][1] == A[0][2] == 2 or A[1][0] == A[1][1] == A[1][2] == 2 or A[2][0] == A[2][1] == A[2][
? ? ? ? 2] == 2 or \
? ? ? ? ? ? A[0][0] == A[1][0] == A[2][0] == 2 or A[0][1] == A[1][1] == A[2][1] == 2 or A[0][2] == A[1][2] == \
? ? ? ? ? ? A[2][
? ? ? ? ? ? ? ? 2] == 2 or \
? ? ? ? ? ? A[0][0] == A[1][1] == A[2][2] == 2 or A[2][0] == A[1][1] == A[0][2] == 2:
? ? ? ? tkinter.messagebox.showinfo('消息提示', '圓圈獲勝')
? ? elif A[0][0] == A[0][1] == A[0][2] == 1 or A[1][0] == A[1][1] == A[1][2] == 1 or A[2][0] == A[2][1] == A[2][
? ? ? ? 2] == 1 or \
? ? ? ? ? ? A[0][0] == A[1][0] == A[2][0] == 1 or A[0][1] == A[1][1] == A[2][1] == 1 or A[0][2] == A[1][2] == \
? ? ? ? ? ? A[2][
? ? ? ? ? ? ? ? 2] == 1 or \
? ? ? ? ? ? A[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1:
? ? ? ? tkinter.messagebox.showinfo('消息提示', '叉號(hào)獲勝')
w1.bind("<Button -1>", dawn)我們拆開進(jìn)行分析:
首先是:點(diǎn)擊位置的確定,得到我們的點(diǎn)擊單元格,開始時(shí)我是用的是判斷是否在方格的內(nèi)切圓范圍內(nèi),發(fā)現(xiàn)點(diǎn)擊到方格的剩余部分會(huì)導(dǎo)致化的圖形錯(cuò)位,通過(guò)進(jìn)一步的分析發(fā)現(xiàn),可以通過(guò)分別定位點(diǎn)擊位置的橫縱坐標(biāo),確定點(diǎn)擊的方格。
for i in range(0, 3): ? ? ? ? for j in range(0, 3): ? ? ? ? ? ? if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180: ? ? ? ? ? ? ? ? break ? ? ? ? if 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180: ? ? ? ? ? ? break
接著,確定了位置以后我們就開始判斷當(dāng)前位置是否能畫圖形,應(yīng)該畫什么圖形,畫?是比較麻煩的需要進(jìn)行復(fù)雜的計(jì)算,畫?就比較簡(jiǎn)單。
if num % 2 == 0 and A[i][j] == 0:?? ??? ??? ?#若為偶數(shù)就畫叉號(hào) ? ? ? ? A[i][j] = 1 ? ? ? ? w1.create_line(110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2), ? ? ? ? ? ? ? ? ? ? ? ?110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2)) ? ? ? ? w1.create_line(110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2), ? ? ? ? ? ? ? ? ? ? ? ?110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2)) ? ? ? ? num += 1 ? ? if num % 2 != 0 and A[i][j] == 0:?? ??? ?#若為奇數(shù)就畫圓圈 ? ? ? ? A[i][j] = 2 ? ? ? ? w1.create_oval(20 + 180 * i, 20 + 180 * j, 20 + 180 * (i + 1), 20 + 180 * (j + 1)) ? ? ? ? num += 1
畫完以后我們要判斷是否達(dá)到獲勝的條件,這里我沒(méi)想到簡(jiǎn)便的方法,但是好在獲勝的情況屈指可數(shù),只有八種(橫3,豎3,兩個(gè)斜方向的)于是將八種情況列出進(jìn)行判斷是否達(dá)到獲勝條件,而且兩種圖形都需要列出。
if A[0][0] == A[0][1] == A[0][2] == 2 or A[1][0] == A[1][1] == A[1][2] == 2 or A[2][0] == A[2][1] == A[2][
? ? ? ? 2] == 2 or \
? ? ? ? ? ? A[0][0] == A[1][0] == A[2][0] == 2 or A[0][1] == A[1][1] == A[2][1] == 2 or A[0][2] == A[1][2] == \
? ? ? ? ? ? A[2][
? ? ? ? ? ? ? ? 2] == 2 or \
? ? ? ? ? ? A[0][0] == A[1][1] == A[2][2] == 2 or A[2][0] == A[1][1] == A[0][2] == 2:
? ? ? ? tkinter.messagebox.showinfo('消息提示', '圓圈獲勝')
? ? elif A[0][0] == A[0][1] == A[0][2] == 1 or A[1][0] == A[1][1] == A[1][2] == 1 or A[2][0] == A[2][1] == A[2][
? ? ? ? 2] == 1 or \
? ? ? ? ? ? A[0][0] == A[1][0] == A[2][0] == 1 or A[0][1] == A[1][1] == A[2][1] == 1 or A[0][2] == A[1][2] == \
? ? ? ? ? ? A[2][
? ? ? ? ? ? ? ? 2] == 1 or \
? ? ? ? ? ? A[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1:
? ? ? ? tkinter.messagebox.showinfo('消息提示', '叉號(hào)獲勝')最后設(shè)置點(diǎn)擊時(shí)間的獲取以及退出按鈕的設(shè)置。
w1.bind("<Button -1>", dawn)
def quit():
? ? root.quit()
button1 = Button(root, text="退出", font=('楷體', 20), command=quit)
button1.pack()到這里游戲的每個(gè)代碼都講解完了。

附完整代碼:
from tkinter import *
import numpy as np
import math
import tkinter.messagebox
root = Tk() ? ? ? ? #窗口名稱
root.title("憨憨制作的三子棋")
f1=Frame(root)
f1.pack()
w1 = Canvas(f1, width=580,height=580,background='lightcyan')
w1.pack()
#棋盤
for i in range(0, 4):
? ? w1.create_line(i * 180 + 20, 20, i * 180 + 20, 560)
? ? w1.create_line(20, i * 180 + 20, 560, i * 180 + 20)
num = 0
A = np.full((3, 3), 0)
def dawn(event):
? ? global w1
? ? global num, A
? ? for i in range(0, 3):
? ? ? ? for j in range(0, 3):
? ? ? ? ? ? if 20 + j * 180 < event.y and event.y <= 20 + (j+1) * 180:
? ? ? ? ? ? ? ? break
? ? ? ? if 20 + i * 180 <= event.x and event.x <= 20 + (i+1) * 180:
? ? ? ? ? ? break
? ? if num % 2 == 0 and A[i][j] == 0:
? ? ? ? A[i][j] = 1
? ? ? ? w1.create_line(110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),
? ? ? ? ? ? ? ? ? ? ? ?110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2))
? ? ? ? w1.create_line(110 + 180 * i + 45 * math.sqrt(2), 110 + 180 * j - 45 * math.sqrt(2),
? ? ? ? ? ? ? ? ? ? ? ?110 + 180 * i - 45 * math.sqrt(2), 110 + 180 * j + 45 * math.sqrt(2))
? ? ? ? num += 1
? ? if num % 2 != 0 and A[i][j] == 0:
? ? ? ? A[i][j] = 2
? ? ? ? w1.create_oval(20 + 180 * i, 20 + 180 * j, 20 + 180 * (i + 1), 20 + 180 * (j + 1))
? ? ? ? num += 1
? ? if A[0][0] == A[0][1] == A[0][2] == 2 or A[1][0] == A[1][1] == A[1][2] == 2 or A[2][0] == A[2][1] == A[2][
? ? ? ? 2] == 2 or \
? ? ? ? ? ? A[0][0] == A[1][0] == A[2][0] == 2 or A[0][1] == A[1][1] == A[2][1] == 2 or A[0][2] == A[1][2] == \
? ? ? ? ? ? A[2][
? ? ? ? ? ? ? ? 2] == 2 or \
? ? ? ? ? ? A[0][0] == A[1][1] == A[2][2] == 2 or A[2][0] == A[1][1] == A[0][2] == 2:
? ? ? ? tkinter.messagebox.showinfo('消息提示', '圓圈獲勝')
? ? elif A[0][0] == A[0][1] == A[0][2] == 1 or A[1][0] == A[1][1] == A[1][2] == 1 or A[2][0] == A[2][1] == A[2][
? ? ? ? 2] == 1 or \
? ? ? ? ? ? A[0][0] == A[1][0] == A[2][0] == 1 or A[0][1] == A[1][1] == A[2][1] == 1 or A[0][2] == A[1][2] == \
? ? ? ? ? ? A[2][
? ? ? ? ? ? ? ? 2] == 1 or \
? ? ? ? ? ? A[0][0] == A[1][1] == A[2][2] == 1 or A[2][0] == A[1][1] == A[0][2] == 1:
? ? ? ? tkinter.messagebox.showinfo('消息提示', '叉號(hào)獲勝')
w1.bind("<Button -1>", dawn)
def quit():
? ? root.quit()
button1 = Button(root, text="退出", font=('楷體', 20), command=quit)
button1.pack()
root.mainloop()游戲?qū)崿F(xiàn)只是個(gè)人的思路和操作,可能會(huì)有很多的不足,有愿意一起研究的朋友可以聯(lián)系我,愿意虛心請(qǐng)教。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python提取PDF中的圖片的實(shí)現(xiàn)示例
本文主要介紹了Python提取PDF中的圖片的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
python網(wǎng)絡(luò)編程學(xué)習(xí)筆記(10):webpy框架
webpy小巧,簡(jiǎn)單,實(shí)用,可以快速的完成簡(jiǎn)單的web頁(yè)面。這里根據(jù)webpy Cookbook簡(jiǎn)要的介紹一下webpy框架,需要的朋友可以參考下2014-06-06
使用PyTorch/TensorFlow搭建簡(jiǎn)單全連接神經(jīng)網(wǎng)絡(luò)
在本篇博客中,我們將介紹如何使用兩大深度學(xué)習(xí)框架——PyTorch 和 TensorFlow,構(gòu)建一個(gè)簡(jiǎn)單的全連接神經(jīng)網(wǎng)絡(luò),該網(wǎng)絡(luò)包含輸入層、一個(gè)隱藏層和輸出層,適合初學(xué)者理解神經(jīng)網(wǎng)絡(luò)的基本構(gòu)建模塊及訓(xùn)練流程,需要的朋友可以參考下2025-02-02
Python標(biāo)準(zhǔn)庫(kù)學(xué)習(xí)之psutil內(nèi)存詳解
本篇文章給大家介紹一個(gè)Python標(biāo)準(zhǔn)庫(kù)中的psutil模塊,它是一個(gè)跨平臺(tái)庫(kù),下面來(lái)學(xué)習(xí)一下器常用的功能及使用方法吧,有需要的同學(xué)可以借鑒參考下2021-09-09
PyTorch數(shù)據(jù)讀取的實(shí)現(xiàn)示例
這篇文章主要介紹了PyTorch數(shù)據(jù)讀取的實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03
6個(gè)實(shí)用的Python自動(dòng)化腳本詳解
每天你都可能會(huì)執(zhí)行許多重復(fù)的任務(wù),例如閱讀 pdf、播放音樂(lè)、查看天氣、打開書簽、清理文件夾等等,使用自動(dòng)化腳本,就無(wú)需手動(dòng)一次又一次地完成這些任務(wù),非常方便。快跟隨小編一起試一試吧2022-01-01

