使用pygame寫(xiě)一個(gè)古詩(shī)詞填空通關(guān)游戲
之前寫(xiě)的詩(shī)詞填空的游戲支持python2,現(xiàn)在對(duì)程序進(jìn)行了修改,兼容支持python2和python3,附下效果圖。

下面是兩個(gè)主程序
idiom_lib.py代碼:
# -*- coding=utf-8 -*-
import sys
import random
if sys.version_info < (3,0):
reload(sys)
sys.setdefaultencoding('utf-8')
elif sys.version_info <= (3,3):
import imp
imp.reload(sys)
else:
import importlib
importlib.reload(sys)
class IdiomInfo(object):
def __init__(self,idiom):
self.idiom = idiom
self.dire = 0
self.word_arr = []
def to_str(self):
arr = []
for word_info in self.word_arr:
arr.append('%s %s %s'%(word_info.i,word_info.j,word_info.word))
return '%s,%s,%s'%(self.idiom, self.dire, '|'.join(arr))
class WordInfo(object):
def __init__(self, word, i, j):
self.i = i
self.j = j
self.word = word
self.is_lock = True
self.state = -1
self.hide_index = -1
self.op_hide_index = -1
class Matrix(object):
rows = 0
cols = 0
data = []
def __init__(self, rows, cols, data=None):
self.rows = rows
self.cols = cols
if data is None: data = [None for i in range(rows * cols)]
self.data = data
def set_val(self, x, y, val):
self.data[y * self.cols + x] = val
def get_val(self, x, y):
return self.data[y * self.cols + x]
def exist_val_four_around(self, x, y, ignore_set):
move_arr = [(-1,0),(1,0),(0,-1),(0,1)]
for dx,dy in move_arr:
tx = x + dx
ty = y + dy
if (tx,ty) in ignore_set: continue
if tx < 0 or tx >= self.cols or ty <0 or ty >= self.rows: continue
if self.data[ty * self.cols + tx]: return True
return False
class IdiomLib():
def __init__(self, block_num=12):
self.word_dic={}
self.word_arr=[]
self.block_num=block_num
self.matrix = Matrix(self.block_num, self.block_num)
self.idiom_dic={}
self.all_word_num=0
self.hide_arr = []
def load_idiom_from_file(self, filename='poetry.txt'):
if sys.version_info < (3,0):
f = open(filename)
else:
f = open(filename,encoding='UTF-8')
all_idiom = f.readlines()
f.close()
for idiom in all_idiom:
if sys.version_info < (3,0):
idiom = idiom.strip().decode('utf-8')
else:
idiom = idiom.strip()
for word in idiom:
if word not in self.word_dic:
self.word_dic[word] = [idiom]
else:
self.word_dic[word].append(idiom)
self.word_arr = list(self.word_dic.keys())
def check_new_idiom(self, new_idiom, new_dire, word_info):
windex = new_idiom.index(word_info.word)
cx,cy = word_info.i, word_info.j
ignore_set = set([(cx,cy)])
new_idiom_word_arr=[]
for i in range(-windex,-windex+len(new_idiom)):
if i==0:
new_idiom_word_arr.append(word_info)
else:
tx = cx+i if new_dire == 0 else cx
if tx < 0 or tx >= self.block_num: return None,None
ty = cy if new_dire == 0 else cy+i
if ty < 0 or ty >= self.block_num: return None,None
if self.matrix.exist_val_four_around(tx, ty, ignore_set): return None,None
old_word_info = self.matrix.get_val(tx, ty)
if old_word_info:
return None,None
new_word_info = WordInfo(new_idiom[i+windex], tx, ty)
new_idiom_word_arr.append(new_word_info)
return new_idiom_word_arr,windex
def add_idiom_to_matrix(self, idiom_num):
if idiom_num == 0: return 0
for idiom,idiom_info in self.idiom_dic.items():
dire = idiom_info.dire
new_dire = 1 - dire
for word_info in idiom_info.word_arr:
word = word_info.word
idiom_list = self.word_dic[word]
for new_idiom in idiom_list:
if new_idiom in self.idiom_dic: continue
new_idiom_word_arr,windex = self.check_new_idiom(new_idiom, new_dire, word_info)
if new_idiom_word_arr:
new_idiom_info = IdiomInfo(new_idiom)
new_idiom_info.dire = new_dire
for new_index in range(len(new_idiom_word_arr)):
new_word_info = new_idiom_word_arr[new_index]
if new_index == windex:
new_idiom_info.word_arr.append(word_info)
else:
self.matrix.set_val(new_word_info.i, new_word_info.j , new_word_info)
new_idiom_info.word_arr.append(new_word_info)
self.idiom_dic[new_idiom] = new_idiom_info
return len(new_idiom) -1 + self.add_idiom_to_matrix(idiom_num - 1)
return 0
def get_idiom_matrix(self, idiom_num):
self.idiom_dic={}
cx = int(self.block_num/2)-1
cy = int(self.block_num/2)-1
n = random.randint(0,len(self.word_arr)-1)
word = self.word_arr[n]
idiom = self.word_dic[word][0]
wn = len(idiom)
self.idiom_dic[idiom] = IdiomInfo(idiom)
last_i = -100
for i in range(len(idiom)):
word_info = WordInfo(idiom[i],cx-int(wn/2)+1+i,cy)
self.matrix.set_val(cx-int(wn/2)+1+i,cy,word_info)
self.idiom_dic[idiom].word_arr.append(word_info)
wn += self.add_idiom_to_matrix(idiom_num-1)
return wn
def get_hide_arr(self, percent):
self.hide_arr=[]
idiom_word_arr = []
for k,v in self.idiom_dic.items():
arr = []
for word_info in v.word_arr:
arr.append(word_info)
idiom_word_arr.append([k, arr])
#idiom_word_arr.sort(cmp=lambda x,y:cmp(len(y[-1]),len(x[-1])))
idiom_word_arr.sort(key=lambda x:len(x[-1]))
idiom_index = 0
while len(self.hide_arr) < self.all_word_num*percent:
tmp_arr = idiom_word_arr[idiom_index%len(idiom_word_arr)][1]
n = random.randint(0,len(tmp_arr)-1)
info = tmp_arr.pop(n)
word=info.word
info.word = ''
info.hide_index = len(self.hide_arr)
info.is_lock = False
self.hide_arr.append([info.i,info.j,word,None])
idiom_index+=1
return self.hide_arr
def get_next_select(self, x, y):
arr = []
for i in range(self.block_num):
for j in range(self.block_num):
info = self.matrix.get_val(i, j)
if info is not None and len(info.word) == 0:
dist = (i-x)*(i-x)+(j-y)*(j-y)
if i<x: dist+=0.2
if j<y: dist+=0.4
arr.append((i,j,dist))
if len(arr) == 0:
return None
#arr.sort(cmp=lambda x,y:cmp(x[-1],y[-1]))
arr.sort(key=lambda x:x[-1])
return (arr[0][0],arr[0][1])
def check_idiom(self):
for idiom, idiom_info in self.idiom_dic.items():
tmp_idiom_str = ''
word_arr = idiom_info.word_arr
for word_info in word_arr:
word = word_info.word
if len(word) > 0:
tmp_idiom_str+=word
if len(tmp_idiom_str) == len(idiom):
state = 1 if tmp_idiom_str == idiom else 2
else:
state = 0
for word_info in word_arr:
if word_info.state != 1: word_info.state = state
for idiom, idiom_info in self.idiom_dic.items():
word_arr = idiom_info.word_arr
for word_info in word_arr:
if word_info.state != 1:
return False
return True
stage = 1
def init(self, new_stage):
idiom_num = int(new_stage/5)+3
if new_stage>100:
percent = 0.7
else:
percent = 0.2+(new_stage*1.0/100)*(0.7-0.2)
self.matrix = Matrix(self.block_num, self.block_num)
self.all_word_num = self.get_idiom_matrix(idiom_num)
self.get_hide_arr(percent)
self.select_rect = self.hide_arr[0][0],self.hide_arr[0][1]
if __name__ == '__main__':
pass
main.py的代碼
# -*- coding=utf-8 -*-
import sys
import random
import pygame
from pygame.locals import *
from idiom_lib import IdiomLib
if sys.version_info < (3,0):
reload(sys)
sys.setdefaultencoding('utf-8')
elif sys.version_info <= (3,3):
import imp
imp.reload(sys)
else:
import importlib
importlib.reload(sys)
block_num=12
lib = IdiomLib(block_num=block_num)
lib.load_idiom_from_file()
header_height = 30
main_space = 20
block_size = 36
bspace = 2
space = 20
width = block_size * block_num + main_space * 2
height = header_height + block_size * block_num + main_space * 2 + (block_size+space) * 3
pygame.init()
screen = pygame.display.set_mode((width,height))
screencaption = pygame.display.set_caption(u'詩(shī)詞填空')
font = pygame.font.Font(u'syht.otf', int(block_size*0.8))
dray_gray = 50,50,200
white = 255,255,255
#textImage = font.render(u'你好', True, white)
bg_image = pygame.image.load('bg.jpeg')
bg_image = pygame.transform.scale(bg_image,(width, height))
bg2_image = pygame.image.load('bg2.jpeg')
bg2_image = pygame.transform.scale(bg2_image,(block_size*block_num,block_size*block_num))
block_bg_image = pygame.image.load('tzg.jpg')
block_bg_image = pygame.transform.scale(block_bg_image,(block_size-bspace*2,block_size-bspace*2))
stage = 1
lib.init(stage)
stage_textImage = pygame.font.Font(u'syht.otf', 30).render(u'第%s關(guān)'%stage, True, dray_gray)
stage_font_width, stage_font_height = stage_textImage.get_size()
stage_x = int((width - stage_font_width)/2)
stage_y = int((header_height - stage_font_height)/2)+int(main_space/2)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
if event.type == MOUSEBUTTONDOWN:
pressed_array = pygame.mouse.get_pressed()
if pressed_array[0]:
x, y = pygame.mouse.get_pos()
for i in range(block_num):
for j in range(block_num):
bx = main_space + block_size*i+bspace
by = header_height + main_space + block_size*j+bspace
if x >= bx and x <= bx+block_size-bspace*2 and y >= by and y<= by+block_size-bspace*2:
info = lib.matrix.get_val(i, j)
if info and info.state != 1 and info.hide_index >= 0:
if info.op_hide_index>=0:
lib.hide_arr[info.op_hide_index][-1] = None
info.word = ''
info.op_hide_index=-1
lib.check_idiom()
lib.select_rect = i,j
break
sx = main_space
sy = header_height + main_space+ block_size*block_num +space
n = 0
for hi in range(len(lib.hide_arr)):
tmp_x = sx + (n%block_num)*block_size
tmp_y = sy + int(n/block_num)*block_size
if lib.hide_arr[hi][-1] is None and x >= tmp_x and x <= tmp_x+block_size-bspace*2 and y >= tmp_y and y<= tmp_y+block_size-bspace*2:
info = lib.matrix.get_val(lib.select_rect[0],lib.select_rect[1])
info.word = lib.hide_arr[hi][2]
info.op_hide_index = hi
info.state = 0
lib.hide_arr[hi][-1] = lib.select_rect
lib.select_rect = lib.get_next_select(lib.select_rect[0],lib.select_rect[1])
flag = lib.check_idiom()
if flag:
stage += 1
lib.init(stage)
stage_textImage = pygame.font.Font(u'syht.otf', 30).render(u'第%s關(guān)'%stage, True, dray_gray)
break
n += 1
screen.blit(bg_image, (0,0))
screen.blit(stage_textImage, (stage_x,stage_y))
panel = screen.subsurface((main_space,header_height+main_space,block_size*block_num,block_size*block_num))
panel.blit(bg2_image, (0,0))
for i in range(block_num):
for j in range(block_num):
info = lib.matrix.get_val(i,j)
if info is not None:
bx = block_size*i+bspace
by = block_size*j+bspace
panel.blit(block_bg_image, (bx,by))
if info.state == 1:
textImage = font.render(info.word, True, (30,144,30))
elif info.is_lock == 1:
textImage = font.render(info.word, True, (100,100,100))
elif info.state == 2:
textImage = font.render(info.word, True, (255,0,0))
else:
textImage = font.render(info.word, True, dray_gray)
tw, th = textImage.get_size()
dx=int((block_size-bspace*2-tw)/2)
dy=int((block_size-bspace*2-th)/2)
panel.blit(textImage, (bx+dx,by+dy))
if (i,j) == lib.select_rect:
pygame.draw.rect(panel,(255,0,0),(bx,by,block_size-bspace*2,block_size-bspace*2),2)
sx = main_space
sy = header_height + main_space+ block_size*block_num +space
n = 0
for i,j,word,op in lib.hide_arr:
screen.blit(block_bg_image, (sx + (n%block_num)*block_size,sy + int(n/block_num)*block_size))
if op is None:
textImage = font.render(word, True, dray_gray)
tw, th = textImage.get_size()
dx=int((block_size-bspace*2-tw)/2)
dy=int((block_size-bspace*2-th)/2)
screen.blit(textImage, (dx+sx+ (n%block_num)*block_size,dy+sy+ int(n/block_num)*block_size))
n+=1
pygame.display.update()
代碼就這么多了,不過(guò)這邊用到幾個(gè)額外的依賴:
bg.jpeg 用于做整個(gè)界面的背景
bg2.jpeg 用于做上半部分的背景
tzg.jpg 每個(gè)文字的格子的背景
words.txt 一個(gè)成語(yǔ)的列表文件(每行一條成語(yǔ)),如果換成詩(shī)詞或者歇后語(yǔ)什么的也是沒(méi)有問(wèn)題的
syht.otf 一個(gè)字體庫(kù),用于正常顯示中文
運(yùn)行python main.py即可開(kāi)始游戲
如果嫌格子太多或者太小,可以調(diào)一下這兩個(gè)參數(shù)
block_size = 32 block_num=12
block_size 表示格子的大小
block_num 上半部分的區(qū)域橫豎最多顯示多少個(gè)格子
block_size = 26,block_num=18的效果圖:

