MOCHET [7] 
27.07.2018 02:47
 0просмотров 21 4

Очень простая оценка карт


Для начала рассмотрим несколько желаемых качеств и утверждений, которыми должна обладать оценка карт и комбинаций или какой-то ИИ для аркомага.

Этот список пока ещё не полный и будет пополнятся.

- если карта или комбинация из карт даёт в течении периода хождения одного персонажа 100%-ую победу, то score (оценка) должен быть максимальный
- если даёт именно нам поражение, то score должен быть 0-вым или бесконечно негативным
- нужно не давать сопернику победить за один ход
- если у нас нет карты сдвиг, то нужно иметь стену всегда чуть-чуть выше чем у противника (т.е. всегда выше нуля), но не настолько высокой, чтобы для него было выгодно поменять стены местами. Зачастую выгодно иметь стену выше чем у противника.
- Если комбинация карт состоит из нескольких раздельных ходов, где играем мы (1.1), потом противник (2.1), потом снова мы(1.2), потом снова противник (2.2), то комбинация не должна быть длиннее чем 2-3 хода (и ходами притивника между ними). Также следует давать какой-то мелкий штраф (или может даже бонус?) за то что ходим в течении нескольких ходов и преследуем какую-то цель
- Играть эффициентно, стараться например использовать карты, где можно максимировать выгоду в зависимости от ситуации или находить и использовать по мере надобности undervalued cards (про это я писал в теме с least squares)
- стараться в разумных рамках фармить ресурсы (resources) и строить предприятия (facilities)
- scoring (оценка) карт в зависимости от ситуации на столе
- scoring (оценка) для игровой ситуации вообщем (руда, мана, шахты, стены, башни, ...)

Спорные идеи
- score(play card) > score(drop card) (для большинства ситуаций)
- score(direct damage) > score(tower damage)
- score(direct damage) > score(wall damage)

Можно выделить 3 типа урона среди карт
- карты, где урон всегда только по башне: tower damage
- карты, где урон всегда только по стене: wall damage
- карты, где урон без всяких условий - им можно нанести урон и башне и стене, назовём его: direct damage
Отчасти об этом я писал уже здесь: Cards damage (conditional cards+exploitable effects)



Для того чтобы начать вообще с чего-либо начнём с очень простой модели.

