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 相关文章推荐
python的构建工具setup.py的方法使用示例
Oct 23 Python
使用Python制作自动推送微信消息提醒的备忘录功能
Sep 06 Python
python hook监听事件详解
Oct 25 Python
Python使用Selenium爬取淘宝异步加载的数据方法
Dec 17 Python
Python基础学习之函数方法实例详解
Jun 18 Python
Python稀疏矩阵及参数保存代码实现
Apr 18 Python
Python OrderedDict字典排序方法详解
May 21 Python
Django实现微信小程序支付的示例代码
Sep 03 Python
Python ellipsis 的用法详解
Nov 20 Python
python 中[0]*2与0*2的区别说明
May 10 Python
Python实现查询剪贴板自动匹配信息的思路详解
Jul 09 Python
python中pd.cut()与pd.qcut()的对比及示例
Jun 16 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
PHP+javascript液晶时钟
2006/10/09 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十)
2014/06/24 PHP
JS是否可以跨文件同时控制多个iframe页面的应用技巧
2007/12/16 Javascript
jQuery+jqmodal弹出窗口实现代码分明
2010/06/14 Javascript
JS正则表达式验证数字代码
2014/01/28 Javascript
js事件绑定快捷键以ctrl+k为例
2014/09/30 Javascript
jQuery异步获取json数据方法汇总
2014/12/22 Javascript
AngularJS包括详解及示例代码
2016/08/17 Javascript
jQuery 的 ready()的纯js替代方法
2016/11/20 Javascript
微信小程序 wx:for的使用实例详解
2017/04/27 Javascript
jQuery实现jQuery-form.js实现异步上传文件
2017/04/28 jQuery
jQuery动画_动力节点节点Java学院整理
2017/07/04 jQuery
vue.js整合vux中的上拉加载下拉刷新实例教程
2018/01/09 Javascript
node.js通过axios实现网络请求的方法
2018/03/05 Javascript
原生js实现拖拽功能基本思路详解
2018/04/18 Javascript
微信小程序实现发送模板消息功能示例【通过openid推送消息给用户】
2019/05/05 Javascript
浅谈vue-router路由切换 组件重用挖下的坑
2019/11/01 Javascript
用Python编写一个简单的俄罗斯方块游戏的教程
2015/04/03 Python
Python操作列表之List.insert()方法的使用
2015/05/20 Python
python3+PyQt5+Qt Designer实现扩展对话框
2018/04/20 Python
Python 循环语句之 while,for语句详解
2018/04/23 Python
Python使用pandas和xlsxwriter读写xlsx文件的方法示例
2019/04/09 Python
Python实现微信消息防撤回功能的实例代码
2019/04/29 Python
使用PyTorch训练一个图像分类器实例
2020/01/08 Python
深入了解Python 变量作用域
2020/07/24 Python
HTML5新特性 多线程(Worker SharedWorker)
2017/04/24 HTML / CSS
应用心理学个人的求职信
2013/12/08 职场文书
书法比赛获奖感言
2014/02/10 职场文书
纪检干部先进事迹材料
2014/08/23 职场文书
党的群众路线教育实践活动学习笔记
2014/11/05 职场文书
2014年后勤工作总结范文
2014/12/16 职场文书
2015年农村党员公开承诺事项
2015/04/28 职场文书
2015年行风建设工作总结
2015/05/15 职场文书
2015年度绩效考核工作总结
2015/05/27 职场文书
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python
SQL Server2019数据库备份与还原脚本,数据库可批量备份
2021/11/20 SQL Server