Я реализую бильярдную игру пула в Java, и все это хорошо работает. Это - многопользовательская игра, но тем не менее, должно также быть возможно играть его один. С этой целью я пытаюсь реализовать простой KI. В данный момент KI выбирают просто случайным образом направление, и случайная интенсивность импульса (не знайте корректное английское слово для этого). Конечно, этот AI очень плох и маловероятен когда-либо бросить вызов плееру.
Таким образом, я думал об улучшении KI, но существуют несколько твердые решить проблемы. Сначала я думал о просто выборе ближайшего шара и пытаться поместить его непосредственно в ближайшую дыру. Это не то, что плохо, но если там другие шары в строке между, это действительно не работает еще. Дополнительно этот dosn't решает te проблему вычисления интенсивности импульса.
Так есть ли какие-либо общие рекомендации? Или какие-либо идеи? Лучшие практики?
Сколько процессорного времени и памяти требуется для расчета результатов одного «хода» игры? Можете ли вы позволить себе анализировать более одного хода? Если это относительно дешево, просто выберите N случайных направлений / импульсов, рассчитайте результаты и выберите лучший.Вы можете исключить некоторые "хитрые" случаи, когда мяч попадает в лузу после слишком большого количества столкновений. Кроме того, для упрощения вы можете ограничить время моделирования для каждого хода (т.е. не ждать, пока все шары остановятся, просто вычислите первые T секунд).
Таким образом, у вас могут быть компьютерные игроки разного уровня - чем выше N (и T), тем выше уровень игры.
Я могу предложить два общих подхода.
Составить список всех возможных положений кия вокруг шара и уровней силы, а затем перебрать этот список, чтобы найти первое, которое позволит вам утопить шар. Это довольно большой список, вы можете сократить его, используя небольшое количество уровней силы и исключая любые "очевидно" плохие удары.
Работайте в обратном направлении - посмотрите на каждый шар на столе и выясните, можно ли сделать так, чтобы кий коснулся его. Затем определите правильное положение кия и уровень силы, чтобы шар попал в лунку. Вы можете расширить эту схему, чтобы найти дерево для ударов по нескольким шарам.
Мне больше всего нравится решение 1; оно позволяет вам найти ситуации, в которых вы сможете загнать два или более шаров одновременно.
Думаю, это вряд ли случайно. Вам понадобится физический движок для моделирования взаимодействия битов, шаров, бамперов и карманов. Мне кажется, что это не столько ИИ, сколько физика.
Вы могли бы рассмотреть возможность отображения шаров в виде взвешенного графика. Можно было положить в карманы как специальные узлы. Затем вы выбираете, какой шар поставить или ударить, в зависимости от веса пути от битка к конкретному шару и лузу. Интенсивность импульса также можно установить с помощью значения этого веса. Затем вы можете использовать физический движок, чтобы определить, возможен ли вообще выстрел. Я никогда не пробовал такую штуку, поэтому все теоретически и не знаю, насколько это практично. Кроме того, такой метод не предусматривает подпрыгивания кия или других шаров, поэтому в основном он рассчитан только на прямые удары.
В зависимости от игры в бильярд у вас обычно есть две задачи
Оценить ситуацию на столе (получить возможно ударов)
В идеальном сценарии (идеальный прицел, точный выстрел) все возможные удары одинаково сложны, и если вы учитываете только прямые удары по одному мячу, то будет только максимум 6 лунок x n ситуаций, которые вам нужно проанализировать (анализ простых canons - для ударов двух шаров требуется только n ^ 2 шаров x 6 лунок). Для каждой из этих ситуаций, чтобы установить, возможны ли они, требуется простой анализ (если вы не выполняете очень реалистичное моделирование столкновений). Таким образом, в очень простых симуляциях вы можете попытаться построить все возможные ситуации и расположить их по порядку. Чтобы анализировать удары с берега, вы можете отразить шары и лунки.
В качестве альтернативы при перечислении возможных ситуаций вы можете просто выполнить сканирование строки таблицы, отметив области, запрещенные для выстрелов, а также перечислить и построить потенциальные выстрелы, например ...
angle1, ball1, pocket2
angle2, ball1, pocket3
angle3, ball1, ball2, pocket1
angle4, cushion2, ball2, pocket1
Для более качественного ИИ вы хотите имитировать недостатки, например, выстрел выполняется ударом по мячу в некоторой точке x (может быть определен как угол от прямого попадания), предположим, что произойдет ошибка (из-за плохой прицел, или плохой удар, или что-то еще) dx - это, в свою очередь, приведет к тому, что мяч будет иметь ошибку в направлении, которая будет увеличиваться с увеличением расстояния до лузы. Это дает один способ ранжировать выстрелы по сложности - чувствительность выстрела с точки зрения ошибки прицеливания / выстрела (одни выстрелы легче, чем другие). Это будет зависеть от длины пути от белого до мяча и от мяча до лунки.
Еще одна вещь, на которую следует обратить внимание, - это риск попадания белого мяча в лунку или другой неправильный бросок.
Выбор удара (не только исходя из сложности, но и потенциального выигрыша)