Я играю в игру, в которой есть компонент для ковки оружия, где вы комбинируете два оружия, чтобы получить новый. Огромное количество комбинаций оружия (см. "6.1. Таблицы комбинаций лезвий" на http://www.gamefaqs.com/ps/914326-vagrant-story/faqs/8485) затрудняет определение того, что вы в конечном итоге можете создать из своего текущего оружия через повторную ковку, поэтому я попробовал написать программу, которая сделает это для меня. Я даю ему список оружия, которое у меня есть, например:
- Francisca
- tabarzin
- крис
и он дает мне список всех видов оружия, которые я могу подделать:
- шаровая булава
- chamkaq
- кортик
- Francisca
- большой полумесяц
- метательный нож
Проблема в том, что я использую алгоритм грубой силы, который очень мало масштабируется; требуется около 15 секунд, чтобы рассчитать все возможные виды оружия для семи пусковых вооружений и несколько минут, чтобы вычислить восемь стартовых орудий. Я бы хотел, чтобы он мог вычислить до 64 единиц оружия (максимум, что вы можете держать одновременно), но я не думаю, что буду жить достаточно долго, чтобы увидеть результаты.
function find_possible_weapons(source_weapons)
{
for (i in source_weapons)
{
for (j in source_weapons)
{
if (i != j)
{
result_weapon = combine_weapons(source_weapons[i], source_weapons[j]);
new_weapons = array();
new_weapons.add(result_weapon);
for (k in source_weapons)
{
if (k != i && k != j)
new_weapons.add(source_weapons[k]);
}
find_possible_weapons(new_weapons);
}
}
}
}
По-английски: Я пытаюсь использовать каждую комбинацию из двух видов оружия из своего списка источников оружия. Для каждой из этих комбинаций я создаю новый список всех видов оружия, которые у меня были бы после этой комбинации (т.е. Новое комбинированное оружие плюс все исходное оружие, кроме двух, которые я объединил), а затем повторяю эти шаги для нового списка.
Есть ли лучший способ сделать это?
Обратите внимание, что объединение оружия в обратном порядке может изменить результат (Rapier + Firangi = Short Sword, но Firangi + Rapier = Spatha), поэтому я не могу пропустить эти развороты в цикле j
.
Изменить: Здесь приведен пример тестового примера, который я дал выше, чтобы показать, что делает алгоритм. Строка в скобках показывает результат комбинации, а следующая строка - новый список оружия, созданного в результате:
francisca,tabarzin,kris
[francisca + tabarzin = chamkaq]
chamkaq,kris
[chamkaq + kris = large crescent]
large crescent
[kris + chamkaq = large crescent]
large crescent
[francisca + kris = dirk]
dirk,tabarzin
[dirk + tabarzin = francisca]
francisca
[tabarzin + dirk = francisca]
francisca
[tabarzin + francisca = chamkaq]
chamkaq,kris
[chamkaq + kris = large crescent]
large crescent
[kris + chamkaq = large crescent]
large crescent
[tabarzin + kris = throwing knife]
throwing knife,francisca
[throwing knife + francisca = ball mace]
ball mace
[francisca + throwing knife = ball mace]
ball mace
[kris + francisca = dirk]
dirk,tabarzin
[dirk + tabarzin = francisca]
francisca
[tabarzin + dirk = francisca]
francisca
[kris + tabarzin = throwing knife]
throwing knife,francisca
[throwing knife + francisca = ball mace]
ball mace
[francisca + throwing knife = ball mace]
ball mace
Также обратите внимание, что повторяющиеся элементы в списке оружия значительны и не могут быть удалены. Например, если я добавлю второй крис в свой список начального оружия, чтобы у меня был следующий список:
- Francisca
- tabarzin
- крис
- крис
то я могу подделать следующие элементы:
- шаровая булава
- боевой топор
- боевой нож
- chamkaq
- кортик
- Francisca
- крис
- Kudi
- большой полумесяц
- scramasax
- метательный нож
Добавление дублированного криса позволило мне создать четыре новых элемента, которые я раньше не мог. Он также увеличил общее количество тестов кузницы до 252 для списка из четырех предметов, по сравнению с 27 для списка трех элементов.
Изменить: У меня возникает ощущение, что для решения этого потребуется больше знаний по математике и информатике, чем у меня, поэтому я собираюсь отказаться от него. Сначала это казалось довольно простой проблемой, но затем, так же, как и Путешественник. Я согласен с ответом Дэвида Эйзенстата, поскольку предложение запомнить и пропустить дубликаты списков элементов сделало такую огромную разницу во времени исполнения и похоже, что оно применимо к множеству подобных проблем.