Объявления
Поздравляем
Roman2211


Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

Улучшение ИИ

Герои Меча и Магии III: Возрождение Эрафии, Герои Меча и Магии III Дыхание Смерти, Герои Меча и Магии III Клинок Армагеддона, Герои Меча и Магии III Хроники Героев
offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 10 май 2020, 17:25

Было бы очень полезно сделать самую простейшую реализации Берсерка для ИИ.
Без сложных расчетов, даже просто на случайный стек противника.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Улучшение ИИ

Сообщение Ben80 » 10 май 2020, 18:06

)))
Анатолий, расчет, который я привел - он не сложный. Адекватный алгоритм для ИИ Берсерка будет сложнее на порядок.
На самом деле нам не достаточно получить набор битов в 0x544. Ведь нужно знать именно ближайший стек, к которому пойдет стек, на который наложен Берсерк. То есть нужно воспроизвести в точности ту механику, которая происходит при применении заклинания. Но только в расчетах, естественно, без применения.

Но начинать нужно с простейшей реализации (не реализации даже, по сути, а черновика) Берсерка - тут полностью с тобой согласен. То есть для начала было бы удовольствием просто посмотреть, как ИИ применяет Берсерк.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Улучшение ИИ

Сообщение Ben80 » 11 май 2020, 03:21

Может кто-нибудь прокомментировать, что происходит в функции действия монстра под Берсерком ?

Код: Выделить всё
//----- (00422440) --------------------------------------------------------
char __thiscall Battle_UnderBerserk_SelectMeeleeAction(_BattleMgr_ *this, _BattleStack_ *a2, int MonPo)
{
  int v3; // ebx
  _BattleStack_ *v4; // edi
  _BattleMgr_ *v5; // esi
  signed int v6; // eax
  int v7; // eax
  int v8; // ecx
  int v9; // ecx
  int v10; // ebx
  int v11; // eax
  int v12; // ebx
  int monster; // [esp+14h] [ebp+8h]
  int thisa; // [esp+18h] [ebp+Ch]
  int thisb; // [esp+18h] [ebp+Ch]

  v3 = MonPo;
  v4 = a2;
  v5 = this;
  a2->field_10 = *(_DWORD *)(MonPo + 244);
  a2->field_14 = *(_DWORD *)(MonPo + 248);
  thisa = *(_DWORD *)(MonPo + 56);
  v6 = thisa;
  if ( thisa >= 0 && thisa < 187 )
  {
    if ( thisa % 17 && thisa % 17 != 16 || !(*(_BYTE *)(v3 + 132) & 1) )
      v6 = thisa;
    else
      v6 = BattleStack_GetSecondOccupedGexNum((_BattleStack_ *)v3);
  }
  AIMgr_Stack_SetHexes_WayToMoveLength(AccessableSquaresStruct, a2, -1, v6, LOBYTE(v5->Tactics), 127, -1);
  LOBYTE(v7) = (_BYTE)AccessableSquaresStruct;
  v8 = *((_DWORD *)AccessableSquaresStruct + 19);
  if ( v8 && (*((_DWORD *)AccessableSquaresStruct + 20) - v8) & 0xFFFFFFFC )
  {
    v9 = *((_DWORD *)AccessableSquaresStruct + 19);
    if ( v9 && ((*((_DWORD *)AccessableSquaresStruct + 20) - v9) & 0xFFFFFFFC) == 4 )
    {
      v5->Action = 6;
      v7 = a2->hex_ix;
      v5->ActionParam = v7;
      v5->ActionTarget = *(_DWORD *)(v3 + 56);
      v10 = *(_DWORD *)(v3 + 244);
      if ( v10 == a2->Side )
        v5->gap53DC[v10] = 1;
    }
    else
    {
      v11 = *((_DWORD *)AccessableSquaresStruct + 9);
      monster = (signed __int16)(**(_WORD **)(*((_DWORD *)AccessableSquaresStruct + 19) + 4) << 6) >> 6;
      if ( v11 )
        thisb = v11 + 30 * *(_DWORD *)(v3 + 56);
      else
        thisb = 0;
      v7 = BattleStack_GetSpeed(v4);
      if ( *(unsigned __int16 *)(thisb + 24) <= v7 )
      {
        v5->Action = 6;
        v5->ActionParam = monster;
        v5->ActionTarget = *(_DWORD *)(v3 + 56);
        v12 = *(_DWORD *)(v3 + 244);
        if ( v12 == v4->Side )
          v5->gap53DC[v12] = 1;
      }
      else
      {
        v4->field_10 = -1;
        v4->field_14 = -1;
        LOBYTE(v7) = AI_Battle_Move(v5, (int)v4, monster, 0, 0);
      }
    }
  }
  else
  {
    v5->Action = 12;
  }
  return v7;
}
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Улучшение ИИ

