开发之前
Python非常有意思,可以开发各种好玩的东西,而且代码很简洁。本文将指导大家怎样用Python实现成语接龙。我们将分为分为两个版本,一个是基础版,实现基本的成语接龙功能。还有一个是加强版,是在简易版上进行扩展,功能更为复杂且完善。
这个可以应用在很多方面,比如说聊天机器人,而且还可以结合itchat这个Python的微信接口玩出花样等等。
下面放实例:
开发环境:Windows
Python版本:3.x
外置模块准备:无
文件准备:成语库文件(例如我使用的是idiom.txt),当然也可以从网上抓取匹配成语,但效率相对要慢。本功能是完全可以在本地实现的。
文件链接:https://pan.baidu.com/s/1dFFyHQ5 密码:6eiv
文件内容图:
我整理出了共11174个常用成语,不是很全但一般使用是没有问题的,你们也可以酌情自行添加补充。
基础版实现
实现原理,就是调用本地成语库进行字符串首尾条件匹配。
先说一下简易版成语接龙规则:
1.接龙的成语的第一个字必须要与前一个成语结尾的字相同
2.接龙的成语必须是四字成语
3.已使用过的成语双方均不得再次使用
4.一方不按照规则接龙或接不下去时判定失败
我们将其功能用函数分解了,似的结构更加清晰也方便调试,源码(文件名为”idiom_s.py”)及注释如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
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”置于同一目录下,放个测试效果图:
增强版实现
简易版的游戏规则略显严格,我们可以稍微对其进行点改变使其更加有趣。但原则上增强版也兼容简易版的规则,这时我们可以用参数调节游戏规则。
拓展版成语接龙规则:
1.接龙的成语的第一个字必须要与前一个成语结尾的字相同(mode = 0); 接龙的成语的第一个字的拼音包括音调要与前一个成语结尾的字的拼音和音调相同(mode = 1);接龙的成语的第一个字的拼音字母(不包括音调)与前一个成语结尾的字的拼音字母相同(mode = 2)
2.接龙的成语必须是四字成语(opt = 0);接龙的成语可以不是四字成语(opt = 1)
3.已使用过的成语双方均不得再次使用
4.一方不按照规则接龙或接不下去时判定失败
可以看出拓展版的确对简易版做了比较大的拓展,还涉及汉字转拼音,实现详见我的另一篇文章:Python实现文字转语音功能 – 知乎专栏
下面展示源码(文件名为”idiom_p.py”):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
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”置于同一目录下,放个测试效果图:
大致实现就是这样,大家也可以自己在此基础上进行更多拓展,如结合我上一篇文章实现成语的语音输出,也是非常不错的。
实例结束,我的表演完了,谢谢大家!如果这篇文章对你有帮助,请在收藏的同时一赞支持,谢谢!光收藏不点赞的让我好心塞啊。
未经允许不得转载:Python在线学习 » Python实现成语接龙