【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目

2020-04-16 - 成语填字

开心!先来个成果图记录一下,之前一直觉得很神奇,自动生成题目的算法是怎样的,好奇着好奇着就去试试,其实好像也不涉及到啥算法,摸索着总算弄出来啦,大神莫笑小白之欢喜。

代码还没整理好,如果有人感兴趣的话,我再把源码贴出来分享分享~

【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目
【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目

=============================================== 2020.04.07补一下源码

不常上简书没留意到留言,嘻嘻嘻,当时偷懒没有上传。我是写java的,本身不是写python的,所以代码里面可能有些不太优雅的地方,目标只是实现功能,见谅哈。另外有些代码可能是过程中为了调试写的,也懒得删了,记录了最原始的创作过程。

【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目
【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目

(对了,我实现的这个,也是有参考别人的文章的,但是不记得是哪一篇了,看了好多篇,如果觉得有相同的地方,抱歉啊,欢迎原文作者们联系,一定把您大名署上) 可以调整目标成语数量target参数,改成你想要一次输出的成语数量。

【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目
【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目

当然,你也可以优化将它变成传入参数,那会更加优雅一些,交给你自己啦。 在terminal里面运行时,要注意窗口大小,尤其是x轴方向的长度,要符合代码里的设定,不然的话出来的是对不齐的,正常应该是这样:

如果大小不注意错位的话就会这样了:

【成语填字游戏题目图片】python实现成语填字游戏 自动生成题目

import randomimport pymysqlfrom enum import Enum#conn = pymysql.connect(host="localhost", user="root", password="123456", database="idiom", charset="utf8")cursor = conn.

cursor()class Coordinate(Enum): X = "x" Y = "y"# 选中的成语列表,[‘一心一意’,’掩耳盗铃’]idioms = []# 选中的成员的拆分列表,含坐标,[[0,0,’一’],[1,0,’心’],[2,0,’一’],[3,0,’意’]]splitIdioms = []# 关键字拆分列表,含坐标,[[0,0,’一’],[1,0,’意’]]splitKeys = []# 已使用过的坐标usedSeats = []# 目标成语数量(!

!!!这里可以修改参数!!!!)target = 5# 已经用过的坐标(后续避免重复)def add_used_seats(idiom_split): for en in idiom_split: usedSeats.

append((en[0], en[1]))# 检查坐标是否已被使用def check_not_in_used_seats(idiom_split, exclude_index): for i in range(len(idiom_split)): if usedSeats.

__contains__((idiom_split[0], idiom_split[1])): if i !

= exclude_index: return False return True# 获取一个切分好的成语def get_one(x, y, keyword): idiom = get_random_idiom(keyword) idioms.

append(idiom) # 第单数个成语:横放; 第双数个成语:竖放 if len(idioms) % 2 == 0: direction = Coordinate.

Y else: direction = Coordinate.X # 找出这个成语中和上个成语的重用字的索引 last_used_index = idiom.

find(keyword) if len(idioms) > 1 else -1 # print("last_used_index is: %s" % last_used_index) # 切分,添加坐标 idiom_split = split_idiom(x, y, last_used_index, idiom, direction) # 检查坐标是否已被使用 if not check_not_in_used_seats(idiom_split, last_used_index): idioms.

pop(-1) return False, None return True, idiom_split# 将使用的成语加入到列表中def add_one(idiom_split): splitIdioms.

extend(idiom_split) add_used_seats(idiom_split)def main(): x, y, keyword, last_used_index = 0, 0, '', -1 for i in range(target): # 获取一个切分好的成语 ret, idiom_split = get_one(x, y, keyword) # 如果不成功,重新获取,直到成功为止 while not ret: ret, idiom_split = get_one(x, y, keyword) # print("succeed to get one idiom: %s" % idiom_split) # 将获取到的成语加入到列表中 add_one(idiom_split) # 确定下个成语的关键字 last_used_index = -1 if len(idioms) <= 1 else idioms[-1].

find(splitKeys[-1][2]) key_index = random.

randint(0, len(idioms[-1]) - 1) while last_used_index == key_index: key_index = random.

