使用pygame写一个古诗词填空通关游戏


Posted in Python onDecember 03, 2019

之前写的诗词填空的游戏支持python2,现在对程序进行了修改,兼容支持python2和python3,附下效果图。

使用pygame写一个古诗词填空通关游戏

下面是两个主程序

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'诗词填空')
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()

代码就这么多了,不过这边用到几个额外的依赖:

bg.jpeg 用于做整个界面的背景

bg2.jpeg 用于做上半部分的背景

tzg.jpg 每个文字的格子的背景

words.txt 一个成语的列表文件(每行一条成语),如果换成诗词或者歇后语什么的也是没有问题的

syht.otf 一个字体库,用于正常显示中文

运行python main.py即可开始游戏

如果嫌格子太多或者太小,可以调一下这两个参数

block_size = 32
block_num=12

block_size 表示格子的大小

block_num 上半部分的区域横竖最多显示多少个格子

block_size = 26,block_num=18的效果图:

使用pygame写一个古诗词填空通关游戏

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

使用pygame写一个古诗词填空通关游戏

试试你的诗词水平,看能冲到第几关吧!

完整的资源已经上传本站:

也可以直接从github下载

https://github.com/zhangenter/guess_idiom

总结

以上所述是小编给大家介绍的使用pygame写一个古诗词填空通关游戏,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Python 相关文章推荐
pyqt4教程之widget使用示例分享
Mar 07 Python
python执行get提交的方法
Apr 29 Python
Python中的列表生成式与生成器学习教程
Mar 13 Python
Python常用算法学习基础教程
Apr 13 Python
python学习教程之Numpy和Pandas的使用
Sep 11 Python
python生成器,可迭代对象,迭代器区别和联系
Feb 04 Python
python实现画一颗树和一片森林
Jun 25 Python
pandas 按照特定顺序输出的实现代码
Jul 10 Python
pyqt5的QComboBox 使用模板的具体方法
Sep 06 Python
python binascii 进制转换实例
Jun 12 Python
Python any()函数的使用方法
Oct 28 Python
Python json读写方式和字典相互转化
Apr 18 Python
使用python和pygame制作挡板弹球游戏
Dec 03 #Python
win10系统Anaconda和Pycharm的Tensorflow2.0之CPU和GPU版本安装教程
Dec 03 #Python
在Python中使用MongoEngine操作数据库教程实例
Dec 03 #Python
matplotlib绘制多个子图(subplot)的方法
Dec 03 #Python
python单向循环链表原理与实现方法示例
Dec 03 #Python
使用 Python 清理收藏夹里已失效的网站
Dec 03 #Python
Python常用模块os.path之文件及路径操作方法
Dec 03 #Python
You might like
一些PHP写的小东西
2006/12/06 PHP
php array_walk_recursive 使用自定的函数处理数组中的每一个元素
2016/11/16 PHP
PHP实现SMTP邮件的发送实例
2018/09/27 PHP
php+ajax 文件上传代码实例
2019/03/18 PHP
使用Mootools动态添加Css样式表代码,兼容各浏览器
2011/12/12 Javascript
JS比较2个日期间隔的示例代码
2014/04/15 Javascript
基于jQuery实现Div窗口震动特效代码-代码简单
2015/08/28 Javascript
谷歌showModalDialog()方法不兼容出现对话窗口的解决办法
2016/02/15 Javascript
限制复选框最多选择项的实现代码
2016/05/30 Javascript
完美解决IE9浏览器出现的对象未定义问题
2016/09/29 Javascript
浅谈js之字面量、对象字面量的访问、关键字in的用法
2016/11/20 Javascript
详解nodejs 文本操作模块-fs模块(五)
2016/12/23 NodeJs
微信小程序 this和that详解及简单实例
2017/02/13 Javascript
JS原型与原型链的深入理解
2017/02/15 Javascript
利用JQuery操作iframe父页面、子页面的元素和方法汇总
2017/09/10 jQuery
详解React中setState回调函数
2018/06/14 Javascript
BootStrap modal实现拖拽功能
2018/12/01 Javascript
js序列化和反序列化的使用讲解
2019/01/19 Javascript
VUE.CLI4.0配置多页面入口的实现
2019/11/25 Javascript
原生javascript实现类似vue的数据绑定功能示例【观察者模式】
2020/02/24 Javascript
[53:49]LGD vs Fnatic 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
Python迭代器和生成器介绍
2015/03/06 Python
python提取字典key列表的方法
2015/07/11 Python
Python数据类型学习笔记
2016/01/13 Python
pygame游戏之旅 调用按钮实现游戏开始功能
2018/11/21 Python
Python 使用 prettytable 库打印表格美化输出功能
2019/12/26 Python
详解python itertools功能
2020/02/07 Python
python程序实现BTC(比特币)挖矿的完整代码
2021/01/20 Python
CSS中垂直居中的简单实现方法
2015/07/06 HTML / CSS
玩具反斗城天猫官方旗舰店:享誉全球的玩具店
2017/10/10 全球购物
耐克中国官方商城:Nike中国
2018/10/18 全球购物
Kiehl’s科颜氏西班牙官方网站:源自美国的植物护肤品牌
2020/02/22 全球购物
酒店管理专业学生求职信
2013/09/27 职场文书
应届护士求职信范文
2014/01/26 职场文书
关于运动会的稿件
2014/02/02 职场文书
2014年店长工作总结
2014/11/17 职场文书