Оптимальный ход ИИ

Тема в разделе "WASM.ZEN", создана пользователем HuXTUS, 27 янв 2012.

  1. HuXTUS

    HuXTUS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2007
    Сообщения:
    240
    Привет, васм.
    Мозг кипит, туплю, похоже, что не замечаю чего-то простого, но глаз замылился. Уверен, что поможете.

    Делаю ИИ для одной самопридуманной стратегической (типа шахмат-шашек, но не совсем) игры .

    Что имею: алгоритм альфа-бета отсечений, внутри которого работает оценочная функция.

    Алгоритм брал из этой статьи http://habrahabr.ru/blogs/artificial_intelligence/111210/

    Мой упрощённый с подробными комментариями код (java):

    Код (Text):
    1. private TurnInfo bestTurn = new TurnInfo();  //найденный лучший ход
    2.  
    3. final private int max_deep = 7;  //максимальная глубина рекурсии
    4.  
    5. //ищет оптимальный ход
    6. private int thinkingBestTurn(int alpha, int beta, int deep, Player currentPlayer) {
    7.  
    8.   int value;
    9.  
    10.   //противник
    11.   Player opponent = game.getOppositePlayer(currentPlayer);
    12.  
    13.   //получаю список доступных ходов
    14.   ArrayList<TurnInfo> turnInfos = game.getTurnsList(currentPlayer);
    15.  
    16.   //перебираю все ходы
    17.   for (int k = 0; k < turnInfos.size(); k++) {
    18.     //беру ход из списка
    19.     TurnInfo ti = turnInfos.get(k);
    20.  
    21.     //сохраняю текущее состояние игры чтобы потом восстановить
    22.     game.push();
    23.  
    24.     //делаю ход
    25.     makeTurn(ti);
    26.  
    27.     //если мы ещё в состоянии думать хоть на один ход вперёд
    28.     if (deep > 1)
    29.       //вызываю рекурсивно метод для определения оптимального хода противника
    30.       value = -thinkingBestTurn(-beta, -alpha, deep - 1, opponent);
    31.     //иначе оцениваю текущую позицию
    32.     else
    33.       value = evaluatePlayerScore(currentPlayer) - evaluatePlayerScore(opponent);
    34.  
    35.     //откатываю сделанный ход
    36.     game.pop();
    37.  
    38.     //дальше классический алгоритм отсечений
    39.     if (value > alpha) {
    40.       if (value >= beta) {
    41.        
    42.         //нашли очередной оптимальный ход (только не в глубине рекурсии)
    43.         if (deep == max_deep) bestTurn = ti;
    44.  
    45.       return beta;
    46.  
    47.     }
    48.    
    49.     //нашли очередной оптимальный ход (только не в глубине рекурсии)
    50.     if (deep == max_deep) bestTurn = ti;
    51.  
    52.     alpha = value;
    53.     }
    54.        
    55.   }
    56.  
    57.   //выходим (в bestTurn - лучший ход)
    58.   return alpha;
    59. }
    Вроде бы в коде ошибок нет. Возникает следующая проблема, опишу (очень упрощённо) абстрактно:
    Предположим, что всё наше поле это три клетки на которых:
    пешка пустая_клетка цель

    Задача пешки дойти до цели. Как бы поступил человек? Сходил бы на пустую клетку, а на следующий ход на клетку_цель.

    Как рассуждает бот, согласно вышеприведённому алго:
    1 ход: получаю список доступных ходов. В списке всего один ход (на пустую клетку). Если я сделаю этот ход, то на следующий у меня будет два доступных хода (смогу сходить на покинутую клетку и на клетку-цель). Отлично, значит имеет смысл делать этот ход (потому что он приблизит меня к цели).
    2 ход: (Пешка бота стоит непосредственно возле цели.) Получаю список доступных ходов. Доступно два хода:

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

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

    В итоге бот двигает пешку влево-вправо!

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

    Функция evaluatePlayerScore(Player p) считает количество очков для текущей игровой ситуации у указанного игрока - она просто складывает стоимости всех фигур, которыми он владеет (король самый дорогой, пешка дешёвая итд).

    Заранее благодарен, сам я не могу сдвинуться с мёртвой точки. Пробовал накладывать штраф за глубину рекурсии при вычислении value, но комп начинает иногда совершать глупые ходы.
     
  2. kernel16

    kernel16 Human Vl

    Публикаций:
    0
    Регистрация:
    29 окт 2010
    Сообщения:
    316
    так значит надо оценить, что у нас есть 2 хода, но какой из них приведёт нас к цели быстрее
     
  3. HuXTUS

    HuXTUS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2007
    Сообщения:
    240
    Нуууу, логично :) Только как?

    Дело в том, что "цель" это не всегда перемещение из точки А -> B. На поле может разворачиваться сложная игровая ситуация. И если в алгоритм захардкодить "рубить всегда", то он иногда начнёт делать самоубийственые ходы. Или я чего-то недопонял, что имеете ввиду. Можно конкретный кусок псевдокода реализующего идею "оценить, что у нас есть 2 хода, но какой из них приведёт нас к цели быстрее"?
     
  4. zxcv

    zxcv New Member

    Публикаций:
    0
    Регистрация:
    30 дек 2011
    Сообщения:
    257
    представляете каждую текущую ситуацию с учетом игровых условий как статический лабиринт и поиск пути в лабиринте для каждой возможной фишки. и сравнение выгодности ходов

    или это, или это, не знаю подробностей задачи. вот тут еще
     
  5. HuXTUS

    HuXTUS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2007
    Сообщения:
    240
    zxcv, если я правильно понял, предлагаете не использовать алгоритм альфа-бета отсечений. Тогда, либо придётся отказаться от просчёта на несколько ходов вперёд, либо комп станет думать слишком долго (сейчас при глубине рекурсии = 8 он думает максимум секунд пять если ситуация сложная. В простых ситуациях ходит моментально).
     
  6. SEC70R_VA

    SEC70R_VA New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2011
    Сообщения:
    78
    HuXTUS
    "понятно, что ничего не понятно" (с).
    насколько понял, эта ваша игра -- "пошаговая стратегия", в связи с чем:
    1. Если задача бота выиграть у игрока, то это реализуемо (компьютеры посообразительней людей); т.е. "уровень сложности" в такой игре необходимость.
    2.
    Второй лучше, потому что сначала необходимо экономить время (т.е. приближать конец игры). Видимо в дизайне ИИбота не прописан строгий порядок действий.

    P.S. если бот не экономит время пользователя -- бот является ТРОЛЛЬлем )))
     
  7. HuXTUS

    HuXTUS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2007
    Сообщения:
    240
    Я понимаю, что второй лучше)

    Что нужно внести в тот код, что я раписал, какое-то простое улучшение (или исправить баг, который я не вижу) чтобы бот начал
    ?

    Код более-менее работает. Сейчас комп действует рационально в ситуациях, когда от неверного хода он может потерять очки, то есть может прикрыть сильную фигуру слабой от угрозы или начать убегать слабой от сильной пока не окажется под прикрытием. Но когда ему ничто не угрожает (как описано в первом посте), он начинает страдать ерундой.
     
  8. zxcv

    zxcv New Member

    Публикаций:
    0
    Регистрация:
    30 дек 2011
    Сообщения:
    257
    вы наверно понимаете, что я не знаю о вашей задаче и условиях решения(например, жабаМЕ + нокия 3310 на поле 10000х10000 при 1000 чар с полной свободой и плотной застройкой в неск уровней) совсем ничего.

    смысл этой фразы в том, что, может, стоит нормализовать условия под возможности целевой платформы? алг A* разработан специально для игр
     
  9. HuXTUS

    HuXTUS New Member

    Публикаций:
    0
    Регистрация:
    8 янв 2007
    Сообщения:
    240
    А* это поиск пути в лабиринте. В моей игре комп не ищет путь, он делает оптимальный ход (как в шашках или шахматах). Надо было сразу дать ссылку на игру, которую я клонирую (с небольшими улучшениями) и делаю ИИ
    http://www.freeworldgroup.com/games6/gameindex/tomb-chess.htm
     
  10. sergy

    sergy New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2012
    Сообщения:
    23
    HuXTUS
    ИИ для игр в шашки ? бред.
    такие игры лехко аписываются матаном и все сводится к тупому вычисленею