0
votes

So I'm making a script and I got a function:

loot()

that returns:

{"3 gold coins"}
{"3 gold coins"}
{"nothing"}
{"6 gold coins", "a hand axe"}
{"12 gold coins", "a hand axe"}

I want that function to be included in a table, and the table should read "a", "an", "without a number before the word" = 1

so the table reads and does a count example:

table = {"gold coins"=24,"nothing"=1,"hand axe"=2}

This is the kind of table I'm searching for, but I didn't have any success doing it at the moment. Like I said before my function loot() returns those messages, these aren't the only messages that loot reads, but I want to save their number or "a", "an" as number values for 1, so if it's "6 gold coins" divides this 6 and increase it in the table when it belongs to the message "gold coins". I hope you understand my point over here.

The purpose of this is to display the table values so I can do:

table["gold coin"] = 24

or

 table = {["item"]="count",}

so I can request the key. I really want a table that increases a key, rather than a regular table, but I just can't figure out how to do this...

thanks in advance

and if you can explain me every part of it I'll be really thankful :)

some other msgs :

{"11 gold coins", "a leather helmet", "meat", "a spear", "a gold coin"}
{"a gold coin"}

btw this program, which I'm using to do this its very restricted. All I can use for it, it's under the lua manual 5.1 link : http://www.lua.org/manual/5.1/manual.html

metatables aren't an option :/

1
Does loot return separate return values or a table that contains those things? - Nicol Bolas
its pretty much a return of i,j but im really bad explainin it so here it is : - Wesker
sure i had problems on the message so i added it in the first post, for a better understanding - Wesker
Can you format that with proper intention? - Nicol Bolas
well yes i can do whatever i want with loot() since i created it, to return this msgs, but i dont know what you ment with proper intention, it will return the content of every message thats the type im looking for from the server, and just give me the important stuff rather than the hour, and loot of x creature, so that function returns "just the loot" - Wesker

1 Answers

2
votes

The first thing you need is a function that extracts the numbers and items names from strings. The following one will read things like "a spear" or "11 spears" and return 1, "spear" and 11, "spear".

function parseAmountAndItem(str)
  assert(type(str)=="string", "Expected a string. Got a " .. type(str))
  -- handle "nothing"
  if str == "nothing" then return nil end
  local item, amount

  -- return 1 when it begins with a/an + space
  _,_,item = str:find("^an? (.+)$")
  if item then
    amount = 1
  else -- it should begin with a number + space + singular + s
    _,_,amount,item = str:find("^(%d%d?%d?%d?%d?) (.+)s$")
    assert(amount and item, "Could not parse the string: " .. str)
    amount = tonumber(amount)
  end
  return amount, item
end

Then you need to accumulate those values. This should work:

function accumulatedLoot()
  local result = {}
  local amount, item
  for _,row in ipairs(loot())
    for _,str in ipairs(row)
      local amount, item = parseAmountAndItem(str)
      if item then
        result[item] = (result[item] or 0) + amount
      end         
    end
  end

  return result
end

A couple warnings:

  • I've written all this by hand, without testing it. It will likely have some syntax errors and/or bugs.
  • I've assumed that the plural forms of all your items is the singular form + "s". Real English is much more complicated. You might need to store a table of irregular plurals and compare it with str instead of just removing the s like I'm doing in the code.