Rei da Colina: Assalto a Banco

15

Exemplo de execução adicionado 4/11

Esclarecimento das regras 4/8: Todos os envios estarão competindo em um torneio gigantesco, composto por tantas partidas quanto o meu computador pode executar em 48 horas.

Qualquer pessoa que passe algum tempo assistindo a transmissões no Twitch está ciente da prevalência do DeepBot e talvez até esteja familiarizada com o jogo de apostas Bank Heist . Este torneio King of the Hill é diretamente inspirado por esse jogo. Não se preocupe, no entanto. Acho que já joguei torções extras suficientes nessa versão para manter as coisas interessantes.

Um exemplo rápido

#####GAME 13: 16 players######

Round 1:
gunHeCK bet 0.
PassivePanga bet 69.
SnitcherKing bet 1.
Lurker bet 0.
OC'sRandomTpyos bet 1.
MonisAddiction bet 69.
RaysFive01K bet 28.
LimeadeSneaktar bet 1.
KaylorrCriterion bet 0.
HardHatUmar bet 0.
HeCKuSumer bet 185.

Round 2
HeCKuSumer decided to !guncheck.
LimeadeSneaktar decided to double cross.
MonisAddiction decided to all in.
OC'sRandomTpyos decided to acquire intel.
RaysFive01K decided to deposit.
SnitcherKing decided to finger.
PassivePanga decided to !guncheck.

