Python+Pygame实战之诗词填空游戏的实现
作者:木木子学python
成语接龙大家都玩过,但诗词填空大家玩过吗?把成语接龙变成填空题。难度可上涨了不止一个档次呢!本文就来用Python和Pygame实现诗词填空游戏,需要的可以参考一下
前言
哈喽!我是你们的栗子同学,今天给大家来点儿有趣的——有句话说:“读史使人明智,读诗使人灵秀。”唐诗本来就是中国文化的绚丽瑰宝,是每个人都该学习的人生必修课。栗子今天特意为大家整理了《唐诗三百首》合集,带你品读千年最美古诗。赶紧学起来吧!
成语接龙大家都玩过,但诗词填空大家玩过吗?把成语接龙变成填空题。
难度可上涨了不止一个档次呢!这就要考一考你对唐诗三百首的记忆里啦。是不是都还给老师了~哈哈哈哈。
如果你来玩,能完成多少诗句呢?今天栗子给大家写一个诗句填空的小游戏,看看你能闯关成功吗?
一、运行环境
1)前期准备
Python 3 、Pycharm、pygame。其他内置模块,安装好python环境就可以了。
pip install 模块名 (如果你觉得安 装速度比较慢, 你可以切换国内镜像源)
2)素材资料
二、代码展示
1)主程序: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'诗词填空') 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关'%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关'%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()
2)程序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=[] # for k,v in self.idiom_dic.items(): # n = random.randint(0, len(v.word_arr)-1) # word_info = v.word_arr[n] # if word_info.hide_index != -1:continue # word = word_info.word # info = self.matrix.get_val(word_info.i,word_info.j) # info.word = '' # info.hide_index = len(self.hide_arr) # info.is_lock = False # self.hide_arr.append([word_info.i,word_info.j,word,None]) # tmp_arr = [] # for i in range(self.block_num): # for j in range(self.block_num): # info = self.matrix.get_val(i,j) # if info and info.word: # tmp_arr.append((i,j,info.word)) # while len(self.hide_arr) < self.all_word_num*percent: # n = random.randint(0,len(tmp_arr)-1) # i,j,word = tmp_arr.pop(n) # info = self.matrix.get_val(i,j) # info.word = '' # info.hide_index = len(self.hide_arr) # info.is_lock = False # self.hide_arr.append([i,j,word,None]) 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 # lib = IdiomLib(block_num=10) # lib.load_idiom_from_file() # arr = [] # for i in range(1,101): # lib.init(i) # idiom_arr = [] # for k,v in lib.idiom_dic.items(): # idiom_arr.append(v.to_str()) # hide_arr = [] # for x,y,word,op in lib.hide_arr: # hide_arr.append('%s %s %s'%(x,y,word)) # arr.append({'hide_num':len(hide_arr),'block_num':lib.block_num, 'word_num':lib.all_word_num,'idiom_arr':';'.join(idiom_arr),'hide_arr':';'.join(hide_arr)}) # #arr.sort(cmp=lambda x,y:cmp(x['hide_num']*2+x['word_num'], y['hide_num']*2+y['word_num'])) # arr.sort(key=lambda x:x['hide_num']*2+x['word_num']) # import json # f = open('idiom.json','w+') # f.write(json.dumps(arr)) # f.close()
三、效果展示
1)第一关
2)第五关
3)第十一关
关卡越高难度越高哦~填空词也会越来越高滴
到此这篇关于Python+Pygame实战之诗词填空游戏的实现的文章就介绍到这了,更多相关Python Pygame诗词填空游戏内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!