Concurso aberto permanentemente - Atualizado em 10 de agosto de 2017
Embora em 5 de junho de 2017 tenha declarado vencedor (que será mantido como a melhor resposta), estarei criando novos bots e atualizando os resultados.
Resultados 5 de junho
Parabéns user1502040
Como não há empates, mostro apenas a% de partidas vencidas.
Statistician2
- 95,7%
Fitter
- 89,1%
Nash
- 83,9%
Weigher
- 79,9%
ExpectedBayes
- 76,4%
AntiRepeater
- 72,1%
Yggdrasil
- 65,0%
AntiGreedy
- 64,1%
Reactor
- 59,9%
NotHungry
- 57,3%
NashBot
- 55,1%
Blodsocer
- 48,6%
BestOfBothWorlds
- 48,4%
GoodWinning
- 43,9%
Rockstar
- 40,5%
ArtsyChild
- 40,4%
Assassin
- 38,1 %
WeightedRandom
- 37,7%
Ensemble
- 37,4%
UseOpponents
- 36,4%
GreedyPsychologist
- 36,3%
TheMessenger
- 33,9%
Copycat
- 31,4%
Greedy
- 28,3%
SomewhatHungry
- 27,6%
AntiAntiGreedy
- 21,0%
Cycler
- 20,3%
Swap
- 19,8%
RandomBot
- 16,2%
Criei uma planilha do Google com a grade de resultados de cada pareamento: https://docs.google.com/spreadsheets/d/1KrMvcvWMkK-h1Ee50w0gWLh_L6rCFOgLhTN_QlEXHyk/edit?usp=sharing
Graças ao dilema de Petri , encontrei-me capaz de lidar com esse rei da colina.
O jogo
O jogo é uma simples "pedra-papel-tesoura" com um toque: os pontos ganhos a cada vitória aumentam durante a partida (seu R, P ou S são carregados).
- Paper ganha Rock
- Tesoura ganha Papel
- Pedra vence Tesoura
O vencedor ganha tantos pontos quanto sua carga em seu jogo.
O perdedor aumenta em 1 a carga em seu jogo.
No caso de empate, cada jogador aumenta a carga em seu jogo em 0,5.
Após 100 jogadas, a que tiver mais pontos é o vencedor.
por exemplo: P1 possui cargas [10,11,12] (Pedra, papel, tesoura) e P2 [7,8,9]. P1 joga R, P2 joga P. P2 vence e ganha 8 pontos. As cargas P1 se tornam [11,11,12], as cargas P2 permanecem as mesmas.
Especificações do desafio
Seu programa deve ser escrito em Python (desculpe, não sei como lidar com isso de outra forma). Você deve criar uma função que aceite cada uma dessas variáveis como argumento em cada execução:
my_points, opp_points, my_loaded, opp_loaded, my_history, opp_history
points
- Pontos atuais (seu e seu opp)
loaded
- Matriz com cargas (em ordem RPS) (sua e do seu opp)
history
- String com todas as jogadas, o último personagem é a última jogada (sua e da sua opp)
Você deve retornar "R"
, "P"
ou "S"
. Se você devolver algo diferente, seria uma perda automática da partida.
Regras
Você não pode alterar as funções internas.
Teste
Manterei um Git atualizado com o código e todos os bots competindo: https://github.com/Masclins/LoadedRPS
A julgar
O vencedor será decidido selecionando a pessoa com mais vitórias após 1000 rodadas completas. Os empates serão quebrados por jogos empatados. 1000 partidas estão sendo disputadas em vez de uma, porque espero muita aleatoriedade, e dessa forma a aleatoriedade seria menos relevante.
Você pode enviar até 5 bots.
O concurso termina no dia 4 de junho (que será o último dia em que eu aceito qualquer resposta) e, no dia 5 de junho, publicarei as classificações finais (tente publicar uma promoção antes).
Como este é o meu primeiro KOTH, estou 100% aberto a mudar qualquer coisa para melhorar, como o número de partidas disputadas contra cada bot.
Editado para 1000 correspondências, pois vejo que realmente existe muita aleatoriedade.
fonte
runcode
ebots
)?Respostas:
Estatístico(não está mais jogando)Alterna entre algumas estratégias simples com base no desempenho passado esperado
Estatístico 2
Nash
Calcula um equilíbrio aproximado de Nash por descida de gradiente.
fonte
Pesador
Perdi a noção do raciocínio ao experimentar o código, mas a idéia básica é estimar a probabilidade de movimento do oponente pelos últimos 3 movimentos usando alguns pesos e multiplicá-los por outro peso que depende das cargas. Pensei que também pudesse usar de alguma forma
my_loaded
, mas não consegui decidir como, então deixei de fora.Satanás
Provavelmente será desqualificado, porque é meio trapaceiro e faz algumas suposições sobre a função de teste (ele precisa ter a função do oponente em uma variável no quadro da pilha), mas tecnicamente não quebra nenhuma regra atual - ele não redefinir ou reescrever qualquer coisa. Simplesmente usa magia negra para executar a função oponente e ver qual turno eles fizeram / farão. Não pode lidar com a aleatoriedade, mas os robôs deterministas não têm chance de derrotar Satanás.
fonte
my_loaded
você pode adicionar um peso que valorize o movimento que perderia contra o (s) seu (s) último (s) movimento (s). É como assumir que seu oponente fará algo semelhante ao que você fez e, portanto, puni-lo por assumir que você continuará jogando da mesma forma. Algo como:for i, m in enumerate(reversed(my_history[-3:])): sc[(idx[m]+1)%3] += (K / (1 + i))
Ajustador
Este bot melhora o Pattern e o funde com o Economist (o Pattern and Economist não participará mais)
A melhoria do Pattern é que o Bot agora procura dois dois tipos de padrões: Oponente reagindo à sua última jogada e o oponente reagindo à minha última jogada. Em seguida, avalia as duas previsões para usar a que se encaixa melhor.
A partir desse padrão, o Bot tem agora a probabilidade de R, P e S. Levando isso em conta e o valor esperado de cada jogada (como Economist fez), o Bot joga o que dá mais valor.
Aqui estão os dois códigos antigos
Padrão(não está mais sendo reproduzido)O Padrão tenta encontrar padrões no seu oponente. Parece o que o oponente havia jogado após a última jogada que ele fez (dando mais peso às últimas jogadas). Com isso, adivinha o que o oponente jogará e joga a contra-partida.
Economista(não está mais jogando)O Economist faz o seguinte: Adivinha a probabilidade de cada jogada do oponente observando o que ele havia jogado nas últimas 9 jogadas. A partir disso, calcula o benefício esperado de cada jogada e segue com a que tem o melhor valor esperado.
fonte
Yggdrasil
Isso se chama "Yggdrasil" porque olha para o futuro na árvore do jogo. Esse bot não realiza nenhuma previsão do oponente, apenas tenta manter uma vantagem estatística se lhe for dada (equilibrando os lucros atuais e futuros). Ele calcula uma estratégia mista aproximadamente ideal e retorna um movimento selecionado aleatoriamente com esses pesos. Se esse bot fosse perfeito (o que não é, porque a função de avaliação de estado é muito ruim e não parece muito à frente), seria impossível vencê-lo mais de 50% do tempo. Eu não sei o quão bem esse bot vai se sair na prática.
fonte
Anti-Repetidor
Coleta de papel no primeiro turno, após o qual retorna o que for melhor do que o adversário fez mais, escolhendo papel em caso de empate.
Imitador
Simplesmente copia o último lance do oponente.
Anti-Anti-Ganancioso
Seleciona o que perde para a escolha mais pesada do oponente.
Um pouco com fome
fonte
O mensageiro
Estrela do rock
Assassino
Explicação
Agora, você pode pensar que esses robôs são totalmente estúpidos.
não é inteiramente verdade, eles são baseados na idéia de acumular um bônus enorme, e o inimigo dando um passo em falso e sendo atacado com ele.
agora, esses robôs jogam de maneira muito semelhante à gananciosa, no entanto, são mais simples e não pegam aleatoriamente até obter uma carga em uma arma, eles ficam com a arma de sua escolha.
Outra coisa a ser observada: cada uma delas vence a ganância por metade do tempo, atraindo um terço do tempo e perdendo um sexto do tempo. quando vencerem, tenderão a ganhar muito. por que é isso?
Ganancioso, até que ele perca uma rodada, escolherá aleatoriamente uma arma. isso significa que quando ele não vencer uma rodada, ele escolherá uma arma aleatoriamente novamente, o que poderia ser uma vitória novamente. se ganancioso empata ou perde, ele fica com essa arma. se ganancioso vence pelo menos uma rodada, escolhe a mesma arma que o bot, ganancioso ganha. se ganancioso escolher a arma perdida em algum momento, nosso bot vence, porque a carga em nossa arma teria sido maior do que a pontuação gananciosa.
Assumindo que ganancioso nem sempre escolhe a arma vencedora com grandes chances, isso significa que as chances são:
1/3: {1/2 vitória (1/6 total). 1/2 perda (1/6 total). }
1/3 empate
Vitória 1/3
então: 1/3 de chance de empate, 1/6 de chance de derrota, 1/2 de chance de ganhar.
isso provavelmente mostra que você precisa fazer vários jogos de várias rodadas
estes são principalmente para começar o desafio
fonte
Reator
Faz a jogada que teria vencido a rodada anterior.
fonte
opp_history[len(opp_history)-1]
poropp_history[-1]
.Criança artística
Esse bot age como uma criança que pratica artes e ofícios, começa com papel e usa papel ou tesoura aleatoriamente, mas não usa tesoura após pedra ou tesoura porque ela precisa usar a tesoura no papel. Jogará uma pedra de volta para quem jogar uma pedra nela.
fonte
Aqui estão os três Bots que construí para testar:
RandomBot
Ávido
Simplesmente escolhe a opção mais carregada.
Antigreedy
Assume que o oponente jogará ganancioso e jogará a alternativa vencedora.
fonte
Not Hungry
Isso é literalmente o inverso de Greedy, escolhe a opção de pontos mais baixos disponível.
fonte
Usar o favorito do oponente
Para o primeiro turno, escolhe um item aleatório. Para todos os outros turnos, usa a escolha mais comum do oponente. Se houver um empate, o padrão é a primeira escolha mais comum.
// Eu roubei o código daqui
Ganhar é bom
Retorna a escolha do vencedor da rodada anterior. Se a rodada anterior foi um empate, verifica recursivamente a rodada antes disso. Se foram apenas empates, ou é a primeira rodada, retorna uma escolha aleatória.
fonte
Melhor dos dois mundos
Este bot basicamente combina Anti-Greedy e Greedy (daí o nome).
fonte
find
é para cordas.my_loaded
eopp_loaded
são as duas listas.index
deve ser bom para o que você quer.NashBot
Escolhe aleatoriamente entre as três opções, de forma que o oponente estatisticamente não tenha preferência entre os movimentos em relação ao valor em que está marcado; em outras palavras, tanto Greedy quanto Not Hungry devem ter a mesma pontuação média esperada.
fonte
Expectedbayes
Editar: Ranking Atualizado
Este é o novo ranking superior após a inclusão do Expectedbayes:
Explicações
(Nota: envio após 05/06/2017)
Este bot tenta maximizar o valor esperado de sua próxima jogada:
As probabilidades são atualizadas a cada dez movimentos. O número de movimentos anteriores usados para calcular as probabilidades foi definido como 10 para cada bot (portanto, 20 recursos no geral). Provavelmente, isso está ajustando demais os dados, mas não tentei verificar mais.
Ele se baseia na biblioteca do scikit para calcular as probabilidades de movimentação do oponente (estou dizendo isso no caso de eu ter lido errado as regras e, de fato, não era permitido).
Vence facilmente contra bots que sempre fazem a mesma escolha. Surpreendentemente, é bastante eficaz contra o bot aleatório com uma taxa de vitória de 93% (acredito que isso se deva ao fato de limitar o número de pontos que seu oponente pode obter e maximizar seu próprio número de pontos possíveis para cada rodada).
Fiz uma tentativa rápida com 100 turnos e apenas um número limitado de bots, e é isso que recebi de result_standing:
O que não é tão ruim assim!
fonte
Cycler
0 0
fonte
Conjunto
Vários algoritmos concorrentes votam na melhor solução.
Troca
Faz um movimento aleatório, mas sem repetir o último movimento que fez.
fonte
blodsocer
socery
Eu dei uma correção, então provavelmente deve funcionar agora, espero
Eu estraguei algo de novo, então excluí e desfiz a exclusão. Estou fazendo muitas bagunças.
fonte
if opp_history[1] == "S": return "R" elif opp_history[1] == "R": return "R" else: return "P"
que tipo de sociedade é essa?elif min(opp_history.count(i) for i in "RPS")/max(opp_history.count(i) for i in "RPS") >0.8 and len(my_history)>30:
"RPS"[my_loaded.index(max(my_loaded))+len(my_history)%2]
mas parece fora de alcance (e também as demais linhas).Aleatório ponderado
Como o RandomBot, mas ele escolhe apenas 2 para lançar cada vez que é invocado. Às vezes, vence o Rockstar ou o Assassin, mas aumenta as pontuações do outro (por exemplo, se vencer o Rockstar, aumenta o Assassin em pontos).
fonte
Psicólogo ganancioso
Nomeado como padrão, por ser ganancioso, mas se não puder decidir, será contrário ao que o adversário faria se usasse a estratégia gananciosa. Se ainda não puder decidir, será aleatoriamente.
fonte