今日午後の授業に行く前にプログラムに機能を追加した。本の第6章にあるように、Kotz’ijに感情モデルを実装した。具体的には特定の言葉によって機嫌が良くなったり、悪くなったりということ。
キチェ語クラスでの単語は150以上位だと思うけど、あまり形容詞を習っていないので今のところ機嫌を良くする言葉(Utz Kotz’i’j=可愛いKotz’i’j)と反対に機嫌を悪くさせる言葉(Chom=太っている)それぞれ一つずつ。
それらはパターン回答集に追加。.rbファイルは5つ。
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 |
require './Kotzij' require './Emocion' def prompt(kotzij) return 'Kotz\'ij > ' end puts('Tzijonik: Version 1.4 (20170511)') 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! break if input == '' response = flor.dialogue(input) puts(prompt(flor) + response) 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 |
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 else @responder = @responderPatterns end return @responder.response(input, @emocion.mood) end def responderName return @responder.name end def mood return @emocion.mood end attr_reader :name end def randomSelect(ary) return ary[rand(ary.size)] end |
Responder.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 |
class Responder def initialize(dictionary) @dictionary = dictionary end def response(input, mood) return '' end attr_reader :name end class WhatResponder < Responder def response(input, mood) "Jas #{input}?" end end class RandomResponder < Responder def response(input, mood) return randomSelect(@dictionary.random) end end class PatternResponder < Responder def response(input, mood) @dictionary.pattern.each do |patternItems| if m = patternItems.match(input) resp = patternItems.choice(mood) next if resp.nil? return resp.gsub(/%match%/, m.to_s) end end return randomSelect(@dictionary.random) end end |
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 |
class Dictionary def initialize @random = [] open('dictionaries/list01.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 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 |
で最後に新しく作成したEmocion.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 |
class Emocion MOOD_MIN = -10 MOOD_MAX = 10 MOOD_RECOVERY = 0.5 def initialize(dictionary) @dictionary = dictionary @mood = 0 end def update(input) @dictionary.pattern.each do |patternItems| if patternItems.match(input) adjust_mood(patternItems.modify) break end end if @mood < 0 @mood += MOOD_RECOVERY elsif @mood > 0 @mood -= MOOD_RECOVERY end end def adjust_mood(val) @mood += val if @mood > MOOD_MAX @mood = MOOD_MAX elsif @mood < MOOD_MIN @mood = MOOD_MIN end end attr_reader :mood end |
キチェ語、英語、スペイン語が入り混じってちょっと分かりずらくなってきたかなぁ。