끝말잇기(예제)#

KoML 의 기능들을 이용해서 끝말잇기를 만들어볼거에요.

<< 끝말잇기 하자
>> ㅋㅋㅋ 로봇인 나한테 끝말잇기로 덤비시겠다?
<< 응
>> 오키ㅋㅋ 그럼 너부터 시작해!
<< 고기
>> 기쁨
<< 쁨?
>> 뭐야 그건 너무 짧잖아 ㅋㅋ 너 졌어
<< 뭐야
>> ㅋㅋㅋㅋ억울하면 한 번 더 할래?
<< 아니
>> 싫으면 하지 마라ㅋㅋ 난 놀아줄라고 한건데
<< 끝말잇기 하자
>> ㅋㅋㅋ 로봇인 나한테 끝말잇기로 덤비시겠다?
<< 응
>> 오키ㅋㅋ 그럼 너부터 시작해!
<< 스트론튬
>> 앗.. 스트론튬은 이어지는 단어가 없는데ㅋㅋ 나의 패배다ㅠㅠ
<< ㅋㅋ
>> ㅋㅋㅋㅋ너 잘한다 한 번 더 할래?
<< 아니
>> 싫으면 하지 마라ㅋㅋ 난 놀아줄라고 한건데

끝말잇기 패키지 설치#

끝말잇기 로직을 직접 구현해도 되지만 끝말잇기를 쉽게 할 수 있도록 도와주는 파이썬 패키지 korean_word_relay 를 설치해주세요.

pip install korean_word_relay


커스텀 함수 작성#

끝말잇기를 하기위해 필요한 커스텀 함수를 작성해주세요.

from korean_word_relay import WordRelay
from koml import Context
import re

word_relay = WordRelay()
hangul = re.compile('[^ ㄱ-ㅣ가-힣]+')

def state_word_relay(word: str, context: Context|None=None) -> str:
    ''' 내 답안이 문제가 없는 답변안인지 확인 '''
    # 한글이 아닌 글자 모두 제거
    word = hangul.sub('', word)

    # 답변은 최소 2글자 이상!
    if len(word) < 2:
        return 'short'

    holder = []
    for item in context.history[:5]:
        holder.append(item.answer.strip())
        holder.append(item.question.strip())
    history = holder

    # 앞선 문맥에 중복된 단어 발견
    if word in history:
        return 'duplicated'

    # 앞에 단어와 내 답변이 끝말잇기 되지 않음
    if not history:
        return 'no_match'
    prev_word = hangul.sub('', history[0])

    is_start = '시작해' in prev_word
    is_continue = word_relay.check_continue(prev_word, word)
    if not is_start and not is_continue:
        return 'no_match'

    next_word = word_relay.get_next(word, log_history=False)
    # koml 봇이 대답할 수 있는 단어 찾음/못찾음
    if next_word:
        return 'found'
    else:
        return 'no_found'

def get_word_relay(word :str, context: Context|None=None) -> str:
    ''' koml 봇 끝말잇기 단어 리턴 '''
    word = hangul.sub('', word)
    next_word = word_relay.get_next(word, log_history=True)
    return next_word

koml 작성#

KoML의 기능들을 활용해서 끝말잇기 처리를 위한 case 들을 작성해주세요.


<!-- word_relay.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<koml>
  <case id='word_intro'>
    <pattern>
      <li>* 끝말잇기 할래_s</li>
      <li>끝말잇기 잘해_s</li>
      <li>끝말잇기 하자*</li>
    </pattern>
    <template>ㅋㅋㅋ 로봇인 나한테 끝말잇기로 덤비시겠다?</template>
  </case>

  <case>
    <follow cid='word_intro, word_user_lose, word_user_win'/>
    <pattern>
      <li>*싫은데?*</li>
      <li>* 아니 *</li>
      <li>* 싫어 *</li>
    </pattern>
    <template>싫으면 하지 마라ㅋㅋ 난 놀아줄라고 한건데</template>
  </case>

  <case id='word_1'>
    <follow cid='word_intro, word_user_lose, word_user_win'/>
    <pattern>
      <li>응 *</li>
      <li>*좋아*</li>
      <li>*하자*</li>
      <li>*그래*</li>
    </pattern>
    <template>오키ㅋㅋ 그럼 너부터 시작해!</template>
  </case>

  <case id='word_2'>
    <follow cid='word_1,word_2'/>
    <pattern><blank/></pattern>
    <template>
      <switch>
        <pivot><func name='state_word_relay'> <arg><blank/></arg> </func></pivot>
        <scase pivot='duplicated'>엥 그거 아까 나왔던 단어인데 ㅋㅋ 너 졌어</scase>
        <scase pivot='short'>뭐야 그건 너무 짧잖아 ㅋㅋ 너 졌어</scase>
        <scase pivot='no_match'>뭐야 <blank/>_eun 안이어지잖아ㅋㅋ 너 졌어</scase>
        <scase pivot='no_found'>앗.. <blank/>_eun 이어지는 단어가 없는데ㅋㅋ 나의 패배다ㅠㅠ</scase>
        <scase pivot='found'>
          <func name='get_word_relay'> <arg><blank/></arg> </func>
        </scase>
        <default>음.. 어렵네</default>
      </switch>
    </template>
  </case>

  <case id='word_user_lose'>
    <follow cid='word_2'>* 너 졌어</follow>
    <pattern>*</pattern>
    <template>ㅋㅋㅋㅋ억울하면 한 번 더 할래?</template>
  </case>

  <case id='word_user_win'>
    <follow cid='word_2'>* 나의 패배다ㅠㅠ</follow>
    <pattern>*</pattern>
    <template>ㅋㅋㅋㅋ너 잘한다 한 번 더 할래?</template>
  </case>
</koml>

실행#

작성한 커스텀 함수와 함께 KomlBot 을 실행해주세요.

from koml import KomlBot,  CustomBag

bag = CustomBag(funcs={'get_word_relay': get_word_relay, 'state_word_relay': state_word_relay})

bot = KomlBot(bag)
bot.learn(['word_relay.xml'])
bot.converse()

결과 확인#

끝말잇기가 성공적으로 진행 되면 성공입니다 :)


<< 끝말잇기 하자
>> ㅋㅋㅋ 로봇인 나한테 끝말잇기로 덤비시겠다?
<< 응
>> 오키ㅋㅋ 그럼 너부터 시작해!
<< 고기
>> 기쁨
<< 쁨?
>> 뭐야 그건 너무 짧잖아 ㅋㅋ 너 졌어
<< 뭐야
>> ㅋㅋㅋㅋ억울하면 한 번 더 할래?
<< 아니
>> 싫으면 하지 마라ㅋㅋ 난 놀아줄라고 한건데
<< 끝말잇기 하자
>> ㅋㅋㅋ 로봇인 나한테 끝말잇기로 덤비시겠다?
<< 응
>> 오키ㅋㅋ 그럼 너부터 시작해!
<< 스트론튬
>> 앗.. 스트론튬은 이어지는 단어가 없는데ㅋㅋ 나의 패배다ㅠㅠ
<< ㅋㅋ
>> ㅋㅋㅋㅋ너 잘한다 한 번 더 할래?
<< 아니
>> 싫으면 하지 마라ㅋㅋ 난 놀아줄라고 한건데