Python打造視覺(jué)精美的數(shù)獨(dú)小游戲?qū)崙?zhàn)記錄
一、前言
Python作為一門簡(jiǎn)潔、易讀、功能強(qiáng)大的編程語(yǔ)言,其基礎(chǔ)語(yǔ)法是入門學(xué)習(xí)的核心。掌握好基礎(chǔ)語(yǔ)法,能為后續(xù)的編程實(shí)踐打下堅(jiān)實(shí)的基礎(chǔ)。本文將全面講解Python3的基礎(chǔ)語(yǔ)法知識(shí),適合編程初學(xué)者系統(tǒng)學(xué)習(xí)。Python以其簡(jiǎn)潔優(yōu)雅的語(yǔ)法和強(qiáng)大的通用性,成為當(dāng)今最受歡迎的編程語(yǔ)言。本專欄旨在系統(tǒng)性地帶你從零基礎(chǔ)入門到精通Python核心。無(wú)論你是零基礎(chǔ)小白還是希望進(jìn)階的專業(yè)開(kāi)發(fā)者,都將通過(guò)清晰的講解、豐富的實(shí)例和實(shí)戰(zhàn)項(xiàng)目,逐步掌握語(yǔ)法基礎(chǔ)、核心數(shù)據(jù)結(jié)構(gòu)、函數(shù)與模塊、面向?qū)ο缶幊?、文件處理、主流?kù)應(yīng)用(如數(shù)據(jù)分析、Web開(kāi)發(fā)、自動(dòng)化)以及面向?qū)ο蟾呒?jí)特性,最終具備獨(dú)立開(kāi)發(fā)能力和解決復(fù)雜問(wèn)題的思維,高效應(yīng)對(duì)數(shù)據(jù)分析、人工智能、Web應(yīng)用、自動(dòng)化腳本等廣泛領(lǐng)域的實(shí)際需求。
數(shù)獨(dú)是一款經(jīng)典的邏輯推理數(shù)字游戲,通過(guò)填充數(shù)字1-9到9x9的網(wǎng)格中,使得每行、每列和每個(gè)3x3子網(wǎng)格都包含1-9的所有數(shù)字,不重復(fù)。本文將帶大家使用Python的Pygame庫(kù)實(shí)現(xiàn)一個(gè)視覺(jué)精美、交互友好的數(shù)獨(dú)小游戲。
二、開(kāi)發(fā)準(zhǔn)備
2.1 所需環(huán)境
- Python 3.6+
- Pygame庫(kù)(用于圖形界面和交互)
2.2安裝依賴
首先確保安裝了Pygame庫(kù),如果沒(méi)有安裝,可以使用pip命令安裝:
pip install pygame
三、項(xiàng)目結(jié)構(gòu)設(shè)計(jì)
我們將項(xiàng)目分為兩個(gè)主要文件:
main.py:負(fù)責(zé)游戲界面渲染和用戶交互build.py:負(fù)責(zé)數(shù)獨(dú)謎題的生成和驗(yàn)證邏輯
這種分離設(shè)計(jì)使代碼結(jié)構(gòu)更清晰,便于維護(hù)和擴(kuò)展。
四 、核心功能實(shí)現(xiàn)
4.1. 數(shù)獨(dú)謎題生成與驗(yàn)證(build.py)
首先實(shí)現(xiàn)數(shù)獨(dú)的核心邏輯,包括數(shù)獨(dú)生成、驗(yàn)證等功能:
import random
def print_matrix(matrix):
"""打印矩陣,用于調(diào)試"""
print('—'*19)
for row in matrix:
print('|'+' '.join([str(col) for col in row])+'|')
print('—'*19)
def shuffle_number(_list):
"""隨機(jī)打亂列表,用于生成不同的數(shù)獨(dú)"""
random.shuffle(_list)
return _list
def check(matrix, i, j, number):
"""
檢查數(shù)字是否可以放置在指定位置
規(guī)則:行、列、3x3子網(wǎng)格中不能有重復(fù)數(shù)字
"""
# 檢查行
if number in matrix[i]:
return False
# 檢查列
if number in [row[j] for row in matrix]:
return False
# 檢查3x3子網(wǎng)格
group_i, group_j = int(i/3), int(j/3)
if number in [matrix[i][j] for i in range(group_i*3, (group_i+1)*3)
for j in range(group_j*3, (group_j+1)*3)]:
return False
return True
def build_game(matrix, i, j, number):
"""遞歸構(gòu)建完整數(shù)獨(dú)矩陣"""
if i > 8 or j > 8:
return matrix
if check(matrix, i, j, number):
# 創(chuàng)建矩陣副本進(jìn)行修改
_matrix = [[col for col in row] for row in matrix]
_matrix[i][j] = number
# 計(jì)算下一個(gè)位置
next_i, next_j = (i+1, 0) if j == 8 else (i, j+1)
# 嘗試下一個(gè)位置的所有可能數(shù)字
for _number in shuffle_number(number_list):
__matrix = build_game(_matrix, next_i, next_j, _number)
# 驗(yàn)證是否生成了完整有效的數(shù)獨(dú)
if __matrix and sum([sum(row) for row in __matrix]) == (sum(range(1,10)) * 9):
return __matrix
return None
def give_me_a_game(blank_size=9):
"""生成帶空白的數(shù)獨(dú)游戲"""
# 生成完整數(shù)獨(dú)
matrix_all = build_game(matrix, 0, 0, random.choice(number_list))
# 隨機(jī)生成要空白的位置
set_ij = set()
while len(list(set_ij)) < blank_size:
set_ij.add(f"{random.choice(range(9))},{random.choice(range(9))}")
# 創(chuàng)建帶空白的數(shù)獨(dú)
matrix_blank = [[col for col in row] for row in matrix_all]
blank_ij = []
for ij in list(set_ij):
i, j = int(ij.split(',')[0]), int(ij.split(',')[1])
blank_ij.append((i, j))
matrix_blank[i][j] = 0
return matrix_all, matrix_blank, blank_ij
# 全局變量
number_list = [1,2,3,4,5,6,7,8,9]
matrix = [([0]*9) for i in range(9)]
if __name__ == "__main__":
# 測(cè)試生成數(shù)獨(dú)
print_matrix(build_game(matrix, 0, 0, random.choice(number_list)))
4.2. 游戲界面與交互(main.py)
接下來(lái)實(shí)現(xiàn)游戲的可視化界面和用戶交互邏輯:
import sys
import pygame
from pygame.color import THECOLORS as COLORS
from build import print_matrix, give_me_a_game, check
def draw_background():
"""繪制游戲背景和網(wǎng)格"""
# 白色背景
screen.fill(COLORS['white'])
# 繪制9x9網(wǎng)格,加粗繪制3x3大格子邊界
# 垂直線
for i in range(10):
line_width = 5 if i % 3 == 0 else 2
pygame.draw.line(screen, COLORS['black'],
(i*100, 0), (i*100, 900), line_width)
# 水平線
for i in range(10):
line_width = 5 if i % 3 == 0 else 2
pygame.draw.line(screen, COLORS['black'],
(0, i*100), (900, i*100), line_width)
def draw_choose():
"""繪制當(dāng)前選中的單元格高亮框"""
# 繪制藍(lán)色高亮框,留出邊框
pygame.draw.rect(screen, COLORS['blue'],
(cur_j*100+5, cur_i*100+5, 100-10, 100-10), 0)
def check_win(matrix_all, matrix):
"""檢查是否完成數(shù)獨(dú)"""
return matrix_all == matrix
def check_color(matrix, i, j):
"""檢查數(shù)字是否符合規(guī)則,返回對(duì)應(yīng)的顏色"""
_matrix = [[col for col in row] for row in matrix]
_matrix[i][j] = 0 # 臨時(shí)清空當(dāng)前位置以便檢查
if check(_matrix, i, j, matrix[i][j]):
return COLORS['green'] # 合法數(shù)字顯示綠色
return COLORS['red'] # 非法數(shù)字顯示紅色
def draw_number():
"""繪制數(shù)獨(dú)中的數(shù)字"""
for i in range(len(MATRIX)):
for j in range(len(MATRIX[0])):
# 空白格子的數(shù)字顏色根據(jù)合法性變化,固定數(shù)字顯示灰色
_color = check_color(MATRIX, i, j) if (i,j) in BLANK_IJ else COLORS['gray']
# 渲染數(shù)字,空值不顯示
txt = font80.render(
str(MATRIX[i][j] if MATRIX[i][j] not in [0, '0'] else ''),
True, _color)
x, y = j*100 + 30, i*100 + 10 # 居中顯示
screen.blit(txt, (x, y))
def draw_context():
"""繪制游戲狀態(tài)信息"""
txt = font100.render(
f'Blank: {cur_blank_size} Changes: {cur_change_size}',
True, COLORS['black'])
screen.blit(txt, (10, 900)) # 顯示在底部
if __name__ == "__main__":
# 初始化pygame
pygame.init()
# 常量定義
SIZE = [900, 1000] # 窗口大小,額外100像素顯示狀態(tài)信息
font80 = pygame.font.SysFont('Times', 80) # 數(shù)字字體
font100 = pygame.font.SysFont('Times', 90) # 狀態(tài)信息字體
# 創(chuàng)建窗口
screen = pygame.display.set_mode(SIZE)
pygame.display.set_caption("數(shù)獨(dú)小游戲") # 設(shè)置窗口標(biāo)題
# 變量初始化
cur_i, cur_j = 0, 0 # 當(dāng)前選中的單元格
cur_blank_size = int(sys.argv[1]) if len(sys.argv) > 1 else 10 # 空白數(shù)量,可通過(guò)命令行參數(shù)設(shè)置
cur_change_size = 0 # 已修改次數(shù)
# 生成數(shù)獨(dú)游戲
MATRIX_ANSWER, MATRIX, BLANK_IJ = give_me_a_game(blank_size=cur_blank_size)
print(BLANK_IJ)
print_matrix(MATRIX)
# 主游戲循環(huán)
running = True
while running:
# 事件處理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
break
elif event.type == pygame.MOUSEBUTTONDOWN:
# 鼠標(biāo)點(diǎn)擊選擇單元格
x, y = event.pos
cur_j, cur_i = int(x / 100), int(y / 100)
# 確保選擇在有效范圍內(nèi)
cur_i = max(0, min(8, cur_i))
cur_j = max(0, min(8, cur_j))
elif event.type == pygame.KEYUP:
# 鍵盤輸入數(shù)字
if chr(event.key) in ['1','2','3','4','5','6','7','8','9'] and (cur_i, cur_j) in BLANK_IJ:
MATRIX[cur_i][cur_j] = int(chr(event.key))
# 更新空白數(shù)量
cur_blank_size = sum(1 for row in MATRIX for col in row if col in [0, '0'])
cur_change_size += 1
# 繪制游戲元素
draw_background()
draw_choose()
draw_number()
draw_context()
# 刷新屏幕
pygame.display.flip()
# 檢查是否完成
if check_win(MATRIX_ANSWER, MATRIX):
print('恭喜你,完成了數(shù)獨(dú)挑戰(zhàn)!')
break
# 退出游戲
pygame.quit()
運(yùn)行效果圖:

