最近看到很多人玩成语填字游戏,那么先用pygame来做一个吧,花了大半天终于完成了,附下效果图。
主要两个py文件
封装的一些操作类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 = self.cols 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={} # 当前关卡的诗句列表,格式为:{诗句:诗句对象IdiomInfo}
self.all_word_num=0 # 当前关卡的文字数量
self.hide_arr = [] # 当前关卡用于保存中间区域的缺字格子,列表类型:[[x,y,文字,None],……]
# 从文件中加载诗句
def load_idiom_from_file(self, filename='words.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):
'''
检查新新诗句是否有效,无效的场景 1.文字排开后发现超出边界 2.文字排开后发现和已选诗句的文字重叠
:param new_idiom: 诗句
:param new_dire: 诗句展开方向
:param word_info: 当前的文字对象
:return:
'''
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 # 诗句横向纵向交替,因为横向=0,纵向=1,1-横向=纵向,1-纵向=横向
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)
# 对诗句的每个字在文字矩阵里放置
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=[] # 用于保存中间区域的缺字格子,列表类型:[[x,y,文字,None],……]
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(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):
'''
根据指定位置选取下一个默认选中格子
:param x:
:param y:
:return:
'''
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 i100:
percent = 0.7 # 100关以后隐藏文字的比例不再改变
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
# lib = IdiomLib(block_num=10)
# lib.load_idiom_from_file()
# arr = []
# for i in range(1,101):
# lib.init(i)
# idiom_arr = []
# for k,v in lib.idiom_dic.items():
# idiom_arr.append(v.to_str())
# hide_arr = []
# for x,y,word,op in lib.hide_arr:
# hide_arr.append('%s %s %s'%(x,y,word))
# arr.append({'hide_num':len(hide_arr),'block_num':lib.block_num, 'word_num':lib.all_word_num,'idiom_arr':';'.join(idiom_arr),'hide_arr':';'.join(hide_arr)})
# #arr.sort(cmp=lambda x,y:cmp(x['hide_num']*2+x['word_num'], y['hide_num']*2+y['word_num']))
# arr.sort(key=lambda x:x['hide_num']*2+x['word_num'])
# import json
# f = open('idiom.json','w+')
# f.write(json.dumps(arr))
# f.close()
复制代码
主程序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 =0 and xi=0 and yi=0表示是下方点上来的文字
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 = xi, yi
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 # 第n个字的x方向起始像素位置
tmp_y = sy + int(n/block_num)*block_size # 第n个字的y方向起始像素位置
if lib.hide_arr[hi][-1] is None and x >= tmp_x and x = tmp_y and y
关注
打赏
最近更新
- 深拷贝和浅拷贝的区别(重点)
- 【Vue】走进Vue框架世界
- 【云服务器】项目部署—搭建网站—vue电商后台管理系统
- 【React介绍】 一文带你深入React
- 【React】React组件实例的三大属性之state,props,refs(你学废了吗)
- 【脚手架VueCLI】从零开始,创建一个VUE项目
- 【React】深入理解React组件生命周期----图文详解(含代码)
- 【React】DOM的Diffing算法是什么?以及DOM中key的作用----经典面试题
- 【React】1_使用React脚手架创建项目步骤--------详解(含项目结构说明)
- 【React】2_如何使用react脚手架写一个简单的页面?