使用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 文件操作api(文件操作函数)
Aug 28 Python
python探索之BaseHTTPServer-实现Web服务器介绍
Oct 28 Python
[原创]pip和pygal的安装实例教程
Dec 07 Python
使用python编写udp协议的ping程序方法
Apr 22 Python
python中for用来遍历range函数的方法
Jun 08 Python
使用Python对微信好友进行数据分析
Jun 27 Python
Django 反向生成url实例详解
Jul 30 Python
Python对称的二叉树多种思路实现方法
Feb 28 Python
python+selenium+chromedriver实现爬虫示例代码
Apr 10 Python
Python读取excel文件中带公式的值的实现
Apr 17 Python
Pandas实现一列数据分隔为两列
May 18 Python
如何基于Python和Flask编写Prometheus监控
Nov 25 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中的三元运算符使用说明
2011/07/03 PHP
PHP+Apache实现二级域名之间共享cookie的方法
2019/07/24 PHP
php设计模式之正面模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
jquery 仿QQ校友的DIV模拟窗口效果源码
2010/03/24 Javascript
JS+CSS实现的拖动分页效果实例
2015/05/11 Javascript
JavaScript实现广告的关闭与显示效果实例
2015/07/02 Javascript
javascript实现查找数组中最大值方法汇总
2016/02/13 Javascript
jquery操作select取值赋值与设置选中实例
2017/02/28 Javascript
NodeJS链接MySql数据库的操作方法
2017/06/27 NodeJs
超级简易的JS计算器实例讲解(实现加减乘除)
2017/08/08 Javascript
深入理解JavaScript和TypeScript中的class
2018/04/22 Javascript
详解Vue项目部署遇到的问题及解决方案
2019/01/11 Javascript
js实现双人五子棋小游戏
2020/05/28 Javascript
浅谈vue 组件中的setInterval方法和window的不同
2020/07/30 Javascript
小程序中手机号识别的示例
2020/12/14 Javascript
详解Python中的type()方法的使用
2015/05/21 Python
浅谈pyhton学习中出现的各种问题(新手必看)
2017/05/17 Python
Python实现的文本对比报告生成工具示例
2018/05/22 Python
Python的UTC时间转换讲解
2019/02/26 Python
Pycharm 安装 idea VIM插件的图文教程详解
2020/02/21 Python
Python生成器generator原理及用法解析
2020/07/20 Python
Django用内置方法实现简单搜索功能的方法
2020/12/18 Python
HTML5之SVG 2D入门11—用户交互性(动画)介绍及应用
2013/01/30 HTML / CSS
HTML5 canvas基本绘图之绘制曲线
2016/06/27 HTML / CSS
美国体育用品商店:Rally House(NCAA、NFL、MLB、NBA、NHL和MLS)
2018/01/03 全球购物
可持续木材、生态和铝制太阳镜:Proof Eyewear
2019/07/24 全球购物
毕业生简单求职信
2013/11/19 职场文书
好矿嫂事迹材料
2014/01/21 职场文书
旅游与环境专业求职信
2014/06/05 职场文书
委托书如何写
2014/08/30 职场文书
湖南省召开党的群众路线教育实践活动总结大会报告
2014/10/21 职场文书
2015年车间安全管理工作总结
2015/05/13 职场文书
申论不会写怎么办?教您掌握这6点思维和原则
2019/07/17 职场文书
世界文化遗产导游词
2019/08/07 职场文书
Redis实现订单自动过期功能的示例代码
2021/05/08 Redis
sql server删除前1000行数据的方法实例
2021/08/30 SQL Server