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关闭windows进程的方法
Apr 18 Python
python开发之for循环操作实例详解
Nov 12 Python
Python3.x对JSON的一些操作示例
Sep 01 Python
Python如何快速上手? 快速掌握一门新语言的方法
Nov 14 Python
在python中利用opencv简单做图片比对的方法
Jan 24 Python
Python3使用TCP编写一个简易的文件下载器功能
May 08 Python
Python 利用高德地图api实现经纬度与地址的批量转换
Aug 14 Python
python如何使用Redis构建分布式锁
Jan 16 Python
Python如何将图像音视频等资源文件隐藏在代码中(小技巧)
Feb 16 Python
python中添加模块导入路径的方法
Feb 03 Python
python基础之文件处理知识总结
May 23 Python
Python实现打乒乓小游戏
Sep 25 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
索尼SONY SRF-S83/84电路分析和打磨
2021/03/02 无线电
PHP中for循环语句的几种变型
2007/03/16 PHP
php中$_SERVER[PHP_SELF] 和 $_SERVER[SCRIPT_NAME]之间的区别
2009/09/05 PHP
curl不使用文件存取cookie php使用curl获取cookie示例
2014/01/26 PHP
CI(CodeIgniter)框架中的增删改查操作
2014/06/10 PHP
PHP与MYSQL中UTF8 中文排序示例代码
2014/10/23 PHP
使用composer 安装 laravel框架的方法图文详解
2019/08/02 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
关于JS管理作用域的问题
2013/04/10 Javascript
node.js中的fs.realpath方法使用说明
2014/12/16 Javascript
Sea.JS知识总结
2016/05/05 Javascript
js判断请求的url是否可访问,支持跨域判断的实现方法
2016/09/17 Javascript
详解Vue.js分发之作用域槽
2017/06/13 Javascript
javascript 初学教程及五子棋小程序的简单实现
2017/07/04 Javascript
Nodejs 复制文件/文件夹的方法
2017/08/24 NodeJs
微信小程序实现点击文字页面跳转功能【附源码下载】
2017/12/12 Javascript
Angular4学习之Angular CLI的安装与使用教程
2018/01/04 Javascript
基于js Canvas实现二次贝塞尔曲线
2018/12/25 Javascript
JavaScript碎片—函数闭包(模拟面向对象)
2019/03/13 Javascript
Electron + vue 打包桌面操作流程详解
2019/06/24 Javascript
Python使用urllib2模块实现断点续传下载的方法
2015/06/17 Python
批量获取及验证HTTP代理的Python脚本
2017/04/23 Python
Python实现好友全头像的拼接实例(推荐)
2017/06/24 Python
Python使用matplotlib简单绘图示例
2018/02/01 Python
numpy 进行数组拼接,分别在行和列上合并的实例
2018/05/08 Python
python的中异常处理机制
2018/08/30 Python
DataFrame:通过SparkSql将scala类转为DataFrame的方法
2019/01/29 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
Python 合并拼接字符串的方法
2020/07/28 Python
Stefania Mode美国:奢华设计师和时尚服装
2018/01/07 全球购物
英国一家集合了众多有才华设计师品牌的奢侈店:Wolf & Badger
2018/04/18 全球购物
纽约州一群才华横溢的金匠制作而成:Hearth Jewelry
2019/03/22 全球购物
中学家长会邀请函
2014/01/17 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
多人股份制合作协议书
2016/03/19 职场文书
宝塔更新Python及Flask项目的部署
2022/04/11 Python