不到 30 行代碼,我自制了一個(gè)成語接龍小游戲!
大家好,我是杰哥。
中國文化底蘊(yùn)深厚,在漫長的歷史中,我們的語言文字形成了大量特定的組合,用來表達(dá)特定的意思。成語是中國傳統(tǒng)文化的一大特色,有的來源于典故,有的則來源于固定的使用方法。在成語類的比賽中,經(jīng)常有“成語接龍”的比賽,往往是雙方對戰(zhàn),一方先提出一個(gè)成語,然后另一方根據(jù)這個(gè)成語最后一個(gè)字的拼音,作為下一個(gè)成語的首拼,承接下去。

本文中,我們希望借助R語言的文本處理工具做一個(gè)簡單的成語接龍小游戲,可以滿足簡單的人機(jī)對戰(zhàn)的需求。首先,讓我們在R中加載基本的環(huán)境:
if(!require(pacman)) install.packages("pacman")
## Loading required package: pacman
pacman::p_load(tidyfst,pinyin,stringr)
在上面加載的包中,tidyfst包用于數(shù)據(jù)的處理,pinyin包用于把漢字轉(zhuǎn)化為其拼音,stringr包則被用于字符串的處理。
首先,我們需要對成語的數(shù)據(jù)集進(jìn)行加載。這需要我們有中華成語的語料庫,在GitHub中有相關(guān)的庫可以用,詳情見:https://github.com/pwxcoo/chinese-xinhua。這個(gè)項(xiàng)目中的idiom.json文件包含了成語的信息,可以使用jsonlite包將其讀入并轉(zhuǎn)化為數(shù)據(jù)框。這里我們不詳細(xì)展開數(shù)據(jù)獲取和轉(zhuǎn)化的過程,我們最終把數(shù)據(jù)存儲(chǔ)在名為“chengyu.csv”的文件中,它只有一列,我們在這里進(jìn)行簡單展示:
fread("chengyu.csv",encoding = "UTF-8") # 編碼格式需要設(shè)置,否則可能顯示亂碼
## word
## <char>
## 1: 阿諛奉承
## 2: 阿黨比周
## 3: 阿黨相為
## 4: 阿狗阿貓
## 5: 阿姑阿翁
## ---
## 30891: 做一天和尚撞一天鐘
## 30892: 做賊心虛
## 30893: 做張做勢
## 30894: 做張做致
## 30895: 做張做智
我們看到,這份數(shù)據(jù)只有一列成語,共30895行,列名為word。僅僅是這個(gè)數(shù)據(jù)框還不足夠,我們還需要有每一個(gè)成語的首字拼音(簡稱“首拼”)和尾字拼音(簡稱“尾拼”)。關(guān)于這個(gè)步驟,我們可以使用pinyin包進(jìn)行實(shí)現(xiàn),具體操作如下:
my_dic = pydic(method = "tone",dic = "pinyin2") # 設(shè)置詞典
# 取得成語的首拼和尾拼
chengyu = fread("chengyu.csv",encoding = "UTF-8")%>%
mutate_dt(shoupin = str_sub(word,1,1)
%>% py(dic = my_dic),
weipin = str_sub(word,-1,-1) %>% py(dic = my_dic))
# 展示結(jié)果
chengyu
## word shoupin weipin
## <char> <char> <char>
## 1: 阿鼻地獄 a1 yu4
## 2: 阿黨比周 a1 zhou1
## 3: 阿黨相為 a1 wei2
## 4: 阿狗阿貓 a1 mao1
## 5: 阿姑阿翁 a1 weng1
## ---
## 30891: 做一天和尚撞一天鐘 zuo4 zhong1
## 30892: 做賊心虛 zuo4 xu1
## 30893: 做張做勢 zuo4 shi4
## 30894: 做張做致 zuo4 zhi4
## 30895: 做張做智 zuo4 zhi4
在上面的操作中,str_sub函數(shù)用來提取成語的第一個(gè)字和最后一個(gè)字,然后利用py函數(shù)來將其轉(zhuǎn)化為首拼和尾拼。pinyin包中有兩套詞典,這里用“pinyin2”詞典來完成轉(zhuǎn)化,因?yàn)樗腻e(cuò)誤率較低
(“pinyin1”詞典有bug,詳情可參考:https://github.com/pzhaonet/pinyin/issues/16)
下面,我們要設(shè)置一個(gè)小游戲。游戲中,我們首先提示用戶輸入一個(gè)成語,然后把用戶寫入的字符串導(dǎo)入,然后把匹配到的第一個(gè)成語輸出來,作為接龍的結(jié)果。如果庫內(nèi)沒有匹配的成語,那么就輸出“好吧,你贏了?!保缓髶Q行。如果匹配上了,就直接輸出匹配結(jié)果。當(dāng)用戶想退出的時(shí)候,鍵入大寫字母Q,然后按回車即可。實(shí)現(xiàn)代碼如下:
game = function(){
chengyu1 = chengyu
repeat{
cat("請輸入一個(gè)成語(認(rèn)輸或離開請按Q):")
input = readline()
if(input == "Q") break else chengyu1 = chengyu1[word != input]
str_sub(input,-1,-1) %>% py(dic = my_dic) -> input_weipin
res = chengyu1[shoupin == input_weipin]
if(nrow(res) == 0) {
cat("好吧,你贏了。\n")
}else{
cat(res$word[1])
chengyu1 = chengyu1[word != res$word[1]]
cat("\n")
}
}
}
現(xiàn)在,game函數(shù)中就封裝了我們這個(gè)游戲的所有過程。下面我們進(jìn)行簡單的解釋:
1、把chengyu這個(gè)數(shù)據(jù)框復(fù)制一份放在chengyu1中,因?yàn)槲覀冊诔烧Z接龍中不允許成語重復(fù)出現(xiàn),因此出現(xiàn)過一次的成語都會(huì)刪掉。
2、readline函數(shù)可以讓用戶交互式地讀入一段字符串;
3、cat函數(shù)可以在屏幕中輸出一段文字對話;
4、repeat語句相當(dāng)于while(1),如果沒有跳出語句(break),它會(huì)一直執(zhí)行下去。
下面,我們可以嘗試玩耍,從而進(jìn)行測試:

