Camel Up Cup: турнир по настольной игре AI

11

Camel Up Cup 2k18

В этом соревновании мы будем играть в полу-популярную настольную игру Camel Up.

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

Как играть

Вот примерное представление о том, как играть. Просмотр одного из видео может быть более полезным, потому что у них есть визуальные эффекты :)

На ваш ход у вас есть 4 варианта.

  1. Переместить верблюда. Это выбирает верблюда из тех, кто не двигался, и перемещает его между 1-3 пробелами. Вы получаете 1 монету. Раунды заканчиваются, когда все пять верблюдов сдвинулись, тогда они могут все двигаться
  2. Разместите ловушку. Это идет на доске до конца раунда. Вы выбираете ловушку + 1 / -1. Если верблюд или верблюжья стая приземляются на них, они двигаются + 1 / -1, и вы получаете монету. Вы не можете поставить ловушку на клетку 0. Вы можете поставить ловушку там, где верблюды, хотя это повлияет только на верблюдов, которые приземляются на нее после.
  3. Круглая ставка победителя. Вы делаете ставку на победителя раунда. Они выигрывают, вы получаете 5/3/2/1 в зависимости от того, сделали ли вы 1/2/3/3 ставку на этого верблюда.
  4. Победитель игры / проигравший. Вы делаете ставку на то, кто будет первым или последним в конце игры. Вы получаете 8/5/3/1/1 (я думаю) на основании того, что вы были 1/2/3 / и т. д., чтобы сделать ставку на этого верблюда

Заметки:

  • Есть 5 верблюдов. Они начинают случайную позицию с 0-2.
  • Когда верблюд перемещается (см. Выше для того, что вызывает это), они перемещаются на 1-3 квадрата. Если они будут помещены в квадрат с другим верблюдом, они помещаются "сверху" другого, создавая стог верблюда. Если верблюд должен двигаться, он перемещает всех верблюдов над ним в стеке верблюдов. Верблюд на вершине стека считается в лидерах
  • Если вы попадаете в ловушку +1 (см. Выше, чтобы узнать, что это вызывает), вы продвигаетесь на одну клетку дальше. Применяются стандартные правила укладки.
  • Однако если вы попали в ловушку -1, вы переместитесь на одну клетку назад. Вы идете под стопку верблюдов, которые на этом квадрате, если таковые имеются.
  • Игра заканчивается, когда верблюд достигает квадрата 16. Это немедленно вызывает завершение раунда и запуск игры
  • Ставки победителя / проигравшего в игре могут быть сделаны только один раз за верблюда. Т.е. нельзя делать ставку на верблюда, чтобы выиграть и проиграть

Вызов

В этом задании вы напишите программу на Python 3 для четырех игроков, победитель получает всю славу игры Camel Up

Ваша программа получит игровое состояние, которое содержит:

  • camel_track : с местонахождением верблюдов
  • trap_track : с расположением ловушек (запись вида [trap_type (-1,1), player])
  • player_has_placed_trap : массив, сообщающий вам, поместили ли игроки ловушку в этом раунде
  • round_bets : массив ставок, сделанных в этом раунде. В форме [верблюд, игрок]
  • game_winner_bets / game_loser_bets : массивы ставок игроков, сделанные для верблюдов, чтобы выиграть или проиграть игру. Вы сможете увидеть ценность только тех игроков, которые сделали ставки, а не тех, на кого они сделали ставку. Вы можете знать, на кого ставите. # формы [верблюд, игрок]
  • player_game_bets : еще одно представление game_winner_bets / game_loser_bets. Опять же, смотрите только на ставки, сделанные вашим ботом.
  • player_money_values : массив, показывающий сумму денег, которую имеет каждый игрок.
  • camel_yet_to_move : массив, показывающий, переместился ли верблюд в этом раунде.

В верхней части игрового состояния вы также получаете:

  • игрок : целое число, указывающее, какой у вас номер игрока (0-3).

Синтаксис того, что игроки должны вернуть:

  • [0]: Переместить верблюда
  • [1, trap_type, trap_location]: разместить ловушку
  • [2, projected_round_winner]: сделать ставку победителем раунда
  • [3, projected_game_winner]: сделать ставку на победу в игре
  • [4, projected_game_loser]: сделать ставку на проигрыш

Это должно быть заключено в методе перемещения (игрок, игровое состояние)

Например, вот игрок, который сделает ставку на победителя раунда, если он будет на последнем месте. Если это не так, то они разместят ловушку на случайном квадрате.

class Player1(PlayerInterface):
     def move(player,g):
         if min(g.player_money_values) == g.player_money_values[player]:
            return [2,random.randint(0,len(g.camels)-1)]
        return [1,math.floor(2*random.random())*2-1,random.randint(1,10)]