Results
PassivePanga failed. :(
SnitcherKing failed. :(
OC'sRandomTpyos was successful, and may gain ¥0
MonisAddiction failed. :(
RaysFive01K was successful, and may gain ¥0
LimeadeSneaktar was successful, and may gain ¥1
HeCKuSumer failed. :(

Results:
0. KaylorrCriterion: 3600
1. Lurker: 3600
2. gunHeCK: 3600
3. SnitcherKing: 3586
4. PassivePanga: 2634
5. LimeadeSneaktar: 2496
6. HeCKuSumer: 1909
7. HardHatUmar: 490
8. RaysFive01K: 255
9. OC'sRandomTpyos: 170
10. MonisAddiction: 0

(In this round, 7 players joined the heist, but the dice only rolled right for 3 of them. Of those, only LimeadeSneaktar brought any home--having stolen it from OcsRandomTpyos. RaysFive01K won significantly more, but deposited it all at the bank before leaving. At this point, the players who did not heist are doing well, living off their day jobs.)

#####GAME 14: 231 players######

Round 1:
Lurker bet 0.
HeCKuSumer bet 190.
KaylorrCriterion bet 0.
HardHatUmar bet 0.
MonisAddiction bet 0.
OC'sRandomTpyos bet 1.
gunHeCK bet 0.
LimeadeSneaktar bet 1.
RaysFive01K bet 25.
PassivePanga bet 69.
SnitcherKing bet 1.

Round 2
PassivePanga decided to !guncheck.
OC'sRandomTpyos decided to buy guard.
HeCKuSumer decided to !guncheck.
SnitcherKing decided to finger.
RaysFive01K decided to deposit.
LimeadeSneaktar decided to double cross.

Results
HeCKuSumer failed. :(
OC'sRandomTpyos failed. :(
LimeadeSneaktar failed. :(
RaysFive01K failed. :(
PassivePanga failed. :(
SnitcherKing failed. :(

Results:
0. KaylorrCriterion: 3840
1. Lurker: 3840
2. gunHeCK: 3840
3. SnitcherKing: 3825
4. PassivePanga: 2805
5. LimeadeSneaktar: 2495
6. HeCKuSumer: 1959
7. HardHatUmar: 490
8. MonisAddiction: 240
9. RaysFive01K: 229
10. OC'sRandomTpyos: 161

Six players heisted--but should have been paying more attention to the rabble and backed out, because the probabilities dropped too low to win, and all failed.


#####GAME 15: 300 players######

Round 1:
OC'sRandomTpyos bet 1.
Lurker bet 0.
SnitcherKing bet 1.
MonisAddiction bet 69.
LimeadeSneaktar bet 1.
gunHeCK bet 0.
HardHatUmar bet 0.
RaysFive01K bet 22.
KaylorrCriterion bet 0.
HeCKuSumer bet 195.
PassivePanga bet 69.

Round 2
HeCKuSumer decided to !guncheck.
OC'sRandomTpyos decided to buy guard.
MonisAddiction decided to all in.
PassivePanga decided to !guncheck.
LimeadeSneaktar decided to double cross.
RaysFive01K decided to deposit.
SnitcherKing decided to finger.

Results
OC'sRandomTpyos failed. :(
SnitcherKing failed. :(
MonisAddiction was successful, and may gain ¥0
LimeadeSneaktar failed. :(
RaysFive01K failed. :(
HeCKuSumer failed. :(
PassivePanga failed. :(

And here, the probabilities dropped too low to win again--except for MonisAddiction, who went all in, and therefore avoided the probability modification incurred by the rabble backing out. No winnings are listed here, because a player who wins going all in immediately adds all winnings to its holdings without any possible modification by other players' actions.

Regras do jogo

Estrutura do torneio / jogo

  • O torneio consistirá em uma série de jogos escolhidos uniformemente aleatoriamente entre 1000 e 1100, nos quais todos os jogadores sérios envios estarão competindo simultaneamente de forma gratuita.
  • Todo jogador começa o primeiro jogo com 240 créditos e cada jogo subsequente com o número de créditos que possuía no final do jogo anterior.
  • Cada jogo prossegue em 2 rodadas e, em cada rodada, os jogadores são convocados em uma ordem determinada uniformemente aleatoriamente para tomar uma decisão:
    • Na primeira rodada, um jogador pode pagar qualquer número inteiro de créditos entre 0 e suas reservas de crédito atuais para participar da estaca em um assalto a banco.
    • Na segunda rodada, cada jogador que optar por participar do assalto apostando pelo menos um crédito (doravante denominado "heisters") pode decidir deixar sua aposta subir (e, ao fazê-lo, possivelmente realizar alguma outra ação), desative o assalto ou faça o all-in. (Essas opções são descritas mais abaixo).
  • Com base no número de heisters e no número total de créditos que eles pagaram, um dos cinco bancos é selecionado para realizar um assalto. Essa seleção afeta a probabilidade individual de vitória e as chances pelas quais o pagamento é determinado. (Os bancos estão descritos abaixo.)
  • Cada heister que não desistir, com a probabilidade (modificada) do banco, ganhará sua aposta multiplicada pelas probabilidades de apostas (modificadas) do banco (arredondadas para baixo) ou perderá sua aposta. Observe que o sucesso ou o fracasso de cada jogador é determinado individualmente - alguns terão sucesso onde outros falham.
  • Todos os jogadores, participando ou não, tiveram sucesso ou falharam e, em seguida, recebem um salário (com as exceções descritas abaixo).
  • Note que é impossível sair permanentemente do jogo. Na pior das hipóteses, um jogador pode ter que esperar um jogo para receber seu próximo salário.
  • Após todos os jogos de 1000 a 1100, o jogador com o maior número de créditos será declarado vencedor do torneio.
  • O torneio será repetido um número não especificado de vezes (o máximo que pode ser calculado em 48 horas) e os ganhos do jogador em todos os torneios somados para determinar o vencedor geral do concurso.

Segunda Rodada de Apostas

  • Qualquer jogador que tenha apostado uma aposta positiva no primeiro turno poderá participar do segundo turno.
  • Nesta rodada, um jogador pode:
    • responda com a string "back out" para cancelar sua aposta. Isso definirá sua aposta como zero para o assalto atual e também diminuirá ligeiramente a probabilidade de os jogadores restantes no assalto serem bem-sucedidos. Ao escolher esta opção, um jogador renuncia ao pagamento de 240 créditos que segue o assalto como punição por colocar os heisters restantes em risco. (Os heisters restantes terão sucesso com uma probabilidade igual à probabilidade do banco vezes a fração de heisters que não "desistiram".)
    • responda com a string "all in" para acabar com todas as suas participações em crédito - e contrair um empréstimo do dia de pagamento nos próximos 240 salários - para comprar todos os melhores equipamentos e informações para um assalto e entrar sozinho, armas em punho, sem confiando em alguém. A probabilidade de vitória de tal jogador não pode ser afetada por outros heisters que abandonam o assalto, nem seus ganhos podem ser roubados por traficantes. Os pagamentos vencedores serão determinados como se sua aposta fosse toda a sua posse de crédito mais 240, enquanto a perda definirá sua posse como zero.
    • Responda com qualquer outra string (incluindo a string vazia) para manter a aposta anterior e continuar com o assalto normalmente. (Resposta recomendada: "! Guncheck"). Certas respostas terão efeitos colaterais adicionais:
      • Uma resposta de "alterar trabalhos" fará com que o player saia do trabalho. A partir desta rodada, no final de cada rodada, o jogador terá 5% de chance de ser contratado em uma nova posição. Se isso der certo, o jogador é contratado e imediatamente recebe seu primeiro salário. É garantido que cada novo trabalho pague exatamente 5% a mais do que o último (arredondado para baixo). Esta ação será bem-sucedida, independentemente de o assalto ter êxito.
      • Uma resposta de "adquirir informação" fará com que, se o assalto for bem-sucedido, o jogador gaste todos os seus ganhos com esse assalto e obtenha 0,00001 extra por crédito, gastando com as probabilidades do banco que foi roubado apenas para esse jogador . Essa modificação de probabilidades é permanente. Por exemplo, se um jogador escolher essa ação ao receber o banco 1 e ganhar 6969 créditos em um assalto, as chances do banco 1 para esse jogador serão permanentemente aumentadas em 0,06969 e o jogador não receberá nada desse assalto.
      • Uma resposta de "guarda de compras" fará com que o jogador compre um dos guardas de segurança do banco que está sendo roubado. Em troca de uma redução permanente de 1 crédito no salário do jogador (suborno regular do guarda), o jogador receberá uma probabilidade de vitória aumentada "permanente" naquele banco (devido ao guarda "esquecer de mencionar" esse jogador aos policiais quando Perguntou). A probabilidade aumentará exatamente 1% da diferença entre a probabilidade de vitória atual do jogador nesse banco e 100%. Esta ação será bem-sucedida mesmo se o roubo falhar. NOTA: Se, a qualquer momento, um jogador não tiver créditos suficientes para pagar todos os seus subornos, ele imediatamente e "permanentemente" perderá tantos bônus de probabilidade quanto o número de subornos que não puderam ser pagos,
      • Uma resposta de "depósito" deixará, se o roubo for bem-sucedido, deixar os ganhos inteiros de um jogador em uma conta no banco roubado. Os créditos não serão acessíveis para nenhum propósito nem serão contados na pontuação de um jogador até serem retirados. Essa conta pagará juros a uma taxa de 0,14% por jogo.
      • Uma resposta de "retirada", se o roubo for bem-sucedido, adicionará aos ganhos de um jogador todo o conteúdo de sua conta no banco roubado. A conta será zerada como resultado. Observe que esses ganhos adicionais podem ser roubados por travessias duplas.
      • Uma resposta de "cruz dupla" fará uma de duas coisas:
        • Se o número de heisters que jogaram "cruzada dupla" for no máximo 1/10 (arredondado para baixo) do número total de heisters não-racionais que decidiram continuar com o assalto (ou exatamente um se houver menos de 10 desses jogadores) ), o jogador receberá ganhos adicionais iguais ao total de ganhos de todos os cruzadores não duplos, dividido pelo número de cruzadores duplos (arredondado para baixo). Todos os não-cruzadores duplos neste caso recebem 0 créditos do assalto. Em outras palavras, os traidores roubam os créditos de todos os outros e o dividem igualmente entre si.
        • Se o número de heisters que jogaram "cruzada dupla" exceder o limite, o jogador não receberá ganhos (se o seu roubo for bem-sucedido), terá seu salário cortado ao meio e será demitido de seu emprego. (Consulte "alterar tarefas".) Neste caso, todos os não-travesseiros duplos (incluindo o ralé) receberão um pagamento de bônus do total de ganhos de todos os travesseiros duplos dividido pelo número total de não-travesseiros duplos. Em outras palavras, a conspiração ficou grande demais para manter um segredo, os conspiradores foram extirpados e excluídos do assalto, e todos dividiram suas apostas por punição - e sua reputação de negociar sujo também lhes perdeu o emprego.
      • Uma resposta de "dedo" (como em "dedilhando um rato patife de cruzamento duplo"), se o assalto for bem-sucedido, dará ao jogador oito oportunidades (empatando uniformemente com a substituição do conjunto de batedores não-ralé) para identificar uma dupla cruzamento que ainda não foi identificado .
        • Cada dupla identificada dessa maneira pagará imediatamente ao fingerer 25% de suas reservas de crédito atuais (arredondadas para baixo) em vez de levar um tiro, perder o emprego e ter seu salário cortado pela metade (porque o chefe não tolerará mau comportamento) e perca 5% de sua probabilidade de vitória no banco que está sendo roubado (já que outros heisters suspeitam no futuro e provavelmente jogam embaixo do ônibus se as coisas ficarem peludas). Os cruzadores cruzados identificados dessa maneira não afetam se a cruzada cruzada foi bem-sucedida para outros cruzadores duplos, mas eles não recebem nenhum dos créditos roubados da cruzada dupla e os referidos créditos roubados serão redistribuídos de volta para os não cruzados. cruzadores duplos.
        • Se nenhuma cruzeta dupla for identificada dessa maneira, o informante ganhará pontos por desperdiçar o tempo de todos - e também pagará metade de seus ganhos com o assalto atual, fará um corte de 5% em seu salário (o chefe corta as horas do tattletale) e perde 5% de suas chances de apostas no banco atual (já que outros heisters têm menos probabilidade de serem generosos / justos com seus ganhos no futuro). A metade de seus ganhos perdidos será distribuída para os cruzadores duplos, se os cruzadores tiverem sucesso, ou os não cruzadores (incluindo ralé), se os cruzadores falharem.

Os bancos

O banco é selecionado usando o índice numheisters + int(totalamountbet/100000), onde numheisters é o número de jogadores que apostaram uma aposta positiva na rodada 1 e totalamountbet é a soma das apostas de todos esses jogadores. Em outras palavras, cem mil créditos são tão bons quanto 1 heister adicional. Com base nesse índice, um dos seguintes bancos será escolhido, o banco com o limite mais alto que o índice atender ou exceder:

Bank             Index Threshold   Victory Prob.  Bet Odds
----             ---------------   -------------  --------
0:Municipal                    0           0.540      0.80
1:City                        20           0.488      1.10
2:State                       40           0.425      1.30
3:National                    60           0.387      1.65
4:Federal Reserve             80           0.324      1.95

Observe que, à medida que o torneio continuar, a probabilidade de atingir o nível mais alto do banco aumentará, conforme o valor que cada jogador pode apostar em tendências para cima. Observe também que estes são apenas iniciais probabilidades e probabilidades , antes de serem modificadas por qualquer ação de "adquirir informações" ou "comprar um guarda". Com as probabilidades e probabilidades iniciais, apenas os bancos City e National esperavam ganhos superiores às perdas esperadas.

The Rabble

  • O torneio também contém 500 outros jogadores, chamados de "ralé", que participam como jogadores regulares de assaltos, mas não são pontuados no final. Isso serve para tornar cada jogo diferente e um pouco menos previsível, e possibilita alcançar os bancos mais arriscados / mais recompensadores, mesmo com apenas alguns jogadores "reais".
  • Cada jogo incluirá algum subconjunto de ralé para participar, escolhido aleatoriamente de maneira uniforme em todos os subconjuntos de ralé.
  • Todos os ralé usam a seguinte estratégia:
    • Escolha aleatoriamente apostar com probabilidade igual à probabilidade de sucesso no banco que seria selecionado com base nas decisões dos jogadores que já tomaram sua decisão nesta rodada .
    • Se você apostar um valor diferente de zero, escolha o maior dos seguintes valores que não excederiam as suas reservas atuais: 69, 420, 6969, 80085.
    • No segundo turno, "desistir" com probabilidade igual a 5% mais 50% da proporção de apostadores que já desistiram, caso contrário, assista como normal. (Observe que isso significa que os jogadores iniciantes do segundo turno que voltarem podem ter enormes efeitos em cascata entre a multidão - preste atenção e esteja pronto para o assalto desmoronar antes mesmo de começar.)

Entradas e saídas

Nas duas rodadas, os programas receberão as seguintes informações, exatamente nessa ordem, como argumentos de linha de comando . Salvo indicação em contrário, todos os valores são números inteiros que não contêm decimais.

  1. O número do jogo atual (indexado a zero)
  2. O número da rodada do jogo atual (1 ou 2)
  3. O número de jogadores no jogo atual (incluindo ralé).
  4. O número de jogadores que já se revezaram nesta rodada.
  5. O número de heisters que comprometeram uma participação positiva até agora. (Na segunda rodada, esse será realmente o número total de heisters que compraram na primeira rodada.)
  6. O número total de créditos investidos até o momento. (Na segunda rodada, este vai ser realmente o número total de créditos investidos no primeiro turno - em particular, que não incluem mais do que as apostas iniciais de "all in" heisters e não incluem as estacas de "voltar atrás" heisters.)
  7. O número de heisters que confirmaram no segundo turno (ou seja, não "desistiram"). Isso será zero durante a primeira rodada.
  8. O número (indexado a zero) do banco a ser roubado (durante a primeira rodada, o banco que seria roubado se ninguém mais apostasse)
  9. O número de créditos atualmente disponíveis para o jogador.
  10. O número de créditos que o jogador apostou na primeira rodada. (Isso é sempre zero na primeira rodada.)
  11. O número de créditos que o jogador receberá em seu salário no final de cada jogo.
  12. 1 se o jogador estiver recebendo um cheque de pagamento, 0 se o jogador estiver desempregado
  13. Classificação do jogador na tabela de classificação (não incluindo ralé) no final do jogo anterior, com 1 índice. (Definido como 1 + o número de jogadores com estritamente mais créditos naquele momento. Por exemplo, durante o primeiro jogo, todos os jogadores têm a classificação 1.)
  14. O número médio de créditos mantidos por todos os jogadores (não incluindo ralé) (representado como um número decimal)
  15. O desvio médio absoluto no número de créditos mantidos por todos os jogadores (não incluindo ralé) (representado como um número decimal)
  16. O número máximo de créditos mantidos por qualquer jogador (ou seja, o número de créditos mantidos por um jogador de nível 1, não incluindo ralé)
  17. O número de créditos que o jogador armazenou na conta do banco 0
  18. Conta do banco 1
  19. Conta do banco 2
  20. Conta do banco 3
  21. Conta do banco 4
  22. Probabilidade de vitória individual do jogador no banco 0
  23. Probabilidade do banco 1
  24. Probabilidade do banco 2
  25. Probabilidade do banco 3
  26. Probabilidade do banco 4
  27. As probabilidades de pagamento individual do jogador após um assalto bem sucedido no banco 0
  28. Probabilidades do banco 1
  29. Probabilidades do banco 2
  30. Probabilidades do banco 3
  31. Probabilidades do banco 4

Na primeira rodada de um jogo, um programa de jogador deve imprimir para indicar um número inteiro entre 0 e o número total de créditos na conta desse jogador. Qualquer valor de aposta maior que o saldo de crédito disponível é considerado uma aposta máxima. Qualquer outra saída (ou condição de erro) será interpretada como uma aposta zero.

Na segunda rodada de um jogo, o programa de um jogador deve ser impresso para incluir uma sequência como descrito na seção "A segunda rodada de apostas" acima. Uma condição de erro aqui é considerada a ação padrão: prossiga com o assalto normalmente.

Controlador

O torneio será realizado usando este controlador . Exemplos de bot lá também. Ainda em teste. Mais código por vir. Sinta-se livre para enviar correções de bugs (no github). Será atualizado se alguma regra mudar também.

Para executar um único torneio em sua própria máquina, adicione uma linha ao concorrentes.txt e use:

python bankheist.py 1000

Regras do concurso

  • Os jogadores podem enviar qualquer número de programas de jogadores em qualquer idioma disponível gratuitamente, cujos programas podem receber argumentos de linha de comando.
  • Os envios devem incluir instruções bastante explícitas sobre como compilar programas e executá-los no meu PC, incluindo nomes de ferramentas necessárias e comandos exatos a serem emitidos. O envio deve incluir pelo menos um comando que execute o programa e pode ter argumentos de linha de comando anexados diretamente a ele.
  • Os envios também devem ter um nome exclusivo para identificá-los (que não contém espaços).
  • Os programas devem ser executados em um período razoavelmente curto. (Não estou definindo um limite superior para o que constitui razoável. Em vez disso, simplesmente aconselharei o criador a qualquer entrada que pareça ter um tempo de execução grande demais para agilizá-la.)
  • Os programas podem não ler ou gravar em arquivos. Nem podem usar qualquer outro método para armazenar informações entre execuções. O objetivo desse desafio é tomar decisões complexas com base em informações limitadas / resumidas.
  • Toda e qualquer uma dessas regras está sujeita a alterações a qualquer momento, se necessário. Uma mensagem será adicionada na parte superior desta postagem indicando essas alterações.
  • Este concurso termina no prazo de uma semana após o último usuário enviar as postagens de seu primeiro envio . Modificações de envios existentes são permitidas a qualquer momento até o término do concurso. Farei o possível para manter o prazo atual atualizado em uma mensagem na parte superior desta postagem.
  • Este concurso termina no máximo uma semana após a última alteração das regras, se houver. Farei o possível para deixar comentários para qualquer usuário afetado por qualquer alteração de regra.
  • É melhor você apostar que eu vou participar deste concurso. ;)
quintopia
fonte
Comentários não são para discussão prolongada; esta conversa foi movida para o bate-papo .
Dennis
Talvez porque eu não esteja familiarizado com o twitch ou o jogo do assalto, mas há muitas regras que podem ser melhor demonstradas com um pequeno exemplo (s) trabalhado (s). No momento, não parece muito acessível.
21817 Moogie
Rei da colina? Não ouço esse nome há anos.
Beta Decay

Respostas:

6

Alguns exemplos "ruins" de programas.

Estes são alguns bots que escrevi para testar o controlador. Principalmente, eles fazem o mínimo necessário para testar um tipo específico de ação. Dependendo do nível de participação neste KotH, de alguns a todos esses itens serão incluídos no torneio final, já que grande parte da estratégia do jogo virá de lidar com o comportamento de muitos bots diferentes.

Incluo todos aqui principalmente como exemplos de "uso".

Lurker

Nunca aposte. Se você não está superando isso, repense sua estratégia.

print 0

PassivePanga

Sempre aposte 69.

import sys


round = int(sys.argv[2])
myyattas = int(sys.argv[9])
if round == 1:
    if myyattas > 69:
        print "69"
    else:
        print "0"
else:
    print "!guncheck"

KaylorrCriterion

Faça uma aposta Kelly se, e somente se, o Critério Kelly for atendido. Como isso raramente acontece com algumas "adquirir informações" e "comprar guarda" primeiro, isso geralmente obtém o mesmo resultado que Lurker.

import sys
import ast
game,round,numplayers,alreadyplayed,numbet,yattasbet,numready,bankid,myyattas,mybet,mypayment,hired,myrank,mu_yattas,sigma_yattas,max_yattas = map(ast.literal_eval,sys.argv[1:17])
bankholdings = map(int,sys.argv[17:22])
bankprobs = map(float,sys.argv[22:27])
bankodds = map(float,sys.argv[27:32])

def get_bank(bettors,credits):
    selector = min(4,int(bettors+int(credits/100000.)/20))
    return bankprobs[selector],bankodds[selector]



if round == 1:
    if alreadyplayed < 0.37*numplayers or numbet==0:
        print 0
        #sys.stderr.write("1: %d,%d\n"%(alreadyplayed,numbet))
    else:
        ratiosofar = numbet/float(alreadyplayed)
        bettors = ratiosofar * numplayers
        ratesofar = yattasbet/float(numbet)
        credits = bettors*ratesofar
        p,b = get_bank(bettors,credits)
        f = (p*(b+1)-1)/b
        print max(int(f*myyattas),0)
        #sys.stderr.write("2: %d,%d\n"%(p,b))
else:
    if alreadyplayed < 0.37*numbet or numbet==0:
        print "!guncheck"
    else:
        p,b = get_bank(numbet,yattasbet)
        realp = p*numready/float(alreadyplayed)
        f = (realp*(b+1)-(1-240./(myyattas+240.)))/b
        print "!guncheck" if f>0 else "back out"

gunHeCK

Fazer uma aposta Kelly se e somente se o número de heisters visto até agora indicam que a aposta vai cumprir o critério de Kelly (mas não voltar atrás se errado). Normalmente faz pior do que Lurker

import sys
import ast
game,round,numplayers,alreadyplayed,numbet,yattasbet,numready,bankid,myyattas,mybet,mypayment,hired,myrank,mu_yattas,sigma_yattas,max_yattas = map(ast.literal_eval,sys.argv[1:17])
bankholdings = map(int,sys.argv[17:22])
bankprobs = map(float,sys.argv[22:27])
bankodds = map(float,sys.argv[27:32])

def get_bank(bettors,credits):
    selector = min(4,int(bettors+int(credits/100000.)/20))
    return bankprobs[selector],bankodds[selector]

if round == 1:
    if alreadyplayed < 0.37*numplayers or numbet==0:
        print 0
        #sys.stderr.write("1: %d,%d\n"%(alreadyplayed,numbet))
    else:
        ratiosofar = numbet/float(alreadyplayed)
        bettors = ratiosofar * numplayers
        ratesofar = yattasbet/float(numbet)
        credits = bettors*ratesofar
        p,b = get_bank(bettors,credits)
        f = (p*(b+1)-1)/b
        print max(int(f*myyattas),0)
        #sys.stderr.write("2: %d,%d\n"%(p,b))
else:
    print "!gunHeCK"

Moni'sAddiction

Vá "all in", a menos que já esteja ganhando.

import sys
import random


round = int(sys.argv[2])
myrank = int(sys.argv[13])
mybet = int(sys.argv[10])

if round == 1:
    if random.random()<0.1:
        print 1
    else:
        print 69
else:
    if myrank>1:
        print "all in"
    else:
        if mybet==1:
            print "back out"
        else:
            print "!guncheck"

HeCKuSumer

Sempre aposte uma pequena fração constante de participações.

import sys

round = int(sys.argv[2])
myyattas = int(sys.argv[9])

if round==1:
    print int(0.1*myyattas)
else:
    print "!guncheck"

OC'sRandomTpyos

Mude muito de emprego no início do torneio. Gaste todo esse dinheiro melhorando probabilidades e probabilidades. Depois, passe os últimos jogos participando all in. Isso provavelmente seria muito melhor sem o all in, a menos que já esteja em primeiro lugar.

import sys
import ast
import random

game,round,numplayers,alreadyplayed,numbet,yattasbet,numready,bankid,myyattas,mybet,mypayment,hired,myrank,mu_yattas,sigma_yattas,max_yattas = map(ast.literal_eval,sys.argv[1:17])
bankholdings = map(int,sys.argv[17:22])
bankprobs = map(float,sys.argv[22:27])
bankodds = map(float,sys.argv[27:32])

if round == 1:
    if game<800 or myrank>3:
        print 1
    else:
        print myyattas/4
else:
    if game<800:
        if hired:
            print "change jobs"
        else:
            print random.choice(["acquire intel","buy guard"])
    else:
        if myrank>3:
            print "all in"
        else:
            print "!guncheck"

HardHatUmar

Altera os trabalhos sempre que possível durante a maior parte do torneio. Evita apostar mais do que o mínimo necessário. Decentemente bem, mas não ótimo.

import sys

game = int(sys.argv[1])
round = int(sys.argv[2])
hired = int(sys.argv[12])

if round==1:
    if game < 900 and hired:
        print 1
    else:
        print 0
else:
    print "change jobs"

LimeadeSneaktar

Troque de emprego sempre que possível durante a primeira parte do torneio. Passe todos os outros jogos em travessia dupla. Decentemente se sai bem contra o SnitcherKing. Provavelmente se sairá mais mal quando muitos outros bots estiverem cruzando e digitando. Caso contrário - as regras podem precisar ser alteradas.

import sys
import ast

game,round,numplayers,alreadyplayed,numbet,yattasbet,numready,bankid,myyattas,mybet,mypayment,hired,myrank,mu_yattas,sigma_yattas,max_yattas = map(ast.literal_eval,sys.argv[1:17])
bankholdings = map(int,sys.argv[17:22])
bankprobs = map(float,sys.argv[22:27])
bankodds = map(float,sys.argv[27:32])

if round==1:
    print 1
else:
    if hired and game<900:
        print "change jobs"
    else:
        print "double cross"

SnitcherKing

Sempre aposte o mínimo e sempre o dedo. Se sai muito bem em pequenos torneios que incluem o LimeadeSneaktar.

import sys

round = int(sys.argv[2])

if round == 1:
    print 1
else:
    print "finger"

RaysFive01K

Um pouco mais complicado - e, portanto, realmente muito bom. A maior parte de sua vantagem vem do depósito de todos os ganhos no início do torneio (protegendo-os de travessias duplas), aumentando as probabilidades de vitória (e mudando de emprego para pagar por todos aqueles guardas e roubos) e depois retirando-os todos no final do jogo ( uma vez que eles ganhem interesse sério e a probabilidade de não se retirar seja suficientemente baixa - embora aqui as perdas para travessias duplas sejam um risco sério). Definitivamente, isso estará no torneio e pode ou não ser um candidato sério.

import sys
import ast
import random
game,round,numplayers,alreadyplayed,numbet,yattasbet,numready,bankid,myyattas,mybet,mypayment,hired,myrank,mu_yattas,sigma_yattas,max_yattas = map(ast.literal_eval,sys.argv[1:17])

bankholdings = map(int,sys.argv[17:22])
bankprobs = map(float,sys.argv[22:27])
bankodds = map(float,sys.argv[27:32])

if round ==1:
    if game < 900:
        print myyattas/10
    else:
        print 1
else:
    if game < 500 and hired:
        print random.choice(["change jobs","finger","buy guard"])
    elif game < 900:
        print "deposit"
    elif bankholdings[bankid]>0:
        print "withdraw"
    else:
        if alreadyplayed/float(numplayers)<0.5:
            print "finger"
        else:
            print "back out"
quintopia
fonte
Eu aprovo essas denominações <insert Twitch & Panga memes>
CAD97
2

John solitário

import sys
import ast

game,round,numplayers,alreadyplayed,numbet,creditsbet,numready,bankid,mycredits,mybet,mypayment,hired,myrank,mu_credits,sigma_credits,max_credits = map(ast.literal_eval,sys.argv[1:17])

bankholdings = map(int,sys.argv[17:22])
bankprobs = map(float,sys.argv[22:27])
bankodds = map(float,sys.argv[27:32])

if round == 1:
    if mycredits > 100 or hired:
        print(int(mycredits)/2)
    else:
        print(0)
else:
    if bankprobs[int(bankid)] > 0.6:
        print("all in")
    elif int(mypayment) > 50 :
        print("buy guard")
    elif int(mycredits) > 200 and int(game) < 900 and hired == "1":
        print("change jobs")
    elif bankprobs[int(bankid)] * (float(numready)+1)/(float(alreadyplayed)+1) < 0.30:
        print "withdraw"
    else:
        print "!guncheck"

Suborna os guardas até que ele tenha a probabilidade de vencer, depois entra all in. Sozinho.

Muda de emprego quando precisa de mais dinheiro para subornar guardas.

MegaTom
fonte
como é esse jogador?
quintopia
@quintopia ops! Esqueci que consegui postar! Nome e explicação adicionados.
MegaTom
Agradável. Apenas como uma dica, você não precisa fazer todas essas previsões. Tudo já é do tipo certo de ser avaliado imediatamente. O que significa que a condição hired == "1"sempre será falsa e nunca mudará de emprego.
quintopia
Eu apenas corri em uma única rodada contra todos os outros que fiz. Veio em último lugar. Má sorte :(
quintopia