目錄
前言
要實現的規則如下:根據接龍的成語的第一個字與前一個成語結尾的字的比較,分一下三種模式模式1:字相同拼音也要相同
模式2:字相同拼音不要求相同
模式3:字不要相同拼音要求相同,即諧音就可以接龍的成語必須是四字成語已使用過的成語雙方均不得再次使用一方不按照規則接龍或接不下去時判定失敗
數據獲取和清洗
本文語料來自于Bookdown圖書下載網,抓下來之后,經過亂碼處理、臟數據去除、分章數據合并、結構化提取等操作,得到了一份結構化好的json類型數據。我已經把它放在了github上,下載地址為github。
本成語庫總共包含成3萬個成語,其中四字成語大概2.9萬個。每條數據包含以下字段:字段說明字段說明idiom成語本身pinyin拼音
source成語出處explanation成語釋義
sample示例
代碼實現
代碼也已經放到了GitHub上,這里就不再貼出。源碼地址為https://github.com/lukeplus/Idiom。下面主要講講如何使用。
示例1:from solitaire import IdiomSolitairegame = IdiomSolitaire()game.forward("一心一意")# 輸出:(True, '意氣飛揚')game.forward("揚眉吐氣")# 輸出:(True, '氣壯山河')game.forward("呵呵呵呵")# 輸出:(False, None)
示例2:xxxxxxxxxx
game = IdiomSolitaire()game.get_next_idiom("人山人海")# 輸出:海市蜃樓game.get_next_idiom("人山人海")# 輸出:海闊天空game.get_next_idiom("戰戰兢兢")# 輸出:兢兢乾乾
示例3:xxxxxxxxxx
from solitaire import IdiomSolitairegame = IdiomSolitaire()# bot_first系統先開始idiom = game.bot_first() ? # 輸出:一心一意game.forward("意氣飛揚")# 輸出:(True, '揚長避短')
IdiomSolitaire類
IdiomSolitaire類負責成語接龍流程,以及游戲狀態維護。支持三種模式,如下:xxxxxxxxxx
game= IdiomSolitaire(mode="pw")# pw表示字和拼音都要保持一致game= IdiomSolitaire(mode="p")# p表示拼音一致即可game= IdiomSolitaire(mode="w")# w表示字一樣即可xxxxxxxxxx
game = IdiomSolitaire(mode="p")game.get_next_idiom("不三不四")# 輸出:肆意橫行
forward方法
推進游戲運行的主要方法,當第一次調用時,允許輸入參數為空,表示由系統起頭開始游戲。第一次調用不為空時,表示由客戶端開始游戲。forward既要檢驗輸入成語對上一個成語的承接(這是與get_next_idiom的主要區別),也要計算下一個成語。
返回二元組,第一個元素代表輸入的成語是否準確,是否能承接上一個成語,第二個元素是下一個待接龍的成語。當返回(False, None),表示輸入的成語不能連接上一個成語。用戶輸掉比賽。
當返回(True, None) , 表示機器找不到一個成語能接上用戶輸入的成語。機器輸掉比賽。
get_next_idiom
不考慮上下文,單純返回能承接輸入詞的詞語。
總結與改進
總的來說,簡單需求的成語接龍的實現幾乎沒什么難點,沒有牽涉到復雜的算法。而實現它的目的,是覺得可以拿這份成語語料做其他NLP相關的更酷的事情。比如說,給定一段話,通過語義分析之后,得到與這段話意思最相近的一個成語。
當然,要把成語接龍做得更人性化,還是得花很多心思的,也沒有那么簡單,需要改進的地方很多。比如系統選詞不應該是簡單的隨機選,而是應該考慮成語的難易程度、普及程度,畢竟如果老是隨機選一些冷門詞,那游戲就不好玩了。