成語接龍測試
我們可以看到,基于命令行的小游戲沒有出現(xiàn)明顯的問題。這樣,我們就用了不到30行的代碼完成了成語接龍的小游戲,實(shí)現(xiàn)的完成代碼如下:
if(!require(pacman)) install.packages("pacman")
pacman::p_load(tidyfst,pinyin,stringr)
my_dic = pydic(method = "tone",dic = "pinyin2")
chengyu = fread("chengyu.csv",encoding = "UTF-8")%>%
mutate_dt(shoupin = str_sub(word,1,1)
%>% py(dic = my_dic),weipin = str_sub(word,-1,-1) %>% py(dic = my_dic))
chengyu
game = function(){
chengyu1 = chengyu
repeat{
cat("請輸入一個(gè)成語(認(rèn)輸或離開請按Q):")
input = readline()
if(input == "Q") break else chengyu1 = chengyu1[word != input]
str_sub(input,-1,-1) %>% py(dic = my_dic) -> input_weipin
res = chengyu1[shoupin == input_weipin]
if(nrow(res) == 0) {
cat("好吧,你贏了。\n")
}else{
cat(res$word[1])
chengyu1 = chengyu1[word != res$word[1]]
cat("\n")
}
}
}
game()
在這個(gè)基礎(chǔ)上,我們還可以讓電腦和電腦自己玩接龍游戲,從而得到一大串沒有重復(fù)的成語接龍結(jié)果。此外,還可以利用shiny包做一個(gè)漂亮的人機(jī)交互界面。
通過這個(gè)例子中,我們可以看到R語言強(qiáng)大的文本挖掘能力,但這都是比較零散的知識。要系統(tǒng)地學(xué)習(xí)一套R語言文本挖掘的系統(tǒng)知識與技術(shù),可以參考機(jī)械工業(yè)出版社出版的新作《文本數(shù)據(jù)挖掘——基于R語言》。
該書立足于R語言與文本挖掘知識基礎(chǔ),實(shí)用性和趣味性兼具,循序漸進(jìn)地引導(dǎo)讀者掌握各項(xiàng)文本挖掘?qū)崿F(xiàn)。書中包含大量代碼,因此也可以作為工具書為文本挖掘用戶提供R代碼參考。
贈(zèng)書福利
書籍贊助方: 機(jī)械工業(yè)出版社計(jì)算機(jī)分社
贈(zèng)書書籍:《文本數(shù)據(jù)挖掘基于 R 語言》
贈(zèng)書規(guī)則: 為本文「點(diǎn)贊」+ 「在看」 +「留言」且與文章內(nèi)容相關(guān)的優(yōu)質(zhì)留言即可上墻并從所有留言中選出點(diǎn)贊最多的前三位讀者留言將各獲得一本。
截止時(shí)間: 2021年6月22日,晚 20:00
領(lǐng)書須知: 提供轉(zhuǎn)發(fā)截圖 + 點(diǎn)贊和在看截圖
注意事項(xiàng): 凡發(fā)現(xiàn)刷贊者一律取消資格,最終獲贈(zèng)者請?jiān)?4小時(shí)以內(nèi)添加我的微信,備注:贈(zèng)書??
原創(chuàng)專輯
杰哥的另一個(gè)公眾號,主要分享關(guān)于個(gè)人成長經(jīng)歷的那點(diǎn)事,歡迎您的關(guān)注。

