Guest User

Untitled

a guest
Apr 22nd, 2013
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. local sounddict = {
  3.     ["hi"] = "",
  4.     ["hi there"] = "",
  5.     ["eat me"] = "",
  6.     ["eat"] = "",
  7.     ["an eye for an eye"] = "",
  8.     ["an eye for an apple or banana"] = "",
  9.     ["orange"] = "",
  10.     ["cactus"] = "",
  11.     ["cactus please"] = "",
  12.     ["no sir"] = "",
  13. }
  14.  
  15. local testphraselist = {
  16.     "hello",
  17.     "say hi",
  18.     "hi there",
  19.     "oh hi there",
  20.     "an eye for an eye for an eye for an apple or banana",
  21.     "an eye for an apple or banana",
  22.     "cactus orange no sir",
  23.     "eat me hi",
  24. }
  25.  
  26. local soundtree = {}
  27. local soundtree_filekey = newproxy and newproxy() or {}
  28. for sound_patt, sound_file in pairs(sounddict) do
  29.     local currnode = soundtree
  30.     for part in string.gmatch(sound_patt, "([a-z_]+)") do
  31.         -- TODO: preprocess part to ignore case and such
  32.         currnode[part] = currnode[part] or {}
  33.         currnode = currnode[part]
  34.     end
  35.     currnode[soundtree_filekey] = string.gsub(sound_patt, " ", "_")..".wav"
  36. end
  37.  
  38. function stuff(soundtree, phrase)
  39.     -- TODO: preprocess phrase to ignore case and such
  40.    
  41.     local foundlist = {}
  42.    
  43.     local stack_i = 0
  44.     local stack_eposlist = { [0] = 1 }
  45.     local stack_nodelist = { [0] = soundtree }
  46.     local complete, atend = false, false
  47.     local backtrack = false
  48.     repeat
  49.         local spos = stack_eposlist[stack_i]
  50.         local node = stack_nodelist[stack_i]
  51.         stack_i = stack_i+1
  52.         -- get next word
  53.         local word_s, word_e, mods = string.find(phrase, "([a-z_]+)(%p%d)+", spos, true)
  54.         if word_s then
  55.             -- we have a next word
  56.             local word = string.sub(phrase, word_s, word_e)
  57.             local subnode = node[word] -- (you could do pattern matching here)
  58.             if subnode then
  59.                 -- we have a pattern that matches this next word
  60.                 -- (could be first, middle or last word in pattern!)
  61.                 stack_eposlist[stack_i] = word_e+1
  62.                 stack_nodelist[stack_i] = subnode
  63.                 -- continue
  64.             else
  65.                 -- there is no continuing pattern that matches this word
  66.                 if stack_i == 1 then
  67.                     -- this is the first word or next unmatched word and no pattern starts with it
  68.                     -- so jump to next word
  69.                     stack_i = 0
  70.                     stack_eposlist[0] = word_e+1
  71.                 else
  72.                     -- we were matching a pattern, see what comes of it
  73.                     -- (this word did not continue any pattern, so it's not considered)
  74.                     backtrack = true
  75.                 end
  76.             end
  77.         else
  78.             -- there is no next word, check for patterns
  79.             -- (last few words may be rechecked if there is no sound for their nodes)
  80.             atend = true
  81.             backtrack = true
  82.         end
  83.         if backtrack then
  84.             -- find the longest pattern on the stack that has a sound associated
  85.             for stack_j = stack_i-1, 1, -1 do
  86.                 -- work backwards through each word to see if it has a sound
  87.                 local node = stack_nodelist[stack_j]
  88.                 local soundfile = node[soundtree_filekey]
  89.                 if soundfile then
  90.                     -- this word has a sound
  91.                     table.insert(foundlist, soundfile)
  92.                     -- TODO: handle mods here
  93.                    
  94.                     if stack_j == stack_i and atend then
  95.                         -- we consumed the last word
  96.                         complete = true
  97.                     else
  98.                         -- start searching for new patterns
  99.                         stack_i = 0
  100.                         -- resume from word after longest pattern with a sound
  101.                         stack_eposlist[0] = stack_eposlist[stack_j+1]
  102.                     end
  103.                     -- stop backtracking
  104.                     break
  105.                 end
  106.             end
  107.             backtrack, atend = false, false
  108.         end
  109.     until complete
  110.    
  111.     return foundlist
  112. end
  113.  
  114. for testphrase_i = 1, #testphraselist do
  115.     local testphrase = testphraselist[testphrase_i]
  116.     local out = stuff(soundtree, testphrase)
  117.     for sound_i = 1, #out do
  118.         print(out[sound_i])
  119.     end
  120. end
Advertisement
Add Comment
Please, Sign In to add comment