У меня есть несколько заметок, чтобы начать, прежде чем я конкретно отвечу на ваш вопрос. (Я просто хочу сделать это, прежде чем я забуду, поэтому, пожалуйста, потерпите меня!)
Я рекомендую печатать на терминал, используя stderr
вместо stdout
— функция Lua print
использует последнее. Когда я пишу Lua-скрипт, я часто создаю функцию в стиле C с именем eprintf
для вывода форматированного вывода в stderr
. Я реализую это так:
local function eprintf(fmt, ...)
io.stderr:write(string.format(fmt, ...))
return
end
Просто имейте в виду, что, в отличие от print
, эта функция не добавляет автоматически символ новой строки к выходной строке; для этого не забудьте поставить \n
в конце строки fmt
.
Далее может быть полезно определить вспомогательную функцию, которая вызывает io.read("*l")
для получения всей строки ввода. При написании примера кода, который поможет ответить на ваш вопрос, я назвал свою функцию getline
— как функцию C++, имеющую аналогичное поведение — и определил ее следующим образом:
local function getline()
local read = tostring(io.read("*l"))
return read
end
Если я правильно понимаю, что вы пытаетесь сделать, у игрока будет инвентарь, который вы назвали bag
, и он сможет помещать в него предметы, вводя названия предметов в stdin
. Так, например, если игрок нашел сундук с сокровищами с золотом, мечом и зельем и хотел взять это золото, он набрал Gold
в stdin
, и оно было помещено в его инвентарь.
Основываясь на том, что у вас есть, похоже, что вы используете таблицы Lua для создания этих элементов: каждая таблица имеет индекс name
, а другая называется ap
; и, если текст, введенный игроком, совпадает с названием предмета, игрок берет этот предмет.
Я бы порекомендовал создать класс Item
, который вы могли бы красиво абстрагировать, поместив его в собственный скрипт, а затем загружая его по мере необходимости с помощью require
. Это очень простой модуль класса Item
, который я написал:
----------------
-- Item class --
----------------
local Item = {__name = "Item"}
Item.__metatable = "metatable"
Item.__index = Item
-- __newindex metamethod.
function Item.__newindex(self, k, v)
local err = string.format(
"type `Item` does not have member `%s`",
tostring(k)
)
return error(err, 2)
end
-- Item constructor
function Item.new(name_in, ap_in)
assert((name_in ~= nil) and (ap_in ~= nil))
local self = {
name = name_in,
ap = ap_in
}
return setmetatable(self, Item)
end
return Item
Оттуда я написал основной драйвер, чтобы инкапсулировать некоторые из действий, которые вы описали в своем вопросе. (Да, я знаю, что мой код на Lua больше похож на C.)
#!/usr/bin/lua
-------------
-- Modules --
-------------
local Item = assert(require("Item"))
local function eprintf(fmt, ...)
io.stderr:write(string.format(fmt, ...))
return
end
local function printf(fmt, ...)
io.stdout:write(string.format(fmt, ...))
return
end
local function getline()
local read = tostring(io.read("*l"))
return read
end
local function main(argc, argv)
local gold = Item.new("Gold", 3)
printf("gold.name = %s\ngold.ap = %i\n", gold.name, gold.ap)
return 0
end
main(#arg, arg)
Теперь, что касается обратного поиска, который вы описали, на данный момент все, что вам нужно сделать, это сравнить ввод пользователя с именем Item
. Вот он в основной функции:
local function main(argc, argv)
local gold = Item.new("Gold", 3)
local bag = {}
eprintf("What are you trying to take? ")
local input = getline()
if (input == gold.name) then
table.insert(bag, gold)
eprintf("You took the %s.\n", gold.name)
else
eprintf("Unrecognized item `%s`.\n", input)
end
return 0
end
Надеюсь, это поможет!
person
Personage
schedule
11.12.2019