和别人玩成语接龙词汇量少怎么办?今天教你在成语接龙无敌天下

前言

这是一篇用Python实现成语接龙小游戏的具体开发教程。Python实现这个功能非常容易,以下分为两个版本,一个是简易版,能够实现基本的功能。还有一个是拓展版,是在简易版上进行拓展,功能更为复杂且完善。

和别人玩成语接龙词汇量少怎么办?今天教你在成语接龙无敌天下_第1张图片

 

这个可以应用在很多方面,比如说聊天机器人,而且还可以结合itchat这个Python的微信接口玩出花样等等。

下面放实例:

开发环境:Windows

Python版本:3.x

外置模块准备:无

文件准备:成语库文件(例如我使用的是idiom.txt),当然也可以从网上抓取匹配成语,但效率相对要慢。本功能是完全可以在本地实现的。

文件内容图:

和别人玩成语接龙词汇量少怎么办?今天教你在成语接龙无敌天下_第2张图片

 

我整理出了共11174个常用成语,不是很全但一般使用是没有问题的,你们也可以酌情自行添加补充。

PS:如有需要Python学习资料的小伙伴可以加下方的群去找免费管理员领取

 

可以免费领取源码、项目实战视频、PDF文件等

 

简易版实例

实现原理大家可能也想到了,就是调用本地成语库进行字符串首尾条件匹配。

先说一下简易版成语接龙规则:

1.接龙的成语的第一个字必须要与前一个成语结尾的字相同

2.接龙的成语必须是四字成语

3.已使用过的成语双方均不得再次使用

4.一方不按照规则接龙或接不下去时判定失败

我将其功能用函数分解了,这样结构更加清晰也方便调试,源码(文件名为"idiom_s.py")及注释如下:

import random

def idiom_exists(x):
    """判断是否为成语的函数,参数为字符串,判断该字符串是否在成语库中"""
    with open('idiom.txt','r') as f:
        for i in set(f.readlines()):
            if x == i.strip():
                return True
        return False

def idiom_test(idiom1, idiom2):
    """判断两个成语是否达成接龙条件"""
    if idiom2[0] != idiom1[-1] or len(idiom2) != 4:
        return False
    return True

def idiom_select(x):
    """核心代码部分,参数x为成语,返回该成语的接龙匹配成语"""
    if x == None:
        with open('idiom.txt','r') as f:
            return random.choice(f.readlines())[:-1]
    else:
        with open('idiom.txt','r') as f:
            base = f.readlines()
            random.shuffle(base)
            for i in base:
                if i[:-1] == x or len(i) != 5:
                    continue
                if i[0] == x[-1]:
                    return i[:-1]
        return None

def idiom_start(start = 0):
    """start参数表示先后手,0表示电脑先手,1表示玩家先手;返回值代表游戏结果,为0表示玩家失败,为1代表玩家胜利"""
    memory = set()  #记忆集合,用于判断成语是否被重复使用
    #如果电脑先手,电脑先抛出的第一个成语我们给点限制,要求它的接龙成语必须存在
    if start == 0:
        while True:
            t = idiom_select(None)
            if idiom_select(t) != None and len(t) == 4:
                break
        print(t)
    else:
        p = input("请输入成语:")
        if p.strip() == '':
            print("游戏结束!你输了")
            return 0
        if idiom_exists(p) == False:
            print("游戏结束!该成语不存在")
            return 0
        memory.add(p)
        cycle_flag = 0  #控制while True循环次数
        while True:
            t = idiom_select(p)
            cycle_flag += 1
            if t not in memory:
                break
            if cycle_flag == 10:
                t = None
                break
        if t == None:
            print("恭喜你,你赢了!")
            return 1
        else:
            print(t)
            memory.add(t)        
    while True:
        p = input("请输入成语:")
        if p.strip() == '':
            print("游戏结束!你输了")
        if idiom_exists(p) == False:
            print("游戏结束!该成语不存在")
            return 0
        if p in memory:
            print("游戏结束!该成语已被使用过")
            return 0
        if idiom_test(t, p) == False:
            print("游戏结束!你未遵守游戏规则")
            return 0
        memory.add(p)
        cycle_flag = 0
        while True:
            t = idiom_select(p)
            cycle_flag += 1
            if t not in memory:
                break
            if cycle_flag == 10:
                t = None
                break
        if t == None:
            print("恭喜你,你赢了!")
            return 1
        else:
            print(t)
            memory.add(t)

#测试运行
idiom_start()

 

这就是简易版的全部内容,测试时将该程序"idiom_s.py"和成语库文件"idiom.txt"置于同一目录下,放个测试效果图:

和别人玩成语接龙词汇量少怎么办?今天教你在成语接龙无敌天下_第3张图片

 

拓展版实例

简易版的游戏规则略显严格,我们可以稍微对其进行点改变使其更加有趣。但原则上拓展版也必须兼容简易版的规则,这时我们可以用参数调节游戏规则。

拓展版成语接龙规则:

1.接龙的成语的第一个字必须要与前一个成语结尾的字相同(mode = 0);接龙的成语的第一个字的拼音包括音调要与前一个成语结尾的字的拼音和音调相同(mode = 1);接龙的成语的第一个字的拼音字母(不包括音调)与前一个成语结尾的字的拼音字母相同(mode = 2)