Сообщение Ben80 » 11 май 2020, 05:53

Универсальная (некостыльная) функция для расчета предпочтения ИИ опыта/денег. Почему универсальная ? - потому что не заставляет ИИ что-то жестко делать/выбирать, а исходит из реальной ситуации (например, ситуации острой нехватки у ИИ денег). Таковыми в идеале должны быть все изменения по ИИ.
Справедливости ради - получилась не на 100% универсальная функция (то есть имеет место "полукостыльность"). В функции сравнивается значение "выгоды от опыта", полученное по новой формуле и по старой (оригинальной). Выбирается большее значение. Написание единой хорошей универсальной функций потребовало бы достаточно много усилий.

Код: Выделить всё
int __stdcall AIPreferExpoThanGold(LoHook* h, HookContext* c)
{
   _Hero_* hero = (_Hero_*)c->esi;

   int needExpo = CALL_1(int, __fastcall, 0x4DA690, hero->level);
   int expoProfit = *(float*)(c->ebp + 0xC) * 3000 / needExpo;
   if(expoProfit > c->eax && c->edi == 6) // only gold + use old formula if bigger
      c->eax = expoProfit;

    return EXEC_DEFAULT;
}
...
_PI->WriteLoHook(0x5284E3, AIPreferExpoThanGold);
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 11 май 2020, 07:16

Интересно, а почему зеленый ИИ не забирает город без охраны?
 
Изображение

В AICalculateMapPosWeight увеличиваю вес города в 7, до 2000000 все равно не берет.
Берет только если увеличить вес в 100 раз.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Улучшение ИИ

Сообщение Ben80 » 11 май 2020, 07:18

Прекрасный повод для исследования ! Попробуй докопаться, почему получается маленькое значение Value (до увеличения в 100 раз).
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 11 май 2020, 07:31

Так в том-то и дело, что вес даже без моего умножения = 300 000, это точно наибольший вес среди всех объектов для этого героя.
Все остальные веса в районе 1000.
Проверил вообще без всех моих изменений - город также не берется.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Улучшение ИИ

Сообщение Ben80 » 11 май 2020, 07:36

Значит нужно посмотреть, какое Value получается на выходе из AICalculateMapPosWeight - может быть, какой-то другой объект получает очень большое значение.

as239 писал(а):

это точно наибольший вес среди всех объектов для этого героя.


Все таки это нужно уточнить.
Есть, конечно, еще вариант, что он просто не видит этот город, но ты написал, что в итоге заставил его взять этот город. При желании докопаться до причины всегда возможно.
Вернуться к началу

offlineas239  
имя: Анатолий
Ветеран
Ветеран
 
Сообщения: 527
Зарегистрирован: 29 дек 2018, 14:17
Пол: Мужчина
Поблагодарили: 38 раз.

Re: Улучшение ИИ

Сообщение as239 » 11 май 2020, 07:38

Так именно это я и проверил - наибольшее значение у города.
Видимо после этой функции есть еще какая-то где может быть принято решение независимо от веса.
Буду смотреть.
Самое интересное что в итоге он идет и забирает шахту руды, пропустив два пустых города соперника!
Последний раз редактировалось as239 11 май 2020, 07:40, всего редактировалось 1 раз.
Вернуться к началу

offlineBen80  
имя: Сергей
Эксперт
Эксперт
 
Сообщения: 1318
Зарегистрирован: 18 июн 2017, 06:49
Пол: Не указан
Поблагодарили: 336 раз.

Re: Улучшение ИИ

Сообщение Ben80 » 11 май 2020, 07:39

Еще важный момент при издевательствах над ИИ алгоритмами - если мы меняем что-то в Enter2Object, то почти всегда должны произвести соответствующие изменения для этого объекта в AICalculateMapPosWeight. Иначе может получиться, что герой будет ходить туда-сюда к объекту-от объекта.

as239 писал(а):

Так именно это я и проверил - наибольшее значение у города.
Видимо после этой функции есть еще какая-то где может быть принято решение независимо от веса.
Буду смотреть.
Самое интересное что в итоге он идет и забирает шахту руды, пропустив два пустых города соперника!


Возможно, мы на пороге очередного маленького открытия по ИИ :smile1:
Вернуться к началу

Пред.След.

Вернуться в Общий раздел

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

cron