-
Notifications
You must be signed in to change notification settings - Fork 8
/
game.py
186 lines (155 loc) · 6.82 KB
/
game.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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
#pip install requests hgtk
import requests, hgtk, random
#이미 있는 단어 알기위해 단어목록 저장
history = []
playing = True
#키 발급은 https://krdict.korean.go.kr/openApi/openApiInfo
apikey = ''
#좀 치사한 한방단어 방지 목록
blacklist = ['즘', '틱', '늄', '슘', '퓸', '늬', '뺌', '섯', '숍', '튼', '름', '늠', '쁨']
#지정한 두 개의 문자열 사이의 문자열을 리턴하는 함수
#string list에서 단어, 품사와 같은 요소들을 추출할때 사용됩니다
def midReturn(val, s, e):
if s in val:
val = val[val.find(s)+len(s):]
if e in val: val = val[:val.find(e)]
return val
#지정한 두 개의 문자열 사이의 문자열 여러개를 리턴하는 함수
#string에서 XML 등의 요소를 분석할때 사용됩니다
def midReturn_all(val, s, e):
if s in val:
tmp = val.split(s)
val = []
for i in range(0, len(tmp)):
if e in tmp[i]: val.append(tmp[i][:tmp[i].find(e)])
else:
val = []
return val
def findword(query):
url = 'https://krdict.korean.go.kr/api/search?key=' + apikey + '&part=word&pos=1&q=' + query
response = requests.get(url)
ans = []
#단어 목록을 불러오기
words = midReturn_all(response.text,'<item>','</item>')
for w in words:
#이미 쓴 단어가 아닐때
if not (w in history):
#한글자가 아니고 품사가 명사일때
word = midReturn(w,'<word>','</word>')
pos = midReturn(w,'<pos>','</pos>')
if len(word) > 1 and pos == '명사' and not word in history and not word[len(word)-1] in blacklist:
ans.append(w)
if len(ans)>0:
return random.choice(ans)
else:
return ''
def checkexists(query):
url = 'https://krdict.korean.go.kr/api/search?key=' + apikey + '&part=word&sort=popular&num=100&pos=1&q=' + query
response = requests.get(url)
ans = ''
#단어 목록을 불러오기
words = midReturn_all(response.text,'<item>','</item>')
for w in words:
#이미 쓴 단어가 아닐때
if not (w in history):
#한글자가 아니고 품사가 명사일때
word = midReturn(w,'<word>','</word>')
pos = midReturn(w,'<pos>','</pos>')
if len(word) > 1 and pos == '명사' and word == query: ans = w
if len(ans)>0:
return ans
else:
return ''
print('''
=============파이썬 끝말잇기===============
사전 데이터 제공: 국립국어원 한국어기초사전
- - - 게임 방법 - - -
가장 처음 단어를 제시하면 끝말잇기가 시작됩니다
'/그만'을 입력하면 게임이 종료되며, '/다시'를 입력하여 게임을 다시 시작할 수 있습니다.
- - - 게임 규칙 - - -
1. 사전에 등재된 명사여야 합니다
2. 적어도 단어의 길이가 두 글자 이상이어야 합니다
3. 이미 사용한 단어를 다시 사용할 수 없습니다
4. 두음법칙 적용 가능합니다 (ex. 리->니)
==========================================
''')
answord = ''
sword = ''
while(playing):
wordOK = False
while(not wordOK):
query = input(answord + ' > ')
wordOK = True
if query == '/그만':
playing = False
print('컴퓨터의 승리!')
break
elif query == '/다시':
history = []
answord = ''
print('게임을 다시 시작합니다.')
wordOK = False
else:
if query == '':
wordOK = False
if len(history)==0:
print('단어를 입력하여 끝말잇기를 시작합니다.')
else:
print(sword + '(으)로 시작하는 단어를 입력해 주십시오.')
else:
#첫 글자의 초성 분석하여 두음법칙 적용 -> 규칙에 아직 완벽하게 맞지 않으므로 차후 수정 필요
if not len(history)==0 and not query[0] == sword and not query=='':
sdis = hgtk.letter.decompose(sword)
qdis = hgtk.letter.decompose(query[0])
if sdis[0] == 'ㄹ' and qdis[0] == 'ㄴ': print('두음법칙 적용됨')
elif (sdis[0] == 'ㄹ' or sdis[0] == 'ㄴ') and qdis[0] == 'ㅇ' and qdis[1] in ('ㅣ', 'ㅑ', 'ㅕ', 'ㅛ', 'ㅠ', 'ㅒ', 'ㅖ'): print('두음법칙 적용됨')
else:
wordOK = False
print(sword + '(으)로 시작하는 단어여야 합니다.')
if len(query) == 1:
wordOK = False
print('적어도 두 글자가 되어야 합니다')
if query in history:
wordOK = False
print('이미 입력한 단어입니다')
if query[len(query)-1] in blacklist:
print('아.. 좀 치사한데요..')
if wordOK:
#단어의 유효성을 체크
ans = checkexists(query)
if ans == '':
wordOK = False
print('유효한 단어를 입력해 주십시오')
else:
print('(' + midReturn(ans, '<definition>', '</definition>') + ')\n')
history.append(query)
if playing:
start = query[len(query)-1]
ans = findword(start + '*')
if ans=='':
#ㄹ -> ㄴ 검색
sdis = hgtk.letter.decompose(start)
if sdis[0] == 'ㄹ':
newq = hgtk.letter.compose('ㄴ', sdis[1], sdis[2])
print(start, '->', newq)
start = newq
ans = findword(newq + '*')
if ans=='':
#(ㄹ->)ㄴ -> ㅇ 검색
sdis = hgtk.letter.decompose(start)
if sdis[0] == 'ㄴ' and sdis[1] in ('ㅣ', 'ㅑ', 'ㅕ', 'ㅛ', 'ㅠ', 'ㅒ', 'ㅖ'):
newq = hgtk.letter.compose('ㅇ', sdis[1], sdis[2])
print(start, '->', newq)
ans = findword(newq + '*')
if ans=='':
print('당신의 승리!')
break
else:
answord = midReturn(ans, '<word>', '</word>') #단어 불러오기
ansdef = midReturn(ans, '<definition>', '</definition>') # 품사 불러오기
history.append(answord)
print(query, '>', answord, '\n('+ansdef+')\n')
sword = answord[len(answord)-1]
#컴퓨터 승리여부 체크
#if findword(sword) == '':
# print('tip: \'/다시\'를 입력하여 게임을 다시 시작할 수 있습니다')