python成语接龙代码_Python实现成语接龙

开发之前

Python非常有意思,可以开发各种好玩的东西,而且代码很简洁。本文将指导大家怎样用Python实现成语接龙。我们将分为分为两个版本,一个是基础版,实现基本的成语接龙功能。还有一个是加强版,是在简易版上进行扩展,功能更为复杂且完善。

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

下面放实例:

开发环境:Windows

Python版本:3.x

外置模块准备:无

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

文件链接:https://pan.baidu.com/s/1dFFyHQ5 密码:6eiv

文件内容图:

v2-edaf8b7b4f00f83ad713b9b5ac106e93_b.png

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

基础版实现

实现原理,就是调用本地成语库进行字符串首尾条件匹配。

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

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()

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

importrandom

defidiom_exists(x):

"""判断是否为成语的函数,参数为字符串,判断该字符串是否在成语库中"""

withopen('idiom.txt','r')asf:

foriinset(f.readlines()):

ifx==i.strip():

returnTrue

returnFalse

defidiom_test(idiom1,idiom2):

"""判断两个成语是否达成接龙条件"""

ifidiom2[0]!=idiom1[-1]orlen(idiom2)!=4:

returnFalse

returnTrue

defidiom_select(x):

"""核心代码部分,参数x为成语,返回该成语的接龙匹配成语"""

ifx==None:

withopen('idiom.txt','r')asf:

returnrandom.choice(f.readlines())[:-1]

else:

withopen('idiom.txt','r')asf:

base=f.readlines()

random.shuffle(base)

foriinbase:

ifi[:-1]==xorlen(i)!=5:

continue

ifi[0]==x[-1]:

returni[:-1]

returnNone

defidiom_start(start=0):

"""start参数表示先后手,0表示电脑先手,1表示玩家先手;返回值代表游戏结果,为0表示玩家失败,为1代表玩家胜利"""

memory=set()#记忆集合,用于判断成语是否被重复使用

#如果电脑先手,电脑先抛出的第一个成语我们给点限制,要求它的接龙成语必须存在

ifstart==0:

whileTrue:

t=idiom_select(None)

ifidiom_select(t)!=Noneandlen(t)==4:

break

print(t)

else:

p=input("请输入成语:")

ifp.strip()=='':

print("游戏结束!你输了")

return0

ifidiom_exists(p)==False:

print("游戏结束!该成语不存在")

return0

memory.add(p)

cycle_flag=0#控制while True循环次数

whileTrue:

t=idiom_select(p)

cycle_flag+=1

iftnotinmemory:

break

ifcycle_flag==10:

t=None

break

ift==None:

print("恭喜你,你赢了!")

return1

else:

print(t)

memory.add(t)

whileTrue:

p=input("请输入成语:")

ifp.strip()=='':

print("游戏结束!你输了")

ifidiom_exists(p)==False:

print("游戏结束!该成语不存在")

return0

ifpinmemory:

print("游戏结束!该成语已被使用过")

return0

ifidiom_test(t,p)==False:

print("游戏结束!你未遵守游戏规则")

return0

memory.add(p)

cycle_flag=0

whileTrue:

t=idiom_select(p)

cycle_flag+=1

iftnotinmemory:

break

ifcycle_flag==10:

t=None

break

ift==None:

print("恭喜你,你赢了!")

return1

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”):

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)

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

importrandom

defchinese_to_pinyin(x):

"""参数为字符串,返回为该字符串对应的汉语拼音"""

y=''

dic={}

withopen("unicode_pinyin.txt")asf:

foriinf.readlines():

dic[i.split()[0]]=i.split()[1]

foriinx:

i=str(i.encode('unicode_escape'))[-5:-1].upper()

try:

y+=dic[i]+' '

except:

y+='XXXX '#非法字符我们用XXXX代替

returny

defidiom_exists(x):

"""判断是否为成语的函数,参数为字符串,判断该字符串是否在成语库中"""

withopen('idiom.txt','r')asf:

foriinset(f.readlines()):

ifx==i.strip():

returnTrue

returnFalse

defidiom_test(idiom1,idiom2,mode,opt):

"""判断两个成语是否达成接龙条件"""

#为了可读性,我把它分开写,比较清晰

ifmode==0andidiom2[0]!=idiom1[-1]:

returnFalse

ifmode==1andchinese_to_pinyin(idiom2[0])!=chinese_to_pinyin(idiom1[-1]):

returnFalse

ifmode==2andchinese_to_pinyin(idiom2[0])[:-2]!=chinese_to_pinyin(idiom1[-1])[:-2]:

returnFalse

ifopt==0andlen(idiom2)!=4:

returnFalse

returnTrue

defidiom_select(x,mode,opt):

"""核心代码部分,参数x为成语,返回该成语的接龙匹配成语"""

ifx==None:

withopen('idiom.txt','r')asf:

returnrandom.choice(f.readlines())[:-1]

else:

withopen('idiom.txt','r')asf:

#以下六行代码,通过索引排除无效循环,显著提升运行效率

pinyin=chinese_to_pinyin(x[-1])

base=f.readlines()

ifpinyin[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)

foriinbase:

ifi[:-1]==xor(opt==0andlen(i)!=5):

continue

ifmode==0andi[0]==x[-1]:

returni[:-1]

ifmode==1andchinese_to_pinyin(i[0])==pinyin:

returni[:-1]

ifmode==2andchinese_to_pinyin(i[0])[:-2]==pinyin[:-2]:

returni[:-1]

returnNone

defidiom_start(start=0,mode=0,opt=0):

"""start参数表示先后手,0表示电脑先手,1表示玩家先手;返回值代表游戏结果,为0表示玩家失败,为1代表玩家胜利"""

memory=set()#记忆集合,用于判断成语是否被重复使用

ifstart==0:

whileTrue:

t=idiom_select(None,mode,opt)

ifidiom_select(t,mode,opt)!=None:

break

print(t)

else:

p=input("请输入成语:")

ifp.strip()=='':

print("游戏结束!你输了")

return0

ifidiom_exists(p)==False:

print("游戏结束!该成语不存在")

return0

memory.add(p)

cycle_flag=0#控制while True循环次数

whileTrue:

t=idiom_select(p,mode,opt)

cycle_flag+=1

iftnotinmemory:

break

ifcycle_flag==10:

t=None

break

ift==None:

print("恭喜你,你赢了!")

return1

else:

print(t)

memory.add(t)

whileTrue:

p=input("请输入成语:")

ifp.strip()=='':

print("游戏结束!你输了")

ifidiom_exists(p)==False:

print("游戏结束!该成语不存在")

return0

ifpinmemory:

print("游戏结束!该成语已被使用过")

return0

ifidiom_test(t,p,mode,opt)==False:

print("游戏结束!你未遵守游戏规则")

return0

memory.add(p)

cycle_flag=0

whileTrue:

t=idiom_select(p,mode,opt)

cycle_flag+=1

iftnotinmemory:

break

ifcycle_flag==10:

t=None

break

ift==None:

print("恭喜你,你赢了!")

return1

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”置于同一目录下,放个测试效果图:

大致实现就是这样,大家也可以自己在此基础上进行更多拓展,如结合我上一篇文章实现成语的语音输出,也是非常不错的。

实例结束,我的表演完了,谢谢大家!如果这篇文章对你有帮助,请在收藏的同时一赞支持,谢谢!光收藏不点赞的让我好心塞啊。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值