Таблица для расчета баланса игрока после постройки
Контекст проблемы
В решении про высокую семантическую точность я предположил, что не только таблицы, но и расчетные функции должны быть предельно специфичными. То есть, для “Пуэрто-Рико” как будто бы нужны функции, возвращающие новый баланс игрока после оплаты каждой возможной суммы, по одной функции на сумму оплаты.
В результате я написал несколько таких функций и понял, что их можно вообще-то выкинуть и переписать в табличном виде.
Варианты решения
Вариантов два:
- Оставить функции.
- (-) неявность расчета. Функции должны быть реализованы в коде, поэтому из таблиц не видно, что за логика выполняется, что и каким образом изменяется.
- (-) дублирование кода. Функции получились идентичными за исключением одного значения - на сколько уменьшить баланс игрока.
- Написать расчетную таблицу.
- (-) комбинаторика. В таблице должно быть столько правил, сколько может существовать комбинаций начального баланса и сумм покупки.
- (-) “тяжелый” расчет. Это следствие комбинаторики, текущий движок рассчитывает все правила таблицы, даже, если какое-то из условий позволяет откинуть некоторые из них.
- (+) не нужен код для определения нового баланса.
Выбранное решение
Все равно остановился на расчетной таблице :) явность логики и возможность не писать серверный или клиентский код для расчета победили.
Последствия
- нужно определить диапазон значений начального баланса (верхнюю границу), которые будут включены в таблицу. Уже не помню, как там складывалась ситуация в игре, но для начала взял 15 монет. То есть, в таблице нужно отразить все комбинации из начального баланса (1-15 монет) и стоимости покупки (1-10 монет);
- можно пропустить невозможные правила, приводящие к отрицательному балансу, поскольку цель таблицы - рассчитать итоговое значение, а оно не может быть отрицательным;
- предыдущий пункт подразумевает, что нужно проверять возможность покупки не в этой таблице, а где-то еще, лучший кандидат - таблицы с правилами покупки конкретных зданий;
- уже созданные таблицы покупки зданий нужно переписать с использованием новой таблицы получения баланса.
Результат
Таблица получилась вот такой (фрагмент):
CND ;${name-to-id::id}::coins ;15 ;15 ; ..... ;15 ;14 ; ..... ;14 ; .....
CND ;temp::price ;10 ; 9 ; ..... ; 1 ;10 ; ..... ; 1 ; .....
OUT ;new-balance ; 5 ; 6 ; ..... ;14 ; 4 ; ..... ;13 ; .....
Называется она coins
, поэтому получить значение из нее можно с помощью записи coins::new-balance
.
В этом расчете я использую значение из temp::price
- это своего рода “аргумент функции”. Вычисления
на таблицах имеют свои особенности, например, в таблицу нельзя передать аргумент при вызове, поэтому
приходится использовать вот такие “ассемблерные” трюки - перед вызовом записать нужное значение в
какой-то временный “регистр”, а затем считать это значение в таблице.