Игра была выбрана по нескольким причинам: она имеет относительно небольшой пул вариантов для выбора (примерно 20 вариантов за ход, их легко сузить до 3-4), игры короткие, и есть элемент удачи (делает его так что даже "плохие" боты могут победить).

Игровой процесс

Бегун турнира можно найти здесь: Кубок верблюда . Запустите camelup.pyдля запуска турнира или функцию PlayGame для запуска игр. Я буду держать этот репозиторий обновленным с новыми представлениями. Примеры программ можно найти в players.py.

Турнир состоит из 100 игр на 10 игроков (округляется, поэтому 14 игроков означают 200 игр). В каждой игре будет четыре случайных игрока, выбранных из пула игроков для заполнения четырех позиций. Игроки не смогут быть в игре дважды.

счет

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

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

Предостережения

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

Ограничьте время, необходимое вашему боту, до ~ 10 с за ход.

Представления не могут дублировать предыдущие представления.

Пожалуйста, не просматривайте ставки game_winner или game_loser от других игроков. Это довольно легко сделать, но все же обманывать.

Если у вас есть вопросы, не стесняйтесь спросить.

выигрыш

Конкурс будет оставаться открытым до бесконечности, так как новые материалы публикуются. Тем не менее, я объявлю победителя (приму ответ) по результатам через месяц после опубликования этого вопроса (20 июля).

Полученные результаты

Player0: 12
Player1: 0
Player2: 1
Sir_Humpfree_Bogart: 87
Тайлер Баррон
источник
Может быть, я читал мимо этого, но сколько верблюдов в игре? Кроме того, сколько квадратов они должны пройти, чтобы добраться до другой стороны? Основываясь на вашем коде GitHub, я почти уверен, что это 5 верблюдов и 25 квадратов, но я не видел этого в описании задачи. Что касается размещения ставок, можем ли мы ставить любую сумму, или она будет ставить 1 по умолчанию? У нас есть лимит расходов, или мы можем ставить каждый раунд на неопределенный срок? Что касается игроков, перемещающих верблюда, какой верблюд перемещается? Верблюд с вашим подходящим игроком? Если да, то почему 4 игрока, кроме 5 верблюдов?
Кевин Круйссен
1
Было бы идеально иметь ответы на Perl
Случайный парень
Добро пожаловать в PPCG!
AdmBorkBork
100 игр на 10 игроков кажется довольно низким IMO, особенно с игрой с такой большой случайностью
Натан Меррилл
1
@AdmBorkBork Спасибо! Я новичок в этом, поэтому приветствую всех указателей. Это хорошо сработало в реальной жизни - чтобы увидеть, как это происходит здесь
Тайлер Баррон

Ответы:

1

Sir_Humpfree_Bogart.py

Это бот, который я сделал для турнира Camel Up Cup .

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

EV_roundwin = (chance_1st)*(payout) + (chance_2nd)*(payout) - (chance_3rd_or_worse)*(cost)

Затем они перемещают верблюдов случайным образом, пока верблюд не победит. Сделав это несколько тысяч раз, вы можете оценить вероятность того, что каждый верблюд выиграет и проиграет. Опять же, мы получаем ожидаемое значение этих с помощью

EV_gamewin = (chance_1st)*(payout) - (chance_2nd_or_worse)*(cost)

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

Поскольку турнир, занявший второе место, заканчивается так же, как и последнее место, имеет смысл, если вы отстаете, чтобы попытаться занять первое место. SBH использовал distance_from_first_place и nearness_to_end, чтобы определить, насколько рискованным должен быть бот, где, если вы далеки от первого и близки к концу, риск будет высоким, а если вы находитесь в первом или далеком конце игры, риск будет низким , С низкой рискованностью бот будет выбирать действие с опцией с высокой ожидаемой ценностью и высокой рискованностью, что дает опцион с высоким результатом. Точное уравнение было

Functional_EV = EV + (upshot-EV) * riskiness

где upshot - это максимальная выплата, которую вы можете получить от решения, а рискованность варьируется от 0 до 1.

Тайлер Баррон
источник
0

players.py

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

import random
import math
from playerinterface import PlayerInterface

class Player0(PlayerInterface):
    def move(player,g):
        #This dumb player always moves a camel
        return [0]

class Player1(PlayerInterface):
    def move(player,g):
        #This player is less dumb. If they have the least amount of money they'll make a round winner bet
        #If they aren't in last then they'll place a trap on a random square. Still p dumb though
        if min(g.player_money_values) == g.player_money_values[player]:
            return [2,random.randint(0,len(g.camels)-1)]
        return [1,math.floor(2*random.random())*2-1,random.randint(1,10)]

class Player2(PlayerInterface):
    def move(player,g):
        #This dumb player always makes a round winner bet
        return [2,random.randint(0,len(g.camels)-1)]
Тайлер Баррон
источник