2.接龙的成语必须是四字成语(opt = 0);接龙的成语可以不是四字成语(opt = 1)

3.已使用过的成语双方均不得再次使用

4.一方不按照规则接龙或接不下去时判定失败

可以看出拓展版的确对简易版做了比较大的拓展,还涉及汉字转拼音。

下面展示源码(文件名为"idiom_p.py"):

import random

def chinese_to_pinyin(x):
    """参数为字符串,返回为该字符串对应的汉语拼音"""
    y = ''
    dic = {}
    with open("unicode_pinyin.txt") as f:
        for i in f.readlines():
            dic[i.split()[0]] = i.split()[1]
    for i in x:
        i = str(i.encode('unicode_escape'))[-5:-1].upper()
        try:
            y += dic[i] + ' '
        except:
            y += 'XXXX ' #非法字符我们用XXXX代替
    return y

def idiom_exists(x):
    """判断是否为成语的函数,参数为字符串,判断该字符串是否在成语库中"""
    with open('idiom.txt','r') as f:
        for i in set(f.readlines()):
            if x == i.strip():
                return True
        return False

def idiom_test(idiom1, idiom2, mode, opt):
    """判断两个成语是否达成接龙条件"""
    #为了可读性,我把它分开写,比较清晰
    if mode == 0 and idiom2[0] != idiom1[-1]:
        return False
    if mode == 1 and chinese_to_pinyin(idiom2[0]) != chinese_to_pinyin(idiom1[-1]):
        return False
    if mode ==2 and chinese_to_pinyin(idiom2[0])[:-2] != chinese_to_pinyin(idiom1[-1])[:-2]:
        return False
    if opt == 0 and len(idiom2) != 4:
        return False
    return True

def idiom_select(x, mode, opt):
    """核心代码部分,参数x为成语,返回该成语的接龙匹配成语"""
    if x == None:
        with open('idiom.txt','r') as f:
            return random.choice(f.readlines())[:-1]
    else:
        with open('idiom.txt','r') as f:
            #以下六行代码,通过索引排除无效循环,显著提升运行效率
            pinyin = chinese_to_pinyin(x[-1])
            base = f.readlines()
            if pinyin[0] != 'Z':
                base = base[base.index(pinyin[0]+'\n'):base.index(chr(ord(pinyin[0])+1)+'\n')]
            else:
                base = base[base.index(pinyin[0]+'\n'):]
            random.shuffle(base)
            for i in base:
                if i[:-1] == x or (opt == 0 and len(i) != 5):
                    continue
                if mode == 0 and i[0] == x[-1]:
                    return i[:-1]
                if mode == 1 and chinese_to_pinyin(i[0]) == pinyin:
                    return i[:-1]
                if mode == 2 and chinese_to_pinyin(i[0])[:-2] == pinyin[:-2]:
                    return i[:-1]
        return None

def idiom_start(start = 0, mode = 0, opt = 0):
    """start参数表示先后手,0表示电脑先手,1表示玩家先手;返回值代表游戏结果,为0表示玩家失败,为1代表玩家胜利"""
    memory = set()  #记忆集合,用于判断成语是否被重复使用
    if start == 0:
        while True:
            t = idiom_select(None, mode, opt)
            if idiom_select(t, mode, opt) != None:
                break
        print(t)
    else:
        p = input("请输入成语:")
        if p.strip() == '':
            print("游戏结束!你输了")
            return 0
        if idiom_exists(p) == False:
            print("游戏结束!该成语不存在")
            return 0
        memory.add(p)
        cycle_flag = 0  #控制while True循环次数
        while True:
            t = idiom_select(p, mode, opt)
            cycle_flag += 1
            if t not in memory:
                break
            if cycle_flag == 10:
                t = None
                break
        if t == None:
            print("恭喜你,你赢了!")
            return 1
        else:
            print(t)
            memory.add(t)        
    while True:
        p = input("请输入成语:")
        if p.strip() == '':
            print("游戏结束!你输了")
        if idiom_exists(p) == False:
            print("游戏结束!该成语不存在")
            return 0
        if p in memory:
            print("游戏结束!该成语已被使用过")
            return 0
        if idiom_test(t, p, mode, opt) == False:
            print("游戏结束!你未遵守游戏规则")
            return 0
        memory.add(p)
        cycle_flag = 0
        while True:
            t = idiom_select(p, mode, opt)
            cycle_flag += 1
            if t not in memory:
                break
            if cycle_flag == 10:
                t = None
                break
        if t == None:
            print("恭喜你,你赢了!")
            return 1
        else:
            print(t)
            memory.add(t)

#测试运行,修改参数使其变为规则更加宽松的接龙(mode和opt默认为0则为简易版的成语接龙)
idiom_start(start=1, mode=2, opt=1)

 

这就是简易版的全部内容,测试时将该程序"idiom_p.py",成语库文件"idiom.txt"和汉字拼音文件"unicode_pinyin.txt"置于同一目录下,放个测试效果图:

和别人玩成语接龙词汇量少怎么办?今天教你在成语接龙无敌天下_第4张图片

 

本文的文字及图片来源于网络,仅供学习、交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理。

作者:碧茂大数据

你可能感兴趣的:(和别人玩成语接龙词汇量少怎么办?今天教你在成语接龙无敌天下)