使用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 ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
Jun 10 Python
Python简单实现TCP包发送十六进制数据的方法
Apr 16 Python
Python 描述符(Descriptor)入门
Nov 20 Python
python 爬虫出现403禁止访问错误详解
Mar 11 Python
Python用61行代码实现图片像素化的示例代码
Dec 10 Python
python:接口间数据传递与调用方法
Dec 17 Python
把django中admin后台界面的英文修改为中文显示的方法
Jul 26 Python
Python中turtle库的使用实例
Sep 09 Python
Pandas聚合运算和分组运算的实现示例
Oct 17 Python
python3光学字符识别模块tesserocr与pytesseract的使用详解
Feb 26 Python
使用PyQt5实现图片查看器的示例代码
Apr 21 Python
pycharm 对代码做静态检查操作
Jun 09 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
详解WordPress中调用评论模板和循环输出评论的PHP函数
2016/01/05 PHP
WordPress后台中实现图片上传功能的实例讲解
2016/01/11 PHP
laravel 解决Eloquent ORM的save方法无法插入数据的问题
2019/10/21 PHP
javascript知识点收藏
2007/02/22 Javascript
firefox浏览器不支持innerText的解决方法
2013/08/07 Javascript
NodeJS与Mysql的交互示例代码
2013/08/18 NodeJs
Jquery取得iframe下内容的方法
2013/11/18 Javascript
js获取对象为null的解决方法
2013/11/21 Javascript
jQuery实现自定义下拉列表
2015/01/05 Javascript
js中hash和ico的关联分析
2015/02/05 Javascript
js实现TAB切换对应不同颜色的代码
2015/08/31 Javascript
基于Flowplayer打造一款免费的WEB视频播放器附源码
2015/09/06 Javascript
Bootstrap精简教程
2015/11/27 Javascript
jQuery插件实现带圆点的焦点图片轮播切换
2016/01/18 Javascript
微信小程序 获取当前地理位置和经纬度实例代码
2016/12/05 Javascript
angularjs中$http异步上传Excel文件方法
2018/02/23 Javascript
为什么使用koa2搭建微信第三方公众平台的原因
2018/05/16 Javascript
webpack css加载和图片加载的方法示例
2018/09/11 Javascript
可能被忽略的一些JavaScript数组方法细节
2019/02/28 Javascript
vue实现给div绑定keyup的enter事件
2020/07/31 Javascript
[34:39]Secret vs VG 2018国际邀请赛淘汰赛BO3 第二场 8.23
2018/08/24 DOTA
[55:56]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.22
2019/09/05 DOTA
python的keyword模块用法实例分析
2015/06/30 Python
Python中list初始化方法示例
2016/09/18 Python
Python字典简介以及用法详解
2016/11/15 Python
python实时分析日志的一个小脚本分享
2017/05/07 Python
基于python中__add__函数的用法
2019/11/25 Python
用Python爬取LOL所有的英雄信息以及英雄皮肤的示例代码
2020/07/13 Python
关于PyCharm安装后修改路径名称使其可重新打开的问题
2020/10/20 Python
深入研究HTML5实现图片压缩上传功能
2016/03/25 HTML / CSS
小学生感恩演讲稿
2014/04/25 职场文书
故宫的导游词
2015/01/31 职场文书
2015年党员创先争优公开承诺书
2015/04/27 职场文书
在校生证明
2015/06/17 职场文书
Python离线安装openpyxl模块的步骤
2021/03/30 Python
「月刊Action」2022年5月号封面公开
2022/03/21 日漫