Camel Up Cup: um torneio de jogos de tabuleiro de IA

11

Taça Camel Up 2k18

Neste desafio, jogaremos o jogo de tabuleiro semi-popular Camel Up.

Camel Up! é um jogo de tabuleiro em que jogadores apostam em camelos para ganhar rodadas, ganhar ou perder o jogo, criar armadilhas para influenciar o movimento ou mover um camelo. Cada uma dessas decisões recompensa você com a chance de obter algum dinheiro, que é o que determina o vencedor. Os jogadores devem usar probabilidade, considerações sobre o estado do jogo e posse do oponente para tomar suas decisões. Aqui está um pequeno vídeo mostrando aos jogadores como jogar .

Como jogar

Aqui está uma idéia aproximada de como jogar. Assistir a um dos vídeos pode ser mais útil, porque eles têm recursos visuais :)

Por sua vez, você tem 4 opções.

  1. Mova um camelo. Isso escolhe um camelo daqueles que não se moveram e o move entre 1-3 espaços. Você ganha 1 moeda. As rodadas terminam quando todos os cinco camelos se movem, eles podem se mover
  2. Coloque uma armadilha. Isso continua no tabuleiro até o final da rodada. Você escolhe a armadilha + 1 / -1. Se um camelo ou pilha de camelos cair sobre ele, eles se movem + 1 / -1 e você recebe uma moeda. Você não pode colocar uma armadilha no quadrado 0. Você pode colocar uma armadilha onde estão os camelos, embora isso afete apenas os camelos que pousarem nela depois.
  3. Aposta na rodada. Você faz uma aposta em um vencedor da rodada. Eles vencem e você recebe 5/3/2/1, dependendo se você foi o 1º / 2º / 3º a apostar nesse camelo.
  4. Vencedor / perdedor do jogo. Você aposta em quem será o primeiro ou o último no final do jogo. você recebe 8/5/3/1/1 (eu acho) com base em se você fosse 1º / 2º / 3º / etc para apostar nesse camelo

Notas:

  • Existem 5 camelos. Eles começam em uma posição aleatoriamente de 0-2.
  • Quando um camelo é movido (veja acima o que desencadeia isso), ele se move de 1 a 3 quadrados. Se eles fossem colocados em um quadrado com outro camelo, eles seriam colocados "em cima" do outro, criando uma pilha de camelos. Se um camelo deve se mover, ele move todos os camelos acima dele na pilha de camelos. O camelo no topo da pilha é considerado o líder
  • Se você pousar em uma armadilha +1 (veja acima o que desencadeia isso), você avança um quadrado adiante. Aplicam-se regras de empilhamento padrão.
  • No entanto, se você acertar uma armadilha -1, move um quadrado para trás. Você fica embaixo da pilha de camelos que estão naquele quadrado, se houver.
  • O jogo termina quando um camelo atinge o quadrado 16. Isso invoca imediatamente o final da rodada e os gatilhos do final do jogo
  • As apostas vencedor / perdedor do jogo podem ser feitas apenas uma vez por camelo. Ou seja, você não pode apostar em um camelo para ganhar e perder o jogo

Desafio

Neste desafio, você escreverá um programa Python 3 para jogar com quatro jogadores, o vencedor leva todo o jogo de glória de Camel Up

Seu programa receberá o estado do jogo, que contém:

  • camel_track : com a localização dos camelos
  • trap_track : com a localização das armadilhas (entrada do formulário [trap_type (-1,1), player])
  • player_has_placed_trap : um array informando se os jogadores colocaram uma armadilha nesta rodada
  • round_bets : um conjunto de apostas feitas nesta rodada. Da forma [camelo, jogador]
  • game_winner_bets / game_loser_bets : matrizes das apostas feitas pelos camelos para ganhar ou perder o jogo. Você só poderá ver o valor dos jogadores que fizeram as apostas, e não em quem eles apostaram. Você pode saber em quem apostou. #do formulário [camelo, jogador]
  • player_game_bets : outra representação dos game_winner_bets / game_loser_bets. Mais uma vez, observe apenas as apostas que seu bot fez.
  • player_money_values : uma matriz que mostra a quantidade de dinheiro que cada jogador possui.
  • camel_yet_to_move : Uma matriz mostrando se um camelo se moveu nesta rodada.

Além do gamestate, você também recebe:

  • player : um número inteiro informando qual número de jogador você é (0-3).

A sintaxe para o que os jogadores devem retornar é:

  • [0]: Mover Camelo
  • [1, trap_type, trap_location]: Colocar armadilha
  • [2, projected_round_winner]: faça a aposta do vencedor da rodada
  • [3, projected_game_winner]: faça a aposta do vencedor do jogo
  • [4, projected_game_loser]: faça uma aposta perdida no jogo

Isso deve ser envolto em um método de movimento (player, gamestate)

Por exemplo, aqui está um jogador que fará uma aposta do vencedor da rodada se estiver em último lugar. Se não estiverem, colocarão uma armadilha em um quadrado aleatório.

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)]