Рассмотрим какими способами можно победить в аркомаге напрямую используя карты:
1. победа через постройку башни (T1 >= MAX, где T1 это наша башня (мы игрок #1), а MAX это высота башни для победы)
2. победа через разрушение башни противника (T2 <= 0, где T2 это башня противника (игрок #2))
3. победа через фарм ресурсов (RES1 >= MAX, где RES1 это наши ресурсы, а MAX количество ресурсов нужное для победы)

Победа через таймаут не учитывается, т.к. её не достичь играя картами. Это отдельный случай, который нас пока не интересует.

Пока что не учитываем вес каждого типа победы. Хотя это можно учесть в будущем. Вес может например зависеть от того как часто побеждают через определённый тип победы. Такие данные можно либо собрать статистически (Можно посмотреть например здесь), либо можно минуя статистику напрямую вывести через начальные условия и распределение эффектов у всех карт (например больше карт на постройку башен и стен чем на разрушение и так далее).

Можно представить себе 3 типа победы как шкалы в системе координат.
X: "Т-2-0" - разрушение башни противника
Y: "T-1-MAX" - постройка нашей башни
Z: "RES-1-MAX" - накопление ресурсов

Графически можно представить себе примерно вот так


Теперь скажем, что эффекты карт находятся где-то в этой системе коордиант, т.е. каждую карту можно представить себе как точку в этом системе (в будущем можно пойти и дальше и начать оперировать картами как векторами, но пока не будет забегать вперёд).

Естественно наша модель пока хромает, как минимум по следующим пунктам:
- не учитывается стена, а она защищает башню от типа урона direct damage
- не учитывается постройка или разрушение предприятий (facilities)
- модель не видит напрямую комбинации из карт. нам придётся суммировать эффекты комбинаций и стоимость (комбинация из карт это по сути наша стратегия) и считать как одну карту, но в принципе это не настолько большая проблема, как два пункта выше.

Теперь постараемся описать нашу идею математически, т.е. построить какой-то простейший scoring на основе этой идеи.



Идея такая:
Мы смотрим какой из эффектов даёт больший вклад в победу какого-либо типа. Максимальный эффект и определяет оценку карты.

Результат каждой отдельной оценки всегда между 0 и 1.
Если score равен 1, это значит, что карта приводит к победе.

Вспомогательные функции h и g


Тета это какой-либо threshold (порог), который мы задаём. Например макс. башня или макс. ресурсы.


Тета 1 и Тета 2 это два каких-либо порога.

Теперь рассмотрим каждый случай раздельно (scoring для каждого типа победы):

1. Победа через разрушение башни пртивника (X)



Тета 1 в данном случае является 0, т.е. если карта делает так, что мы может разрушить башню противника (и её высота будет равнятся нулю или ниже).
Тета 2 в данном случае является высотой башни нужной для победы. Напомню, что нам нужен score между 0 и 1.

Пример:



Получаем score 0.2, при этом 40 это высота башни после применения карты.
Наверное лучше было бы использовать разницу двух оценок: Высота башни до применения карты и после. Разница и будет оценкой.

2. Победа через постройку нашей башни (Y)



Тета в данном случае является башней нужной для победы (Например в столице 50).

3. Победа через фарм ресурсов (Z)



Z состоит из трёх компонентов: ore, mana, stacks (руда, мана, отряды).
Тета это количество ресурсов нужных для победы. Т.к. для победы нужно собрать каждого вида ресурса по максимуму, то просчитываем отдельный score для руды, маны и отрядов.



Примечания
- Ситуация на столе имплицирует и scoring какой-то карты в данный момент
- Недостатки данного типа оценки описаны наверху (стена и предприятия не учитываются). Стена защищает башню, но не во всех случаях. А вот ресурсы нужны всегда, поэтому нужно строить "предприятия" (шахты, монастыри, казармы). Т.к. копить до макс.ресурсов очень долго, то оценка решит, что лучше либо разрушить башню противнику либо построить свою. И будет считать что не надо фармить ресурсы вообще. В конце концов ресурсы закончатся и будем в тупике.
- Можно подумать ещё над weighted scoring, т.к. распределение эффектов у карт разное. Например много карт для постройки башни.
- Можно подумать сделать вторую систему координат для противника
- Можно экспериментировать с подобными системами координат и оценками для других вещей: Например для трёв видов ресурсов (X: руда, Y: мана, Z: отряды), чтобы задать приоритет фарма, при этом можно сделать плавающий порог. и т.д.
Комментарии
1 / 27.07.2018 08:46 / Небылица [16] ?
Чтобы не было
Цитата
оценка решит, что лучше либо разрушить башню противнику либо построить свою. И будет считать что не надо фармить ресурсы вообще. В конце концов ресурсы закончатся и будем в тупике.
, можно добавить дополнительные шкалу (шкалы) по ресурсам и откатывать по ним в отрицательном направлении в размере стоимости
И поставить искуственный порог псевдопоражения при приближении к какому-то значению (возможно, зависящему от хода или накоплений противника, чтобы не начинать паниковать в начале партии)
Кстати, при таком подходе не нужна отдельная шкала для победы по ресурсам, тк можно суммировать значения по отдельным

В сущности, можно вообще всю игру представить в виде 16-мерного пространста (свои/чужие ресы/приросты и башня/стена), вектор в котором будет однозначно соответствовать каждой карте (причём с учётом стоимости)
Ну почти однозначно, есть ещё "играем снова"

Трёхмерное пространство со шкалами по типам побед, конечно, смотрится изящнее, но в него надо как-то впихивать множество эффектов карт, проводя их оценку
Чтобы вектор в направлении побед реально соответствовал эффекту
А большое пространство, считай, и есть оценка
Ну, по крайней мере численное представление
2 / 27.07.2018 09:01 / Небылица [16] ?
Ещё по-хорошему надо ввести некий дефолтный вектор, перерасчитываемый на каждом ходу и общий дя всех карт текущего хода
Который отвечал бы за прирост
И с ним складывать все номинальные эффекты карт
Чтобы не получилось, что, скажем, ты мог сбросить карту и победить по ресам или просто накопить на что-нибудь нужное, а заюзал что-то не особо толковое
Правда для учёта нужного нужно вводить какой-то доп. коэфф при наличии сильной карты, на которую имеет смысл копить, если эффекты всех текущих карт не покрывают затрат

И ещё ХЗ, как учитывать, что значение имеют и свои, и чужие ресы, но изменение происходит на разных ходах + противник может влиять посередине
Грубо говоря, ты сбрасываешь карту в расчёте на накопление ресов
Но после своего хода ты их не получаешь, это только пол-шага
Потом ещё ходит противник, который тоже может что-то сделать с твоими ресами, что ты должен предсказать заранее
3 / 27.07.2018 15:02 / MOCHET [6] ?
Цитата: Небылица
Чтобы не получилось, что, скажем, ты мог сбросить карту и победить по ресам или просто накопить на что-нибудь нужное, а заюзал что-то не особо толковое
Правда для учёта нужного нужно вводить какой-то доп. коэфф при наличии сильной карты, на которую имеет смысл копить, если эффекты всех текущих карт не покрывают затрат
Здесь нужна дополнительная функция, которая будет смотреть - можно ли ускорить время ожидания карты
Есть у нас например карта Дракон (20 урона, -10 маны, -1 казарма у врага), но совсем не хватает ресурсов
- можно либо ждать, и не пользоваться зелёными картами
- либо стараться использовать какие-то карты, которые строят казармы либо дают отряды.
(если не хватает ресурсов на эти карты, можно пытаться рекурсивно искать карты для тех карт, чтобы ускорить)
и наооборот для противника, чтобы не дать ему сыграть какой-то картой.


Цитата: Небылица
В сущности, можно вообще всю игру представить в виде 16-мерного пространста (свои/чужие ресы/приросты и башня/стена), вектор в котором будет однозначно соответствовать каждой карте (причём с учётом стоимости)
Ну почти однозначно, есть ещё "играем снова"
хорошая идея. над этим нужно будет подумать...
сейчас так спонтанно не вижу ещё минусов или плюсов
вернее, да плюсы есть, потому что всё в одной системе координат представить
но может быть есть что-то ненужное


Цитата: Небылица
Грубо говоря, ты сбрасываешь карту в расчёте на накопление ресов
Но после своего хода ты их не получаешь, это только пол-шага
Потом ещё ходит противник, который тоже может что-то сделать с твоими ресами, что ты должен предсказать заранее
да, это очень нехорошая ситуация
но это уже часть игры :)
поэтому лучше иметь план Б и В и Г :), если противник запорол нам всю стратегию, чтобы хоть как-то амортизировать этот нехороший эффект
4 / 27.07.2018 15:13 / MOCHET [6] ?
Цитата: Небылица
В сущности, можно вообще всю игру представить в виде 16-мерного пространста (свои/чужие ресы/приросты и башня/стена), вектор в котором будет однозначно соответствовать каждой карте (причём с учётом стоимости)
Ну почти однозначно, есть ещё "играем снова"
я как понимаю функции оценки будут примерно одинаковые что и сейчас?
там же ещё больше всего....
нужно посмотреть как это всё в одно связать можно.
намного же больше параметров, которые нужно учесть


Цитата: MOCHET
да, это очень нехорошая ситуация
но это уже часть игры :)
поэтому лучше иметь план Б и В и Г :), если противник запорол нам всю стратегию, чтобы хоть как-то амортизировать этот нехороший эффект
а вот можно было бы встроить ещё каким-то способом ожидание, что придёт какая-то карта
т.е. привязать к кулдауну
насколько это реализуемо и даёт какой-то весомый эффект - это отдельный вопрос

Возможность комментировать доступна после регистрации