Урожай и рынок
Грядка созрела, когда она росла столько дней, сколько нужно её культуре. Тогда Эмма собирает урожай: каждое семя даёт одну единицу урожая, и урожай отправляется в сарай. А грядка начинает расти заново с 0: на ферме Эммы после сбора урожая каждая грядка снова растит свою культуру.
Сарай — это словарь. Его ключи — названия культур, а значения говорят, сколько их лежит в сарае. Добавлять в него — это приём подсчёта из урока про словари: barn[name] = (barn[name] or 0) + plot.seeds. В первый раз barn[name] равно nil, и or 0 превращает его в 0. Без этого программа останавливается на самом первом сборе урожая:
main.lua:95: attempt to perform arithmetic on a nil value (field '?')Вопросительный знак стоит потому, что ключ — не имя, написанное в коде, а значение переменной name. И остерегайтесь barn.name: это ключ "name", а не название культуры, поэтому все культуры оказались бы под одним ключом.
Собирайте урожай с грядки сразу после того, как её описание попало в список дня. Тогда в строке в день сбора будет морковь 3/3, а на следующий день — морковь 1/3. Если собрать урожай до описания, будет морковь 0/3.
В конце сезона Эмма относит всё, что лежит в сарае, на рынок. Функция sell(barn) выводит одну строку со всеми культурами, их количеством и ценой одной единицы, а также итог. Затем она возвращает итог, и главная программа прибавляет его к монетам. Культуры должны идти по алфавиту. Но pairs обходит словарь в произвольном порядке, который может даже меняться от запуска к запуску. Поэтому сначала соберите ключи в список и отсортируйте его, как в уроке про словари. Например, яйца, подсчитанные по курице, которая их снесла:
local laidBy = {"Перчинка", "Златка", "Перчинка"}
local counts = {}
for _, hen in ipairs(laidBy) do
counts[hen] = (counts[hen] or 0) + 1
end
local names = {}
for name in pairs(counts) do
table.insert(names, name)
end
table.sort(names)
for _, name in ipairs(names) do
print(name, counts[name])
endОн выведет:
Златка 1
Перчинка 2В вашей программе отдельная функция sortedNames(t) будет возвращать отсортированный список ключей словаря. Затем sell проходит по sortedNames(barn) с помощью ipairs и для каждого названия берёт цену культуры через findCrop. Поставьте обе функции под describePlot: sell вызывает findCrop, поэтому она должна стоять ниже неё.
Задание
- 1
В главной программе создайте пустой словарь
barnнад циклом по дням. Во внутреннем цикле, под строкой, которая добавляет описание грядки в список, соберите урожай с грядки, если она созрела: добавьте её семена в сарай под названием культуры и верните еёgrownобратно в0. Теперь дни выглядят так:Монеты: 6 День 1 (солнечно): морковь 1/3, пшеница 1/2, тыква 1/6 День 2 (солнечно): морковь 2/3, пшеница 2/2, тыква 2/6 День 3 (дождливо): морковь 3/3, пшеница 2/2, тыква 4/6 День 4 (облачно): морковь 1/3, пшеница 1/2, тыква 5/6 День 5 (солнечно): морковь 2/3, пшеница 2/2, тыква 6/6Если у грядки
0/3вместо3/3, вы собираете урожай раньше, чем описываете грядку. - 2
Под
describePlotнапишите функциюsortedNames(t), которая с помощьюpairsсобирает ключи словаряtв список, сортирует его с помощьюtable.sortи возвращает. - 3
Под ней напишите функцию
sell(barn). Для каждого названия изsortedNames(barn)она составляет строку вродеморковь 8 x 5(название, количество в сарае и цена на рынке) и прибавляет к итогу количество, умноженное на цену. Затем она выводит одну строку:Рынок:, строки, соединённые через", ", знак равенства и итог, напримерРынок: морковь 8 x 5, пшеница 18 x 3 = 94, и возвращает итог. - 4
В конце главной программы прибавьте к
coinsто, что вернётsell(barn), и выведите монеты в конце сезона. Программа заканчивается так:День 5 (солнечно): морковь 2/3, пшеница 2/2, тыква 6/6 День 6 (облачно): морковь 3/3, пшеница 1/2, тыква 1/6 Рынок: морковь 8 x 5, пшеница 18 x 3, тыква 2 x 20 = 134 Конец сезона. Монеты: 140Эмма продала морковь с двух сборов (4 + 4) и пшеницу с трёх (6 + 6 + 6).