使用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 相关文章推荐
跟老齐学Python之集合的关系
Sep 24 Python
python登录pop3邮件服务器接收邮件的方法
Apr 30 Python
python装饰器实例大详解
Oct 25 Python
Python3.5.3下配置opencv3.2.0的操作方法
Apr 02 Python
浅谈利用numpy对矩阵进行归一化处理的方法
Jul 11 Python
python使用scrapy发送post请求的坑
Sep 04 Python
python自带tkinter库实现棋盘覆盖图形界面
Jul 17 Python
django 连接数据库 sqlite的例子
Aug 14 Python
python matplotlib饼状图参数及用法解析
Nov 04 Python
python路径的写法及目录的获取方式
Dec 26 Python
使用matplotlib的pyplot模块绘图的实现示例
Jul 12 Python
用Python实现定时备份Mongodb数据并上传到FTP服务器
Jan 27 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去除换行(回车换行)的三种方法
2014/03/26 PHP
PHP高手需要要掌握的知识点
2014/08/21 PHP
PHP使用数组依次替换字符串中匹配项
2016/01/08 PHP
PHP全功能无变形图片裁剪操作类与用法示例
2017/01/10 PHP
CakePHP框架Session设置方法分析
2017/02/23 PHP
php5.3/5.4/5.5/5.6/7常见新增特性汇总整理
2020/02/27 PHP
JQUBAR1.1 jQuery 柱状图插件发布
2010/11/28 Javascript
使用jquery+CSS实现控制打印样式
2014/12/31 Javascript
vue-cli之router基本使用方法详解
2017/10/17 Javascript
在vue中使用v-bind:class的选项卡方法
2018/09/27 Javascript
Python中函数的参数定义和可变参数用法实例分析
2015/06/04 Python
Python实现的密码强度检测器示例
2017/08/23 Python
Python实现的计算马氏距离算法示例
2018/04/03 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
Python 新建文件夹与复制文件夹内所有内容的方法
2018/10/27 Python
Python3内置模块之base64编解码方法详解
2019/07/13 Python
python 字符串追加实例
2019/07/20 Python
Python读取分割压缩TXT文本文件实例
2020/02/14 Python
pytorch 实现在一个优化器中设置多个网络参数的例子
2020/02/20 Python
python实现人工蜂群算法
2020/09/18 Python
html5 更新图片颜色示例代码
2014/07/29 HTML / CSS
Timberland美国官网:全球领先的户外品牌
2016/08/15 全球购物
女孩每月服装订阅盒:kidpik
2019/04/17 全球购物
德国最大的服装、鞋子和配件在线商店之一:Outfits24
2019/07/23 全球购物
澳大利亚买卖正宗二手奢侈品交易平台:Luxe.It.Fwd
2019/10/16 全球购物
临床医学专业学生的自我评价分享
2013/11/21 职场文书
事业单位鉴定材料
2014/05/25 职场文书
领导党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
2014年政风行风自查自纠报告
2014/10/21 职场文书
2015年科室工作总结
2015/04/10 职场文书
少年派的奇幻漂流观后感
2015/06/08 职场文书
十八大观后感
2015/06/12 职场文书
粗暴解决CUDA out of memory的问题
2021/05/22 Python
pytorch 两个GPU同时训练的解决方案
2021/06/01 Python
python 中yaml文件用法大全
2021/07/04 Python
Java版 单机五子棋
2022/05/04 Java/Android