7
\$\begingroup\$

Was the best way to implent this? For example it will only say "It's nice I know." If you first ask "hat" and then answer "yes".

This is how I'm thinking:

Topic = 0

local messages = {
    {"name", "I'm Bob, the owner of this little shop."},
    {"job", "I sell stuff."},
    {"hat|head", "You like my hat?", Topic = 1},
    {Topic == 1, "yes", "It's nice I know."}}

for i, a in ipairs(messages) do
    if isMsg(a[1], msg) then
        makeSay(a[2])
        return true
    end
end

Functions

function isMsg(messages, msg)
    local keys = split(messages, "|")
    if getmsg(keys, msg) then
        return true
    end
    return false
end

function table.contains(table, element)
    for _, value in ipairs(table) do
        if value == element then
            return true
        end
    end
    return false
end

function getmsg(t, msg)
    for v, a in ipairs(t) do
        if msgcontains(msg, a) then
            return true
        end
    end
    return false
end

function keyContains(t, msg)
    for v, t in ipairs(t) do
        if t == msg then
            return true
        end
    end
    return false
end

function split(str, pat)
    local t = {} -- NOTE: use {n = 0} in Lua-5.0
    local fpat = "(.-)" .. pat
    local last_end = 1
    local s, e, cap = str:find(fpat, 1)
    while s do
        if s ~= 1 or cap ~= "" then
            table.insert(t,cap)
        end
        last_end = e+1
        s, e, cap = str:find(fpat, last_end)
    end
    if last_end <= #str then
        cap = str:sub(last_end)
        table.insert(t, cap)
    end
    return t
end
\$\endgroup\$

1 Answer 1

7
\$\begingroup\$

I see a lot of problems here...

  • are the answers selectable in the GUI? If not such predefined answers are not quite user-friendly, prone to typos etc.
  • You might have to escape strings with "|" then unescape them. Yes chances are low, but that's how bugs start.
  • Use closures. Do not redefine your table every time you run that function
  • for k,v in ipairs(tbl) is a lot slower than for i, #tbl do
  • Is there an actual difference between keyContains and table.contains?

Use Hash-Tables

Lua has a pretty fast implementation of them, so your decision code could be made a lot faster - and easier to read like this

local messages = {
    ["name"] = "I'm Bob, the owner of this little shop.",
    ["job"] = "I sell stuff.",
}

function getanswer(question)
    return messages[question];
end
  • Since Lua hashes all strings anyway you will almost always win using hashtables.
  • Your string can contain any value
  • it's a lot easier to read.

Now for the topics. I will skip the part where you "revert" from topics, since you have to know yourself whether you need to "cancel out" or "time out" or don't allow it in general.

local messages = {
    [1] = "Hello stranger!",
    ["name"] = "I'm Bob, the owner of this little shop.",
    ["job"] = "I sell stuff.",
    ["hat"] = {
         [1] = "You like my hat?",
         ["yes"] = "It's nice I know.",
         ["no"] = "You ...!",
    },
}
local topic = messages;

function getanswer(question)
    if type(topic[question]) == "table" then
        topic = topic[question];
        return topic[1];
    else
        return topic[question];
    end
end

You could also implement random answers quite easily by just adding more integer key values and selecting one with math.random(1, #topic)

if there are duplicate topics, just duplicate the table. Yeah it looks like a big overhead but in most cases it doesn't really matter. An alternative is just referencing the table like

messages.head = messages.hat;

Though that might get hard to maintain. There are other options but my answer would just get longer and longer...

\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.