五 、 功能解析
5.1. 數(shù)獨(dú)生成邏輯
build_game()函數(shù)使用遞歸回溯算法生成完整的數(shù)獨(dú)矩陣give_me_a_game()函數(shù)從完整數(shù)獨(dú)中隨機(jī)挖去指定數(shù)量的數(shù)字作為謎題check()函數(shù)驗(yàn)證數(shù)字放置是否符合數(shù)獨(dú)規(guī)則
5.2. 游戲界面設(shè)計(jì)
- 9x9的網(wǎng)格布局,使用不同粗細(xì)的線條區(qū)分3x3子網(wǎng)格
- 選中的單元格會(huì)顯示藍(lán)色高亮框
- 固定數(shù)字顯示為灰色,玩家輸入的數(shù)字根據(jù)合法性顯示綠色(合法)或紅色(非法)
- 底部狀態(tài)欄顯示剩余空白數(shù)量和已修改次數(shù)
5.3. 用戶交互
- 鼠標(biāo)點(diǎn)擊選擇單元格
- 鍵盤輸入1-9數(shù)字填充選中的空白單元格
- 自動(dòng)檢查輸入合法性并通過(guò)顏色提示
- 完成數(shù)獨(dú)后自動(dòng)提示成功
六、游戲玩法
運(yùn)行程序,可通過(guò)命令行參數(shù)指定空白格數(shù)量(難度):
python main.py 20 # 生成有20個(gè)空白格的數(shù)獨(dú)
鼠標(biāo)點(diǎn)擊要填充的單元格(藍(lán)色高亮顯示)
按鍵盤1-9數(shù)字鍵填入數(shù)字
綠色數(shù)字表示符合數(shù)獨(dú)規(guī)則,紅色數(shù)字表示有沖突
填滿所有空白且全部正確后,游戲結(jié)束并提示成功
七、優(yōu)化建議
- 增加難度選擇界面,無(wú)需通過(guò)命令行參數(shù)設(shè)置
- 添加計(jì)時(shí)器功能,記錄完成時(shí)間
- 增加錯(cuò)誤次數(shù)限制
- 添加提示功能
- 優(yōu)化UI,增加更精美的背景和動(dòng)畫效果
- 保存游戲進(jìn)度功能
八、總結(jié)
本項(xiàng)目通過(guò)Pygame實(shí)現(xiàn)了一個(gè)功能完整的數(shù)獨(dú)游戲,包含了數(shù)獨(dú)生成、規(guī)則驗(yàn)證、用戶交互等核心功能。代碼結(jié)構(gòu)清晰,注釋完善,便于理解和擴(kuò)展。
通過(guò)這個(gè)項(xiàng)目,我們學(xué)習(xí)了遞歸回溯算法在數(shù)獨(dú)生成中的應(yīng)用,以及如何使用Pygame構(gòu)建圖形界面和處理用戶交互。希望這個(gè)教程能幫助你入門Python游戲開(kāi)發(fā),也歡迎在此基礎(chǔ)上進(jìn)行更多創(chuàng)新和改進(jìn)!
附錄:擴(kuò)展學(xué)習(xí)資源
- 官方資源:
- Python官網(wǎng):https://www.python.org
- PyPI:https://pypi.org(查找第三方庫(kù))
- 安裝包等相關(guān)文件(另附帶pycharm工具),下載地址:http://m.fzitv.net/softs/598504.html
到此這篇關(guān)于Python打造視覺(jué)精美的數(shù)獨(dú)小游戲的文章就介紹到這了,更多相關(guān)Python數(shù)獨(dú)小游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python使用sorted函數(shù)對(duì)列表進(jìn)行排序的方法
這篇文章主要介紹了python使用sorted函數(shù)對(duì)列表進(jìn)行排序的方法,涉及Python使用sorted函數(shù)的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2015-04-04
Pandas數(shù)據(jù)操作分析基本常用的15個(gè)代碼片段
這篇文章主要介紹了Pandas數(shù)據(jù)操作分析基本常用的15個(gè)代碼片段,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
酷! 程序員用Python帶你玩轉(zhuǎn)沖頂大會(huì)
程序員用Python玩轉(zhuǎn)王思聰?shù)摹稕_頂大會(huì)》,感興趣的小伙伴們可以參考一下2018-01-01
Python通過(guò)Pillow實(shí)現(xiàn)圖片對(duì)比
這篇文章主要介紹了Python Pillow實(shí)現(xiàn)圖片對(duì)比,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Python+Selenium+PIL+Tesseract自動(dòng)識(shí)別驗(yàn)證碼進(jìn)行一鍵登錄
本篇文章主要介紹了Python+Selenium+PIL+Tesseract自動(dòng)識(shí)別驗(yàn)證碼進(jìn)行一鍵登錄,具有一定的參考價(jià)值,有興趣的可以了解下2017-09-09
如何導(dǎo)出python安裝的所有模塊名稱和版本號(hào)到文件中
Python 模塊(Module),是一個(gè) Python 文件,以 .py 結(jié)尾,包含了 Python 對(duì)象定義和Python語(yǔ)句。這篇文章主要介紹了如何導(dǎo)出python安裝的所有模塊名稱和版本號(hào)到文件中,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2020-06-06
Python除法之傳統(tǒng)除法、Floor除法及真除法實(shí)例詳解
本文通過(guò)實(shí)例代碼給大家介紹了Python除法之傳統(tǒng)除法、Floor除法及真除法,需要的朋友可以參考下2019-05-05

