|
•Третий вариант - Artlav, 09.02.2011 21:08:10 |
|
|
Во-превых, я наверное поспешил просить крепко задумываться, так как постановка меняется раз в 12-24 часа по мере моего обдумывания задачи.
Во-вторых, вторая ветка обсуждения тут - http://www.gamedev.ru/code/forum/?id=143859
В третьих, вот третий вариант алгоритма и задачи. Сейчас я пытаюсь продумать алгоритм непосредственно рассчёта потребления по списку связанных юнитов.
Предпосылки: -Есть квадратная сетка, на ней стоят здания (=юниты) -Если здания в соседних клетках, то они связаны и могут передавать ресурсы -Если между двумя зданиями есть цепочка связанных зданий, то они связаны -Ресурс задаётся как нечто, что можно потребить, создать и (опционально) хранить. -Ресурсы тратятся в момент конца хода, до этого они должны быть учитываемыми - т.е. если включить завод, то нужно уже знать что ему хватит железа и энергии, но сам забор происходит только в конце хода. -Распределение = активность данного алгоритма если глагол, и состояние на данный момент если сущ. (кто у кого что берёт, если взорвать забор на отшибе, то распределение не меняется, а если трубу между двумя комплексами - то меняется)
-Обработка возможно как по временной схеме без изменений (для запросов), так и по постоянной с записью изменений -У юнита есть единое состояние включенности, при котором он потребляет и производит, это состояние может быть константой (невыключаемый юнит) или переменной -Потребляющий юнит не может быть невыключаемым -Чисто производящий юнит может быть невыключаемым -У юнита есть приоритет (есть или нет, два варианта) -Хранение и долги юнит даёт всегда, отказаться нельзя (нельзя закрыть склад или перекрыть трубу) -Проводимость у юнита постоянная (проводит либо не проводит)
-Все ситуации и события считать в пределах одного домена (ниже), конец хода перебирает все домены
Данные: -У каждого юнита для каждого ресурса хранится рабочая и временная структуры: --=num Емкость хранилища --=use Потребить в этом ходу --=next_use Потребить на следующем ходу (строитель может иметь непостоянное потребление, при просчёте конца хода это надо учесть) --=now Имеется на борту --=pro Произвести за этот ход --=dbt Долг за этот ход, необходим чтобы определить, а можем ли мы включить что-то --=isact Включенность
-Каждое здание хранит в себе номер домена (комплекса), который обновляется при соответствующих событиях созидания и разрушения (вне проблемы данной задачи, считать всегда правильными) -По определению все здания в одном домене связаны, все здания с разными доменами не связаны -Номер домена не имеет географической или игроковой привязки, это величина, объединяющая связанные на данный момент группы юнитов конкретным идентификатором
События игры: -Создан юнит --=Выключенный или постоянно производящий, включение - отдельное событие, у постоянно включенного то же, но сразу после создания --=Может изменить связность, но не влияет на распределение --=Ничего менять не надо
-Убран юнит --=Взорван, вероятна потеря связности. Нужно обновить от всех, кто рядом с ним --=Вырублен диверсантом, не потеряна связность. Нужно обновить от него
-Запущен юнит --=Запросить возможность включения, запрос идёт по временной схеме --=В случае успеха повторить на основной схеме или скопировать в неё --=В случае неуспеха не запускать, сообщить игроку чего не хватило
-Остановлен юнит --=Запросить возможность остановки, по временной схеме --=В случае успеха повторить на основной схеме или скопировать в неё --=В случае неуспеха не останавливать, сообщить игроку чего не хватит
-Изменено потребление/производство юнита --=Запросить разницу как запрос добавления/остановки, по временной схеме. Один ресурс за событие --=В случае успеха повторить на основной схеме или скопировать в неё
-Заменён юнит (удалён-создан без изменения связности, например здание построено на трубах) --=Ресурсы не задействованы, удалить и создать без запросов к распределителю
-Передача материалов --=Проверить на связность, если да - то передать долг вместе с материалом, если нет, то следующий такт. --=Если долг превышает остаток+производство, то сделать долг равным производству и обновить, иначе ничего не делать
Обновление: -Возможные конечные ситуации: --=Всё ОК --=Долги остались, потребитель пропал --=Потребление осталось, долги пропали -Решение: --=Суммировать всё потребление и суммировать все долги --=Вычесть из долгов потребление, остаток долга освободить или избыток добавить (запрос добавления долга по временной схеме) --=При нехватке производства последовательно по возрастанию приоритета искать потребляющий юнит с наименьшим производством и останавливать, повторяя запрос на добавление долга --=При успешности запроса на добавление долга записать его в постоянную схему
Конец хода: -Требования: --=Нужно удовлетворить потребности --=Нужно остановить тех, кто не получил по потребностям --=Нужно положить избыток в хранилища (возможно, что произведено больше, чем влезет, но будет потрачено и влезет) --=Нужно обновить потребления у производителей --=Всё должно быть целостным -Решения: --=Перебирать последовательно все домены --=Предположить что всё обновлено, либо вызвать обновление. --=Произвести всё, доложить в хранилища не учитывая их размера --=Вычесть все свои долги, из хранилищ. Производство учитывается переполнением хранилищ --=Отсечь избыток из хранилищ, распределив его по остальным и выбросив не влазящее (запрос на немедленную клажу в себя распределит по соседям избыток, и вернёт остаток что не влез - его удалить) --=Пересчитать потребление - продвинуть на шаг строительство, и т.п. (use=next_use, обеспечить корректность next_use до вызова конца хода) --=Обновить
Функции: -Обновить -Конец хода -Передача
-Запрос на добавление ресурса немедленно --=Не меняет балансировку --=Перебрать всех в домене, кладя по мере нахождения пустот, выйти при иссякании запроса, или вернуть не доложенное как результат
-Запрос наличия: --наличия ресурса (сумма хранения) --наличия свободного места (сумма пустоты) --наличия свободного долга (сумма производства и хранения) --наличия свободного ресурса (хранение минус max(0,(долг минус производство))) --=Перебрать всех в домене, суммируя требуемое, и вернуть сумму как результат
-Запрос на добавление долга --=Перебрать всех в домене по временной схеме, добавляя долг --=Если не хватит, то откатить и начать поиск объекта для запуска, запустить его, и вернуться в начала --=Если хватило, то перенести временное в постоянное, иначе вернуть отказ --=Что если хватило одного ресурса, но не второго? Электростанции останутся запущенными, и всё?
-Запуск юнита (нужно думать): --=Проверить необходимость потребления, если нет, то всё --=Если есть потребление, то по отдельности на каждый ресурс запросить долг по временной схеме --=Если хватило, то запросить долг по основной
-Остановка юнита: --=Если нет производства, то освободить потребление и всё --=Если есть производство, то по временной схеме запросить эквивалентное число долгов (исключая себя) --=Если хватило, то выключится и запросить по основной схеме, освободить потребление, и готово
Проблемы: Раздельность: -Если обновлять ресурсы по отдельность, то как гарантировать то, что обновление одного не угробит обновление другого? -Как решить задачу оптимизации по потреблению? Если надо выключить юнит, который снабжает другие юниты? (две станции, мало бензина. Которую гасить?)
|
|
ответы :
-
Третий вариант. Мысли. Раздельность. - Burn, 09.02.2011 23:28:15
-
Но это требует... - Artlav, 09.02.2011 23:54:35
-
Зато это работает. - Burn, 10.02.2011 0:33:39
-
Отв: Зато это работает. - Artlav, 10.02.2011 0:45:10
-
Отв: Отв: Зато это работает. - Burn, 10.02.2011 1:20:44
-
Верю. - Artlav, 10.02.2011 1:36:33
-
Третий вариант. Вопросы. Терминология. - Burn, 10.02.2011 0:16:57
-
Отв: Третий вариант. Вопросы. Терминология. - Artlav, 10.02.2011 1:07:21
-
Терминология. - Burn, 10.02.2011 1:58:25
-
Отв: Терминология. - Artlav, 10.02.2011 8:24:26
-
Терминология & Подход - Burn, 10.02.2011 11:10:33
-
Дискретность задачи - Artlav, 10.02.2011 11:48:39
|
| |