python实现成语填字游戏 自动生成题目

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


image.png

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

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

不常上简书没留意到留言,嘻嘻嘻,当时偷懒没有上传。我是写java的,本身不是写python的,所以代码里面可能有些不太优雅的地方,目标只是实现功能,见谅哈。另外有些代码可能是过程中为了调试写的,也懒得删了,记录了最原始的创作过程。(对了,我实现的这个,也是有参考别人的文章的,但是不记得是哪一篇了,看了好多篇,如果觉得有相同的地方,抱歉啊,欢迎原文作者们联系,一定把您大名署上)
可以调整目标成语数量target参数,改成你想要一次输出的成语数量。当然,你也可以优化将它变成传入参数,那会更加优雅一些,交给你自己啦。
在terminal里面运行时,要注意窗口大小,尤其是x轴方向的长度,要符合代码里的设定,不然的话出来的是对不齐的,正常应该是这样:


image.png

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


image.png
import random

import pymysql
from 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[i][0], idiom_split[i][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 ret


def 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()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,874评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,102评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,676评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,911评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,937评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,935评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,860评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,660评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,113评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,363评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,506评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,238评论 5 341
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,861评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,486评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,674评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,513评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,426评论 2 352

推荐阅读更多精彩内容

  • 这是一本研究社会心理学的书,我们生活的周围,其实都可能被顺从性所影响。 我们为什么会当软柿子的原因?日常生活中,我...
    衣非阅读 479评论 0 2
  • 书籍《亲密关系》 阅读目的 我是一个有点内向的人,母胎单身,喜欢沉浸在自己的世界里,从没有和异性有过深入接触,无法...
    丽丽许专栏阅读 128评论 0 0
  • 三天温馨而有能量的《智慧之旅》,让我对智慧的涵义有了新的体会。 从“感恩” 到“孝道”;从“自我认知”到“德行”的...
    弘一男子阅读 108评论 0 0
  • 茜纱烛影舞难休, 烟绕七弦独倚楼。 一任空阶寂寞雨, 滴破无边梦里愁。
    桨影铭阅读 229评论 0 2
  • 梦 想 病躯像把丢了钥匙的锁 囚困了我向往自由的灵魂 梦想则是那翱翔...
    Any梦阅读 1,504评论 25 52