pygame实现成语填空游戏


Posted in Python onOctober 29, 2019

最近看到很多人玩成语填字游戏,那么先用pygame来做一个吧,花了大半天终于完成了,附下效果图。

pygame实现成语填空游戏

偷了下懒程序没有拆分,所有程序写在一个文件里,主要代码如下:

# -*- coding=utf-8 -*-
import sys
import random
import pygame
from pygame.locals import *
reload(sys)
sys.setdefaultencoding('utf-8')

f = open('words.txt')
all_idiom = f.readlines()
f.close()

word_dic = {}
for idiom in all_idiom:
 idiom = idiom.strip().decode('utf-8')
 for word in idiom:
 if word not in word_dic: 
 word_dic[word] = [idiom]
 else:
  word_dic[word].append(idiom)

word_arr = list(word_dic.keys())

header_height = 30
main_space = 20

block_size = 36
block_num=12
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,50
white = 255,255,255
#textImage = font.render(u'你好', True, white)

class IdiomInfo(object):
 def __init__(self,idiom):
 self.idiom = idiom
 self.dire = 0
 self.word_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

def check_new_idiom(matrix, 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 >= block_num: return None,None

 ty = cy if new_dire == 0 else cy+i
 if ty < 0 or ty >= block_num: return None,None

 if matrix.exist_val_four_around(tx, ty, ignore_set): return None,None

 old_word_info = 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(matrix, word_dic, idiom_dic, idiom_num):
 if idiom_num == 0: return 0
 for idiom,idiom_info in 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 = word_dic[word]
 for new_idiom in idiom_list:
 if new_idiom in idiom_dic: continue
 new_idiom_word_arr,windex = check_new_idiom(matrix, 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:
  matrix.set_val(new_word_info.i, new_word_info.j , new_word_info)
  new_idiom_info.word_arr.append(new_word_info)
  idiom_dic[new_idiom] = new_idiom_info

  return len(new_idiom) -1 + add_idiom_to_matrix(matrix, word_dic, idiom_dic, idiom_num - 1)

 return 0

def get_idiom_matrix(word_arr, word_dic, idiom_num):
 cx = 4
 cy = 4
 matrix = Matrix(block_num, block_num)
 n = random.randint(0,len(word_arr)-1)
 word = word_arr[n]
 idiom = word_dic[word][0]
 idiom_dic={}
 idiom_dic[idiom] = IdiomInfo(idiom)
 wn = len(idiom)
 last_i = -100
 for i in range(len(idiom)):
 word_info = WordInfo(idiom[i],cx-1+i,cy)
 matrix.set_val(cx-1+i,cy,word_info)
 idiom_dic[idiom].word_arr.append(word_info)

 wn += add_idiom_to_matrix(matrix, word_dic, idiom_dic, idiom_num-1)
 return matrix, idiom_dic, wn


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))

def get_hide_arr(matrix, idiom_dic, all_word_num, percent):
 hide_arr = []
 for k,v in idiom_dic.items():
 n = random.randint(0, len(v.word_arr)-1)
 word_info = v.word_arr[n]
 if word_info.hide_index != -1:continue
 word = word_info.word
 info = matrix.get_val(word_info.i,word_info.j)
 info.word = ''
 info.hide_index = len(hide_arr)
 info.is_lock = False
 hide_arr.append([word_info.i,word_info.j,word,None])

 tmp_arr = []
 for i in range(block_num):
 for j in range(block_num):
 info = matrix.get_val(i,j)
 if info and info.word:
 tmp_arr.append((i,j,info.word))

 while len(hide_arr) < all_word_num*percent:
 n = random.randint(0,len(tmp_arr)-1)
 i,j,word = tmp_arr.pop(n)
 info = matrix.get_val(i,j)
 info.word = ''
 info.hide_index = len(hide_arr)
 info.is_lock = False
 hide_arr.append([i,j,word,None])

 return hide_arr 

def get_next_select(matrix, x, y):
 arr = []
 for i in range(block_num):
 for j in range(block_num):
 info = 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]))
 return (arr[0][0],arr[0][1])

def check_idiom():
 for idiom, idiom_info in 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 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(new_stage):
 idiom_num = (new_stage/5)+3
 if new_stage>100:
 percent = 0.7
 else:
 percent = 0.2+(new_stage*1.0/100)*(0.7-0.2)
 matrix,idiom_dic,all_word_num = get_idiom_matrix(word_arr, word_dic, idiom_num)
 hide_arr = get_hide_arr(matrix, idiom_dic, all_word_num, percent)
 select_rect = hide_arr[0][0],hide_arr[0][1]
 stage_textImage = pygame.font.Font(u'syht.otf', 30).render(u'第%s关'%new_stage, True, dray_gray)
 return matrix,idiom_dic,all_word_num,hide_arr,select_rect,stage_textImage

matrix,idiom_dic,all_word_num,hide_arr,select_rect,stage_textImage = init(stage)

