使用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编程中基本的数学计算使用
Feb 04 Python
Python爬虫爬验证码实现功能详解
Apr 14 Python
Python实现批量更换指定目录下文件扩展名的方法
Sep 19 Python
Python之os操作方法(详解)
Jun 15 Python
Python3实现转换Image图片格式
Jun 21 Python
Python Flask前后端Ajax交互的方法示例
Jul 31 Python
Python对CSV、Excel、txt、dat文件的处理
Sep 18 Python
Python爬虫实现验证码登录代码实例
May 10 Python
python Tkinter的图片刷新实例
Jun 14 Python
自适应线性神经网络Adaline的python实现详解
Sep 30 Python
python命令 -u参数用法解析
Oct 24 Python
Python+PyQt5+MySQL实现天气管理系统
Jun 16 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令牌 Token改进版
2008/07/18 PHP
apache mysql php 源码编译使用方法
2012/05/03 PHP
PHP中的str_repeat函数在JavaScript中的实现
2013/09/16 PHP
php后门URL的防范
2013/11/12 PHP
PHP输出图像imagegif、imagejpeg与imagepng函数用法分析
2016/11/14 PHP
Jquery Validation插件防止重复提交表单的解决方法
2010/03/05 Javascript
目前流行的JavaScript库的介绍及对比
2013/09/29 Javascript
ParseInt函数参数设置介绍
2014/01/02 Javascript
JS实现点击按钮自动增加一个单元格的方法
2015/03/09 Javascript
BootStrap创建响应式导航条实例代码
2016/05/31 Javascript
JS函数修改html的元素内容,及修改属性内容的方法
2016/10/28 Javascript
input输入密码变黑点密文的实现方法
2017/01/09 Javascript
javaScript基础详解
2017/01/19 Javascript
微信小程序 弹框和模态框实现代码
2017/03/10 Javascript
js实现自定义进度条效果
2017/03/15 Javascript
jQuery插件FusionCharts绘制的2D帕累托图效果示例【附demo源码】
2017/03/28 jQuery
详解node.js搭建代理服务器请求数据
2017/04/08 Javascript
详解JavaScript 中 if / if...else...替换方式
2018/07/15 Javascript
python实现文件分组复制到不同目录的例子
2014/06/04 Python
浅谈Python2获取中文文件名的编码问题
2018/01/09 Python
python flask实现分页的示例代码
2018/08/02 Python
python pickle存储、读取大数据量列表、字典数据的方法
2019/07/07 Python
TensorFlow实现保存训练模型为pd文件并恢复
2020/02/06 Python
Python collections.defaultdict模块用法详解
2020/06/18 Python
HTML5页面音视频在微信和app下自动播放的实现方法
2016/10/20 HTML / CSS
canvas线条的属性详解
2018/03/27 HTML / CSS
销售行业个人求职自荐信
2013/09/25 职场文书
门卫班长岗位职责
2013/12/15 职场文书
工程管理英文求职信
2014/03/18 职场文书
九一八事变纪念日演讲稿
2014/09/14 职场文书
党员自我评议个人对照检查材料
2014/09/16 职场文书
新员工入职欢迎词
2015/01/23 职场文书
信仰观后感
2015/06/03 职场文书
领导欢送会主持词
2015/07/06 职场文书
2019年大学生职业生涯规划书最新范文
2019/03/25 职场文书
redis调用二维码时的不断刷新排查分析
2022/04/01 Redis