自己動手設計交談機器人 - 使用 Java自己動手設計交談機器人 - 使用 Java
作者:陳鍾誠
程式下載:ChatBot.zip
簡介
你的程式會與人聊天嗎,本文說明了如何用 Java 設計一個命令列的聊天虛擬機器人。
// --- ChatBot.java -----
import java.util.*;
import java.io.*;
// ChatBot.java
// 執行方式 : 必需有 Java JVM,然後
// 方法 1. 直接點選 ChatBot.bat 即可。
// 方法 2. 執行命令列,將命令列切換到本資料夾打 java ChatBot 即可。
// 注意:該資料夾中必需有 ChatBotRule.txt 的檔案
public class ChatBot {
Vector<QA> qaList = new Vector<QA>();
public static void main(String[] args) throws Exception {
ChatBot agent = new ChatBot();
agent.load("ChatBotRule.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String question;
System.out.println("您好,我的朋友! 有心事嗎 ?");
do {
System.out.print(">> ");
question = reader.readLine();
Thread.currentThread().sleep(1000);
System.out.println(agent.answer(question));
} while (!question.equals("再見"));
}
void load(String pFile) throws Exception {
String kb = STR.file2text(pFile, "BIG5");
String[] blocks = kb.split("Q\\:");
for (int i=0; i<blocks.length; i++) {
String block = blocks[i].trim();
if (block.length()==0) continue;
QA qa = new QA(block);
qaList.add(qa);
}
}
String answer(String input) {
for (int i=0; i<qaList.size(); i++) {
QA qa = qaList.get(i);
String answer = qa.answer(input);
if (answer != null)
return answer;
}
return "然後呢?";
}
}
class STR {
public static String head(String pStr, String pSpliter) {
int spliterPos = pStr.indexOf(pSpliter);
if (spliterPos < 0) return pStr;
return pStr.substring(0,spliterPos);
}
public static String tail(String pStr, String pSpliter) {
int spliterPos = pStr.indexOf(pSpliter);
if (spliterPos < 0) return "";
return pStr.substring(spliterPos+pSpliter.length());
}
public static String replace(String pStr, String fromPat, String toPat) {
if (fromPat.length()==0) return pStr;
if (pStr.indexOf(fromPat)<0) return pStr;
StringBuffer rzStr = new StringBuffer();
int strIdx = 0, nextIdx;
while ((nextIdx = pStr.indexOf(fromPat, strIdx))>=0) {
rzStr.append(pStr.substring(strIdx, nextIdx));
rzStr.append(toPat);
strIdx = nextIdx + fromPat.length();
}
rzStr.append(pStr.substring(strIdx));
return rzStr.toString();
}
public static String expand(String pText, String pMacros) {
String[] macros = pMacros.split("\\|");
for (int i=0; i<macros.length; i++) {
String name = head(macros[i], "=");
String expand = tail(macros[i], "=");
pText = replace(pText, name, expand);
}
return pText;
}
public static String file2text(String fileName, String encode) throws Exception {
File f = new File(fileName);
int length = (int)(f.length());
FileInputStream fin = new FileInputStream(f);
byte[] bytes = new byte[length];
fin.read(bytes);
return new String(bytes, encode);
}
}
class QA {
static Random random = new Random(3767);
String q[], a[];
QA(String block) {
block = STR.replace(block, "\r", "");
block = STR.replace(block, " ", "");
String head = STR.head(block, "\n");
String tail = STR.tail(block, "\n");
q = head.split("\\|");
a = tail.split("\n");
}
public String answer(String input) {
for (int i=0; i<q.length; i++) {
int matchAt = input.indexOf(q[i]);
String tail;
if (matchAt >= 0)
tail = input.substring(matchAt+q[i].length());
else if (q[i].equals("比對失敗"))
tail = "";
else
continue;
int aIdx = Math.abs(random.nextInt())%a.length;
String answer = STR.replace(a[aIdx], "*", tail);
answer = STR.expand(answer, "我=");
return answer;
}
return null;
}
public String toString() {
return "Q:"+Arrays.asList(q)+" A:"+Arrays.asList(a);
}
}
// --- ChatBotRule.txt -----
Q:謝謝
不客氣!
Q:對不起 | 抱歉 | 不好意思
別說抱歉 !
別客氣,儘管說 !
Q:可否 | 可不可以
你確定想*
Q:我想
你為何想*
Q:我要
你為何要*
Q:你是
你認為我是*
Q:認為 | 以為
為何說*?
Q:感覺
常有這種感覺嗎?
Q:為何不
你希望我*
Q:是否
為何想知道是否*
Q:不能
為何不能*?
你試過了嗎?
或許你現在能*了呢?
Q:我是
你好,久仰久仰!
Q:甚麼 | 什麼 | 何時 | 誰 | 哪裡 | 如何 | 為何 | 因何
為何這樣問?
為何你對這問題有興趣?
你認為答案是甚麼呢?
你認為如何呢?
你常問這類問題嗎?
這真的是你想知道的嗎?
為何不問問別人?
你曾有過類似的問題嗎?
你問這問題的原因是甚麼呢?
Q:原因
這是真正的原因嗎?
還有其他原因嗎?
Q:理由
這說明了甚麼呢?
還有其他理由嗎?
Q:你好 | 嗨 | 您好
你好,有甚麼問題嗎?
Q:或許
你好像不太確定?
Q:不曉得 | 不知道
為何不知道?
在想想看,有沒有甚麼可能性?
Q:不想 | 不希望
有沒有甚麼辦法呢?
為何不想*?
那你希望怎樣呢?
Q:想 | 希望
為何想*?
真的想*?
那就去做阿?
為何不呢?
Q:不
為何不*?
Q:請
我該如何*
你想要我*
Q:你
你真的是在說我嗎?
別說我了,談談你吧!
為何這麼關心我*
不要再說我了,談談你吧!
你自己*
Q:總是 | 常常
能不能具體說明呢?
何時?
Q:像
有多像?
哪裡像?
Q:對
你確定嗎?
我了解!
Q:朋友
多告訴我一些有關他的事吧!
你認識他多久了呢?
Q:電腦
你說的電腦是指我嗎?
Q:難過
別想它了
別難過
別想那麼多了
事情總是會解決的
Q:高興
不錯ㄚ
太棒了
這樣很好ㄚ
Q:是阿|是的
甚麼事呢?
我可以幫助你嗎?
我希望我能幫得上忙!
Q:比對失敗
我了解
我能理解
還有問題嗎 ?
請繼續說下去
可以說的更詳細一點嗎?
這樣喔! 我知道!
然後呢? 發生甚麼事?
再來呢? 可以多說一些嗎
接下來呢?
可以多告訴我ㄧ些嗎?
多談談有關你的事,好嗎?
祝福你
想多聊ㄧ聊嗎
可否多告訴我ㄧ些呢?
|