stage_font_width, stage_font_height = stage_textImage.get_size()
stage_x = (width - stage_font_width)/2
stage_y = (header_height - stage_font_height)/2+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 = matrix.get_val(i, j)
  if info and info.state != 1 and info.hide_index >= 0:
  if info.op_hide_index>=0:
   hide_arr[info.op_hide_index][-1] = None
   info.word = ''
   info.op_hide_index=-1
   check_idiom()
  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(hide_arr)):
  tmp_x = sx + (n%block_num)*block_size
  tmp_y = sy + (n/block_num)*block_size
  if 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 = matrix.get_val(select_rect[0],select_rect[1])
  info.word = hide_arr[hi][2]
  info.op_hide_index = hi
  info.state = 0
  hide_arr[hi][-1] = select_rect
  new_select_rect = get_next_select(matrix, select_rect[0],select_rect[1])
  select_rect = new_select_rect
  flag = check_idiom()
  if flag:
  stage += 1
  matrix,idiom_dic,all_word_num,hide_arr,select_rect,stage_textImage = init(stage)
  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 = 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.state == 2:
  textImage = font.render(info.word, True, (255,0,0))
 elif info.is_lock == 1:
  textImage = font.render(info.word, True, (150,150,150))
 else:
  textImage = font.render(info.word, True, dray_gray)

 tw, th = textImage.get_size()
 dx=(block_size-bspace*2-tw)/2
 dy=(block_size-bspace*2-th)/2
 panel.blit(textImage, (bx+dx,by+dy))
 if (i,j) == 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 hide_arr:
 screen.blit(block_bg_image, (sx + (n%block_num)*block_size,sy + (n/block_num)*block_size))
 if op is None:
 textImage = font.render(word, True, dray_gray)
 tw, th = textImage.get_size()
 dx=(block_size-bspace*2-tw)/2
 dy=(block_size-bspace*2-th)/2
 screen.blit(textImage, (dx+sx+ (n%block_num)*block_size,dy+sy+ (n/block_num)*block_size))
 n+=1

 pygame.display.update()

代码就这么多了,不过这边用到几个额外的依赖:
bg.jpeg 用于做整个界面的背景
bg2.jpeg 用于做上半部分的背景
tzg.jpg 每个文字的格子的背景
words.txt 一个成语的列表文件(每行一条成语),如果换成诗词或者歇后语什么的也是没有问题的
syht.otf 一个字体库,用于正常显示中文

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

block_size = 32
block_num=12

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

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

pygame实现成语填空游戏

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

pygame实现成语填空游戏

完整的资源已经上传:guess_idiom

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Django中处理出错页面的方法
Jul 15 Python
Django小白教程之Django用户注册与登录
Apr 22 Python
python实现批量监控网站
Sep 09 Python
python表格存取的方法
Mar 07 Python
十分钟利用Python制作属于你自己的个性logo
May 07 Python
django利用request id便于定位及给日志加上request_id
Aug 26 Python
快速排序的四种python实现(推荐)
Apr 03 Python
python实现远程控制电脑
May 23 Python
Python 列表去重去除空字符的例子
Jul 20 Python
python实现大量图片重命名
Mar 23 Python
Python 线性回归分析以及评价指标详解
Apr 02 Python
使用Python Tkinter实现剪刀石头布小游戏功能
Oct 23 Python
Python多线程及其基本使用方法实例分析
Oct 29 #Python
基于python的itchat库实现微信聊天机器人(推荐)
Oct 29 #Python
pygame实现非图片按钮效果
Oct 29 #Python
线程安全及Python中的GIL原理分析
Oct 29 #Python
pygame实现贪吃蛇游戏(下)
Oct 29 #Python
python TK库简单应用(实时显示子进程输出)
Oct 29 #Python
pygame实现贪吃蛇游戏(上)
Oct 29 #Python
You might like
用 Composer构建自己的 PHP 框架之使用 ORM
2014/10/30 PHP
asp 的 分词实现代码
2007/05/24 Javascript
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
javascript自启动函数的问题探讨
2013/10/05 Javascript
javascipt匹配单行和多行注释的正则表达式
2013/11/20 Javascript
JavaScript页面模板库handlebars的简单用法
2015/03/02 Javascript
jQuery简单tab切换效果实现方法
2015/04/08 Javascript
浅谈json取值(对象和数组)
2016/06/24 Javascript
JavaScript之Vue.js【入门基础】
2016/12/06 Javascript
JS实现旋转木马式图片轮播效果
2017/01/18 Javascript
js评分组件使用详解
2017/06/06 Javascript
基于JS递归函数细化认识及实用实例(推荐)
2017/08/07 Javascript
JavaScript实现的原生态Tab标签页功能【兼容IE6】
2017/09/18 Javascript
在vue项目中安装使用Mint-UI的方法
2017/12/27 Javascript
Node批量爬取头条视频并保存方法
2018/09/20 Javascript
Node 代理访问的实现
2019/09/19 Javascript
小程序实现多个选项卡切换
2020/06/19 Javascript
浅谈vue获得后台数据无法显示到table上面的坑
2020/08/13 Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
2020/11/16 Javascript
[03:58]兄弟们,回来开黑了!DOTA2昔日战友招募宣传视频
2016/07/17 DOTA
Python读写txt文本文件的操作方法全解析
2016/06/26 Python
python导入不同目录下的自定义模块过程解析
2019/11/18 Python
关于Tensorflow 模型持久化详解
2020/02/12 Python
Python基于smtplib协议实现发送邮件
2020/06/03 Python
Python3爬虫关于识别检验滑动验证码的实例
2020/07/30 Python
CSS3的RGBA中关于整数和百分比值的转换
2015/08/04 HTML / CSS
H5 meta小结(前端必看篇)
2016/08/24 HTML / CSS
英国在线药房:Chemist.co.uk
2019/03/26 全球购物
C有"按引用传递"吗
2016/09/06 面试题
超市5.1促销活动
2014/01/15 职场文书
2014年党建工作汇报材料
2014/10/27 职场文书
初婚初育证明范本
2014/11/24 职场文书
小学感恩节活动总结
2015/03/24 职场文书
2015年学生资助工作总结
2015/05/25 职场文书
Java 超详细讲解hashCode方法
2022/04/07 Java/Android
Nginx 常用配置
2022/05/15 Servers