陳鍾誠 | 教材 | 程式 | 文章 | 留言版


自己動手設計交談機器人 - 使用 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:比對失敗 我了解 我能理解 還有問題嗎 ? 請繼續說下去 可以說的更詳細一點嗎? 這樣喔! 我知道! 然後呢? 發生甚麼事? 再來呢? 可以多說一些嗎 接下來呢? 可以多告訴我ㄧ些嗎? 多談談有關你的事,好嗎? 祝福你 想多聊ㄧ聊嗎 可否多告訴我ㄧ些呢?



    作者:陳鍾誠 E-mail:ccc@kmit.edu.tw
    Creative Commons License

    本著作係採用創用 CC 「姓名標示─相同方式分享 2.5 台灣版」授權條款釋出。

    大學課程網 | 手機入口網