block_size = 40,block_num=10的效果圖:

試試你的詩(shī)詞水平,看能沖到第幾關(guān)吧!
完整的資源已經(jīng)上傳本站:
http://xiazai.jb51.net/201912/yuanma/guess_idiom_jb51.rar
也可以直接從github下載
https://github.com/zhangenter/guess_idiom
總結(jié)
以上所述是小編給大家介紹的使用pygame寫(xiě)一個(gè)古詩(shī)詞填空通關(guān)游戲,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺(jué)得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
- python Pygame的具體使用講解
- Python中pygame的mouse鼠標(biāo)事件用法實(shí)例
- Python中pygame安裝方法圖文詳解
- 用Python寫(xiě)飛機(jī)大戰(zhàn)游戲之pygame入門(mén)(4):獲取鼠標(biāo)的位置及運(yùn)動(dòng)
- python使用PyGame繪制圖像并保存為圖片文件的方法
- python中pygame模塊用法實(shí)例
- 用python制作游戲外掛
- python基礎(chǔ)練習(xí)之幾個(gè)簡(jiǎn)單的游戲
- 使用Python寫(xiě)一個(gè)貪吃蛇游戲?qū)嵗a
- 用Python設(shè)計(jì)一個(gè)經(jīng)典小游戲
相關(guān)文章
python用pickle模塊實(shí)現(xiàn)“增刪改查”的簡(jiǎn)易功能
本篇文章主要介紹了python用pickle模塊實(shí)現(xiàn)“增刪改查”的簡(jiǎn)易功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-06-06
使用Python實(shí)現(xiàn)將list中的每一項(xiàng)的首字母大寫(xiě)
今天小編就為大家分享一篇使用Python實(shí)現(xiàn)將list中的每一項(xiàng)的首字母大寫(xiě),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
Python中的type與isinstance的區(qū)別詳解
本文主要介紹了Python中的type與isinstance的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04
使用Python實(shí)現(xiàn)全攝像頭拍照與鍵盤(pán)輸入監(jiān)聽(tīng)功能
這篇文章主要介紹了使用Python實(shí)現(xiàn)全攝像頭拍照與鍵盤(pán)輸入監(jiān)聽(tīng)功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08