O jogo foi escolhido por várias razões: ele tem um conjunto relativamente pequeno de opções para escolher (aproximadamente 20 opções por turno, facilmente reduzidas para geralmente cerca de 3-4), os jogos são curtos e há um elemento de sorte (o torna para que até os bots "ruins" possam vencer).

Jogabilidade

O corredor do torneio pode ser encontrado aqui: camel-up-cup . Corra camelup.pypara executar um torneio ou a função PlayGame para executar jogos. Manterei esse repositório atualizado com novos envios. Programas de exemplo podem ser encontrados em players.py.

Um torneio consiste em 100 jogos por 10 jogadores (arredondados, então 14 jogadores significam 200 jogos). Cada jogo terá quatro jogadores aleatórios selecionados do grupo de jogadores para preencher as quatro posições. Os jogadores não poderão entrar no jogo duas vezes.

Pontuação

O vencedor de cada jogo é o jogador com mais dinheiro no final do jogo. No caso de empate no final de um jogo, todos os jogadores com o valor máximo em dinheiro recebem um ponto. O jogador com mais pontos no final do torneio vence. Vou postar pontuações enquanto corro os jogos.

Os jogadores enviados serão adicionados ao pool. Adicionei três bots realmente idiotas e um que fiz para começar.

Ressalvas

Não modifique as entradas. Não tente afetar a execução de nenhum outro programa, exceto através da cooperação ou defeito. Não faça uma submissão sacrificial que tente reconhecer outra submissão e beneficiar esse oponente às suas próprias custas. As brechas padrão são proibidas.

Limite o tempo gasto pelo seu bot em ~ 10s por turno.

Os envios não podem duplicar envios anteriores.

Por favor, não veja as apostas game_winner ou game_loser de outros jogadores. É muito fácil de fazer, mas ainda trapaça.

Se você tiver alguma dúvida não hesite em perguntar.

Ganhando

A competição permanecerá aberta indefinidamente, à medida que novas submissões forem publicadas. No entanto, declararei um vencedor (aceite uma resposta) com base nos resultados um mês após a publicação desta pergunta (20 de julho).

Resultados

Player0: 12
Player1: 0
Player2: 1
Sir_Humpfree_Bogart: 87
Tyler Barron
fonte
Talvez eu tenha lido além disso, mas quantos camelos existem em jogo? Além disso, quantos quadrados eles precisam percorrer para chegar ao outro lado? Com base no seu código do GitHub, tenho certeza de que são 5 camelos e 25 quadrados, mas não vi isso mencionado na descrição do desafio. Quanto às apostas, podemos apostar qualquer quantia ou apostará 1 por padrão? Temos um limite de gastos ou podemos apostar a cada rodada indefinidamente? Quanto aos jogadores movendo um camelo, qual camelo é movido? O camelo com o seu jogador correspondente? Se sim, por que existem 4 jogadores, mas 5 camelos?
Kevin Cruijssen
1
Teria sido perfeito ter respostas Perl
O cara aleatório
Bem-vindo ao PPCG!
AdmBorkBork
100 jogos por 10 jogadores parece bastante baixo IMO, especialmente com um jogo com tanta aleatoriedade
Nathan Merrill
1
@AdmBorkBork Thank you! Eu sou novo nisso, então seja bem-vindo todos os ponteiros. Isso funcionou bem na vida real - empolgado para ver como ele joga fora aqui
Tyler Barron

Respostas:

1

Sir_Humpfree_Bogart.py

Este é um bot que eu fiz para o Torneio Camel Up Cup .

Primeiro, eles examinam todas as configurações possíveis que os camelos podem acabar no final da rodada. Eles determinam o valor esperado de apostar em um camelo que vence a rodada usando

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

Então eles movem camelos aleatoriamente até que um camelo ganhe. Depois de fazer isso alguns milhares de vezes, você pode estimar a chance de cada camelo ganhar e perder. Novamente, obtemos o valor esperado deles usando

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

As únicas outras opções são mover um camelo (que sempre produz uma moeda, portanto seu valor esperado é um) e colocar uma armadilha. Ambas as equipes sentiram que colocar uma armadilha era uma opção fraca o suficiente para ignorá-la completamente. Com essas informações, os bots escolheram a opção com o maior valor esperado.

Como o torneio viu o segundo lugar terminar da mesma forma que no último lugar, faz sentido se você estiver atrasado para ter chances de chegar ao primeiro lugar. O SBH usou distance_from_first_place e nearness_to_end para determinar o quão arriscado o bot deve ser, onde se você estiver longe do primeiro e próximo do final, o risco será alto e se você estiver no primeiro ou longe do final do jogo, o risco será baixo . Com um baixo risco, o bot decidiria uma ação com uma opção de alto valor esperado e um alto risco, produzindo a opção com um alto resultado. A equação exata foi

Functional_EV = EV + (upshot-EV) * riskiness

onde o resultado é o pagamento mais alto que você pode obter de uma decisão e o risco varia de 0 a 1.

Tyler Barron
fonte
0

players.py

Estes são bots incrivelmente burros para começar o torneio. Eles quase não têm lógica, mas agem como estruturas para as pessoas usarem

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)]
Tyler Barron
fonte