プログラムに何とか形態素解析を取り組みたいと思う。アルファベットを用いたキチェ語では英語の様に各単語を離して表記するため、日本語程難しくはならないと思う。ただ、動詞を用いない会話も多いため、その点が少し問題となり得る。
取り敢えず、形態素解析をひとまず隅において、Kotz’i’jがユーザーが入力した文章を用いることが出来る仕様にした。辞書ファイルへの書き込みや入力内容の評価といったことが形態素解析にも繋がるので次に向けたステップとしては中々良いかな。
まぁ、恋するプログラムも同じ手順を踏んでいるということもあるけれど。
でプログラムだけど今回は3つのソース・ファイルを修正。
Dictionary.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
class Dictionary def initialize @random = [] open('dictionaries/list02.txt') do |f| f.each do |line| line.chomp! next if line.empty? @random.push(line) end end @pattern = [] open('dictionaries/patterns02.txt') do |f| f.each do |line| pattern, phrases = line.chomp.split("\t") #split by tab next if pattern.nil? or phrases.nil? @pattern.push(PatternItem.new(pattern, phrases)) end end end def study(input) return if @random.include?(input) @random.push(input) end def save open('dictionaries/list02.txt', 'w') do |f| f.puts(@random) end end attr_reader :random, :pattern end class PatternItem SEPARATOR = /^((-?\d+)##)?(.*)$/ def initialize(pattern, phrases) SEPARATOR =~ pattern @modify, @pattern = $2.to_i, $3 @phrases = [] phrases.split('|').each do |phrase| SEPARATOR =~ phrase @phrases.push({'need'=>$2.to_i, 'phrase'=>$3}) end end def match(str) return str.match(@pattern) end def choice(mood) choices = [] @phrases.each do |p| choices.push(p['phrase']) if suitable?(p['need'], mood) end return (choices.empty?)? nil : randomSelect(choices) end def suitable?(need, mood) return true if need == 0 if need > 0 return mood > need else return mood < need end end attr_reader :modify, :pattern, :phrases end |
Kotzij.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
require './Responder' require './Dictionary' class Kotzij def initialize @dictionary = Dictionary.new @emocion = Emocion.new(@dictionary) @responderWhat = WhatResponder.new(@dictionary) @responderRandom = RandomResponder.new(@dictionary) @responderPatterns = PatternResponder.new(@dictionary) @responder = @responderRandom end def dialogue(input) @emocion.update(input) case rand(10) when 0 @responder = @responderWhat when 1..5 @responder = @responderRandom else @responder = @responderPatterns end response = @responder.response(input, @emocion.mood) @dictionary.study(input) #@dictionary.save return response end def responderName return @responder.name end def mood return @emocion.mood end def save @dictionary.save end attr_reader :name end def randomSelect(ary) return ary[rand(ary.size)] end |
Tzijonik.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
require './Kotzij' require './Emocion' def prompt(kotzij) return 'Kotz\'ij > ' end puts('Tzijonik: Version 1.6 (20170518)') currentTime = Time.now #get the current time hour = currentTime.hour if hour > 3 && hour < 12 then saludo = 'Saqarik' elsif hour >= 12 && hour < 18 then saludo = 'Xe\'q\'ij' else saludo = 'Xokaq\'ab\'' end flor = Kotzij.new puts(prompt(flor) + saludo) puts(prompt(flor) + 'In al Kotz\'ij') while true print('At> ') input = gets input.chomp! if input == '' then @log = ["Tzijonik System: Log -- #{Time.now} "] open('TzijonikLog.txt', 'a') do |f| f.puts(@log) f.puts flor.save end end break if input == '' response = flor.dialogue(input) puts(prompt(flor) + response) end def putlog(log) @logArea.text += "#{log}\n" @logArea.scrollTo(@logArea.countLines-1, 1) @log.put(log) end |
プログラムの更新を分かりやすくするため、単語リストはトマト(pix)の一単語のみとしてみた。
実行してみる。
途中からKotz’ijがスペイン語を話し始めてしまった。
ちなみにXwanというのはスペイン語のJuan、Ko’zijのスペルは発音を間違えたと仮定して元々とは違う形で入力してみた。
プログラム終了時に単語リストはこうなっていた。
スペイン語を話し始めたKotz’ijだけど次回からは本格的にキチェ語を学ぶ様になるかな?まずはやはり名詞から始めようと思う。