randint(0, len(idioms[-1]) - 1) splitKeys.append(idiom_split[key_index]) # print("next keyword is: %s" % idiom_split[key_index]) # 准备下一个成语的基础 x = splitKeys[-1][0] y = splitKeys[-1][1] keyword = splitKeys[-1][2] # 调整坐标 # print("usedIdioms: %s" % idioms) # print("beforeList: %s" % splitIdioms) fix_border() # print("finalList: %s" % splitIdioms) printOnScreen(splitIdioms)def get_random_idiom(keyword): if len(keyword) > 0: keyword = '%' keyword '%' sql = "SELECT chengyu FROM XUEBIJUN AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM XUEBIJUN)) AS id) AS t2 WHERE not locate(',',t1.

chengyu) %s and t1.id >= t2.id ORDER BY t1.id ASC LIMIT 1" % "and chengyu like '%s'" % keyword else: sql = "SELECT chengyu FROM XUEBIJUN AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM XUEBIJUN)) AS id) AS t2 WHERE not locate(',',t1.

chengyu) and t1.id >= t2.id ORDER BY t1.id ASC LIMIT 1" cursor.

execute(sql) ret = cursor.fetchone() while ret is None or idioms.__contains__(ret[0]): ret = get_random_idiom(keyword) # print("random idiom: %s" % ret) return ret[0]# 切分,添加坐标def split_idiom(x, y, key_index, idiom, direction): ret = [] key_index = key_index if key_index > 0 else 0 if direction == Coordinate.

X: for index in range(len(idiom)): ret.append([x index - key_index, y, idiom[index]]) else: for index in range(len(idiom)): ret.

append([x, y index - key_index, idiom[index]]) return retdef fix_border(): min_x, min_y = 0, 0 for p in usedSeats: min_x = p[0] if p[0] < min_x else min_x min_y = p[1] if p[1] < min_y else min_y for p in splitIdioms: p[0] = p[0] abs(min_x) p[1] = p[1] abs(min_y)def printOnScreen(info): newStr = ' ' * (40 * 40) # 注意上面的空格是个中文空格!

! newList = list(newStr) # 把字符串编程list以方便下面的直接索引操作 # 如果输入值对某个坐标位置有定义,则将该位置的空格换成对应字符 for pinfo in info: index = 40 * pinfo[1] pinfo[0] newList[index] = pinfo[2] # 再把list变回字符串,以方便输出 finalStr = ''.

join(newList) print(finalStr)# info = [(0, 0, '天'), (1, 0, '地'), (3, 0, '人'), (2, 1, '日'), (2, 2, '月'), (2, 3, '风')]# printOnScreen(info)main()

相关阅读
  • 毛远新对张志新的看法 张志新的喉管与毛远新的腿

    毛远新对张志新的看法 张志新的喉管与毛远新的腿

    2017-10-06

    前几天看到一段过期电视新闻,里面出现一位久违的人物毛远新算起来三十年为一世,已经恍如隔世了。电视里他似乎行动不灵便,一问旁人原来他已经瘸了。apos瘸了?apos,身边一位几十年前见过他的老人说apos我记得76年他还正常着呢apos。

  • 袁隆平杂交水稻 袁隆平是真正的杂交水稻之父吗?

    袁隆平杂交水稻 袁隆平是真正的杂交水稻之父吗?

    2019-03-27

    一眼望去,颜龙安的试验田里满眼碧绿,看不出庄稼之间有什么差别。“这一蔸是不育系,旁边一排是恢复系,这一亩是野生稻,那一块是超级稻?” 听了他的介绍才知道,这些看上去长得差不多的绿色植物,原来“出身”各不相同。

  • 【小学语文教学大纲模板】俄专家建议:俄罗斯学校需统一汉语教学大纲

    【小学语文教学大纲模板】俄专家建议:俄罗斯学校需统一汉语教学大纲

    2020-03-07

    参考消息网1月2日报道 俄媒称,专家认为,俄罗斯学校需要制定统一的汉语教学大纲,并且通过在国家统一考试中引入汉语考试,这正变得愈发可行。据俄罗斯卫星通讯社1月1日报道,2018至2019学年,汉语首次被列入俄罗斯国家统一考试科目。