Mafia (também conhecido como Lobisomem) é um jogo de festa que é mais ou menos assim:
- O jogo começa no dia 0. Depois de cada dia
n
chega uma noiten
. Depois de toda noiten
chega o dian+1
. ieD0, N0, D1, N1, D2, N2
... - No início do dia 0, um anfitrião escolhe secretamente os jogadores para desempenhar certas funções:
- Algum número de jogadores se torna a máfia. Toda noite, todo mafioso escolhe um jogador. Ao amanhecer do dia seguinte, o jogador escolhido pelos mais mafiosos é morto. Eles são permanentemente removidos do jogo e seu papel é revelado publicamente. Alinhado à máfia.
- Algum número de jogadores se torna policial. Toda noite, cada policial escolhe um jogador. No amanhecer do dia seguinte, o policial toma conhecimento do alinhamento dos jogadores. Alinhado pela vila.
- Algum número de jogadores se torna médico. Toda noite, cada médico escolhe um jogador. Se este jogador for o mesmo que a máfia escolheu matar, as ações da máfia naquela noite serão canceladas. Alinhado pela vila.
- Todos os jogadores que não são escolhidos para outro papel são aldeões. Os moradores não têm habilidades que não são compartilhadas por toda a cidade. Alinhado pela vila.
- Todos os dias, exceto o dia 0, a cidade inteira (ou seja, todos os jogadores vivos) vota em um jogador. No final do dia, esse jogador é removido do jogo e seu papel é revelado. (No dia 0, todos relaxam até o anoitecer.)
- Se, a qualquer momento, não houver mafiosos restantes, o jogo termina com todos os jogadores alinhados à aldeia vitoriosos (incluindo os mortos).
- Se, a qualquer momento, os jogadores alinhados à aldeia não superarem os jogadores alinhados à máfia, o jogo terminará com todos os jogadores alinhados à máfia vitoriosos (incluindo os mortos).
Para esse desafio, seu objetivo é escrever um bot para vencer outros bots na Mafia!
Como fazer um bot funcionando
Tudo o que você precisa fornecer para mim é um arquivo chamado run
. Dentro da estrutura de diretórios em que esse desafio ocorrerá, seu bot viverá aqui:
start
controller/
tmp/
players/ # You are here!
some_bot/ # Let's pretend you're some_bot.
to_server
from_server
players
run # This is what you give me
mafia-game-bot/
skynet/
O run
arquivo, quando executado, fará com que seu bot faça seu trabalho. É importante observar que esse arquivo não deve exigir argumentos de linha de comando ou algo assim. Será executado exatamente como ./run
. Se você precisar ser executado de uma maneira diferente, precisará contorná-lo fazendo algo assim:
real_bot.py
#!/bin/python2
# code goes here
run
#!/bin/bash
./real_bot.py --flags --or --whatever
Uma coisa importante a ser observada é que todas as entradas recebidas pelo bot serão encontradas no arquivo from_server
e o programa de controle procurará a saída do bot to_server
. Eu escolhi fazer dessa maneira para que qualquer idioma que possa fazer a E / S de arquivo possa participar. Se seu idioma facilitar o trabalho com stdin e stdout do que com E / S de arquivos, você pode escrever um run
arquivo parecido com este:
#!/bin/bash
./real_bot.py < from_server > to_server
Isso fará com que stdin venha do from_server
arquivo e stdout vá diretamente para to_server
.
Seu bot não ficará em execução durante o jogo. Em vez disso, ele será executado quando precisar tomar uma decisão. Da mesma forma, ele não será informado quando estiver morto, apenas não será mais executado. Planeje isso salvando tudo o que deseja lembrar em um arquivo e lendo-o mais tarde. Você pode criar, gravar ou ler qualquer arquivo na pasta do seu bot, mas não pode escrever ou ler em qualquer lugar fora dessa pasta, incluindo acesso à rede ou qualquer outra coisa . Se o seu bot souber algo que não foi informado de dentro da pasta, ou se tocar em algo que não está nessa pasta, seu bot será desqualificado.
Como fazer um bot funcional
Dia
No início do jogo, o arquivo players
será preenchido com uma lista delimitada por nova linha de todos os jogadores no jogo. Não será atualizado quando os jogadores saírem do jogo.
No início do dia 0, todos os jogadores encontrarão esta mensagem em seu from_server
arquivo:
Rise and shine! Today is day 0.
No voting will occur today.
Be warned: Tonight the mafia will strike.
Se você é o policial, a linha You are the cop
é anexada ao final. O médico vê You are the doctor
. A máfia vê You are a member of the mafia.\nYour allies are:
e uma lista delimitada por nova linha de membros da máfia, excluindo o jogador que está lendo a mensagem.
No início de todos os outros dias, esta mensagem aparecerá:
Dawn of day `day_number`.
Last night, `victim` was killed. They were `victim_role`.
Investigations showed that `cop_target` is `target_alignment`-aligned.
These players are still alive: `remaining_players`
dayNumber
é substituído pelo número do dia. victim
é substituído pelo nome da vítima da noite passada e victim_role
é um dos seguintes:
a villager
a mafioso
the cop
the doctor
cop_target
é o nome do jogador que o policial investigou na noite passada e target_alignment
é village
ou mafia
. Finalmente, remaining_players
é uma lista de jogadores que ainda estão vivos neste formato:player1, player2, player3
A segunda linha é omitida se não houve morte ontem à noite, e a terceira linha é mostrada apenas para o policial.
Por exemplo,
Dawn of day 42.
Last night, Xyzzy was killed. They were a villager.
Investigations showed that Randy is mafia-aligned.
These players are still alive: Randy, CopBot, JohnDoe, Steve
Uma vez que esta mensagem está fora do caminho, o dia começa! Cada bot pode realizar 50 ações ao longo do dia, onde uma "ação" está votando em um jogador ou dizendo algo em voz alta.
Para votar em um jogador, escreva vote player_name
no seu to_server
arquivo e termine. Para votar para não matar ninguém, escreva vote no one
. Quando você votar, todos os jogadores (incluindo você) verão your_bot votes to kill your_selection
. Os votos são ignorados no dia 0.
Um número de mensagens predefinidas pode ser enviado a todos os jogadores. O ID de cada mensagem possível está listado aqui:
0: No
1: Yes
2: I am the cop
3: I am the doctor
4: I am a normal villager
5: I trust this player:
6: I think this player is suspicious:
7: I think this player is the cop:
8: I think this player is the doctor:
9: I think this player is a normal villager:
10: I think this player is mafia:
11: Do you think this player is mafia?
12: I tried to save this player:
13: I successfully saved this player:
14: I investigated this player and found that they were mafia-aligned:
15: I investigated this player and found that they were village-aligned:
16: Will you please use your power on this player tonight?
Todas essas mensagens, exceto as cinco primeiras, estão se referindo a um jogador específico. Para dizer uma dessas mensagens, escreva say message_id player_name
. Para uma das cinco primeiras mensagens, basta escrever say message_id
. Você pode adicionar um terceiro argumento opcional a ambos, especificando o nome do jogador com quem está falando (todos os jogadores ainda podem lê-lo, mas saberão quem é o destinatário pretendido).
Quando o seu bot diz uma mensagem, todos os jogadores leem your_bot says "message"
, onde message
está a mensagem associada ao ID que você escreveu. Se a mensagem incluir um assunto, um caractere de espaço e o assunto serão inseridos diretamente após o final da mensagem. Se incluir um destinatário, seu nome, dois pontos e um caractere de espaço serão inseridos imediatamente antes da mensagem.
No final do dia, todos os jogadores vivos são disputados uma última vez para ver o resultado da votação. Se um jogador foi eliminado, está escrito:
The town has killed player_name!
They were a villager
... ou a mafioso
, ou the cop
, ou the doctor
.
Se nenhum jogador foi votado, isto está escrito:
The town opted to lynch no one today.
Quando o controlador envia essas mensagens, ele ignora qualquer resposta dos jogadores. O dia acabou.
Noite
À noite, todos, menos os moradores, usam seu poder.
Máfia:
Você vai ler It is night. Vote for a victim.
. Quando isso acontecer, digite o nome do jogador que você gostaria de matar.
Policial:
Você vai ler It is night. Who would you like to investigate?
. Quando isso acontece, imprima o nome do player que você deseja verificar.
Médico:
Você vai ler It is night. Who would you like to save?
. Quando isso acontecer, digite o nome do jogador que você deseja proteger.
Depois disso, o dia seguinte começa normalmente.
Você pode se salvar apenas uma vez por jogo.
Informação geral
- O jogo não será executado sem 6 ou mais jogadores.
- Um terço dos jogadores, arredondados, será da máfia. Um jogador será médico e um jogador será policial. Todos os outros jogadores são aldeões.
- Os laços no voto da aldeia ou o voto da máfia da noite para o dia são resolvidos aleatoriamente.
- Os nomes dos bot devem ser alfanuméricos + traços e sublinhados.
- É proibido usar o conhecimento do código do oponente diretamente. Em teoria, eu deveria ser capaz de colocar seu bot contra bots que você nunca viu antes e ter um desempenho comparável.
- Lamentavelmente, se eu não conseguir executar seu programa usando software exclusivamente gratuito (como em cerveja), terei que desqualificá-lo.
- Reservo-me o direito de desqualificar qualquer envio, se achar que é malicioso. Isso inclui, mas não se limita ao uso excessivo de tempo, memória ou espaço para execução. Intencionalmente deixei o limite baixo, mas lembre-se: estou executando isso no meu computador doméstico, não em um supercomputador, e não quero que os resultados levem um ano. Não espero ter que usar isso, pois meus padrões são bem baixos. Isso é basicamente "se eu acho que você está sendo um idiota de propósito", e se você pode me convencer do contrário, vou reverter minha decisão.
Pontuação
A cada rodada, 100 jogos serão executados (isso pode aumentar à medida que mais bots se juntam para manter o tamanho da amostra grande o suficiente, mas na teoria isso não afeta nada). Vou gravar quantas vezes cada bot vence como aldeão em comparação com quantas vezes ele joga como aldeão, e o mesmo para a máfia. Um bot villager_ratio
é number of games won as villager / number of games played as villager
, e mafia_ratio
é o mesmo, mas s/villager/mafia/g
. A pontuação de um bot é (villager_ratio - mean villager_ratio) + (mafia_ratio - mean mafia_ratio)
.
Exemplo de bot
Randy, o robô, não é um bom jogador da máfia. Randy ignora praticamente tudo, escolhendo aleatoriamente o que dizer, em quem votar e em quem mirar com poderes noturnos.
run.sh
:
#!/bin/bash
./randy.py < from_server > to_server
randy.py
:
#!/usr/bin/env python
import random
with open('players') as f:
p = f.read().split() + ['no one']
day = True
try:
line = raw_input()
if line.endswith(('?', 'victim.')):
day = False
if not day:
print random.choice(p)
else:
if random.random() > 0.5:
if random.random() > 0.5:
print 'vote {}'.format(random.choice(p))
else:
id = random.randint(0, 17)
print 'say {}{}'.format(id, (' ' + random.choice(p)) if id > 4 else '')
except: pass
Controlador
O @undergroundmonorail escreveu um programa de controle para esse desafio, disponível aqui .
Você tem um mês para codificar e entregar as respostas. Eu darei ao bot vencedor (o desempate com maior taxa de vitória é o voto) pelo menos uma recompensa de 50 reputação (dependendo de quanto rep eu posso ganhar em um mês)
Aqui está um script de wrapper, criado por @Blacksilver, para usar com idiomas compilados:
#!/bin/bash
run="./a.out"
compile="gcc bot.c"
if [ -e $run ]; then
$run
else
$compile
$run
fi
Coloque isso run
.
Este post foi escrito por @undergroundmonorail (fiz algumas edições).
Ele o entregou aqui para quem quisesse terminar e publicá-lo.
fonte
Respostas:
zulu
run
Nem tudo o que eu esperava que fosse. Eu posso acabar mexendo de vez em quando.
Como funciona v1.0
Controla o número do dia, quem está vivo, quem está morto, quem é máfia, quem está alinhado com a aldeia, papéis, votos / mensagens do dia atual e votos / mensagens gerais.
Noite
uma. Máfia - vote em qualquer morador que tenha votado contra a máfia (aleatoriamente), se possível, caso contrário, um morador aleatório.
b. Policial - Investigue quem é de alinhamento desconhecido.
c. Médico - salve a si próprio primeiro turno, depois salve o policial se souber (acho que nunca saberá disso a partir de agora), salve o aldeão se souber (provavelmente também não sabe disso), caso contrário salve uma pessoa aleatória.
Dia
uma. Se alguém falou uma mensagem diretamente para si mesmo, responda a eles (respostas limitadas são possíveis).
b. Máfia - vote no aldeão com mais votos.
c. Aldeão com qualquer conhecido vivo alinhado à Máfia - vote em mafioso.
d. Aldeão conhecido apenas como morto pela máfia - vote em um bot aleatório que nunca votou no mafioso.
e Aldeão com policial conhecido - vote no bot aleatório em que o policial votou.
f. Aldeão com mortos conhecidos alinhados com a aldeia - vote em um bot aleatório que votou nos mortos.
g. Aldeão com votos contra o voto próprio para o bot mais alto atualmente não alinhado com a aldeia.
fonte
O código de exemplo não funcionou para mim, eu uso o Python 3, então alterei o
main.py
arquivo para fazê-lo funcionar.Então, aqui está a minha versão fixa para o Python 3, eu nunca programei em Python antes, talvez seja um código horrível, mas funcione :)
run.sh
:randy.py
:Algumas coisas que aprendi enquanto fazia esse trabalho (e não estava claro para mim na descrição)
print
não faz nada com o jogo é como umconsole.log
em jsinput()
bloqueia o programa em execução, pode ser bom para depuração passo a passofrom_server
eto_server
é limpo a cada rodada.Ctrl+C
combinação, o que é irritante.fonte
run.sh
.< from_server > to_server
é necessário porque codifiquei os nomes de arquivos no código. o mecanismo de jogo simplesmente liga./run
sem canos. entãoinput()
eprint()
não funcionou com o jogo.mayn.py
linha 57:os.system('./run')
randy.py
foi escrito em Python 2 , o que causou os problemas../start
da pasta original ou você precisa de uma versão python 3 do arquivomain.py
The Logician
Fantasia, longo monte de código python que eu não vou explicar (embora não seja um jogo de golfe), além de manter listas de "amigos" e "inimigos" que são originalmente preenchidos com base em chances e / ou investigação policial . Aviso: não fique na presença do lógico.
fonte
run.sh
padrão (fazer alguns testes)Sobrevivente (v 1.0)
Sinopse
O Survivalist simplesmente sobrevive brutalmente ao jogo, repreendendo qualquer um que se atreve a acusá-lo, independentemente de ser ou não máfia.
Lógica
Se você sobreviver até o final do jogo, você ganha, não importa o quê. Portanto, você sobrevive a todo custo.
História de fundo
As tropas marcharam pela floresta úmida e escura.
"Tenente, onde estamos marchando?" O jovem recruta aparentemente não se endureceu com atrocidades, pensou o comandante. Ah bem. Ele respondeu com um brusco "para destruir o inimigo".
Na vila, o comandante inimigo estava bebendo e rindo junto com os outros oficiais do clube quando um batedor apareceu com as notícias. "Há uma coluna, com várias centenas de metros de comprimento, marchando pela floresta Yulin para nós! Reúna as tropas!"
O comandante inimigo, obviamente embriagado, disse inesperadamente: "Não recebi relatos de outros batedores". O batedor (mais tarde sobrevivente) pensou, então terei que reunir as tropas eu mesmo . Depois de contar a história aos companheiros, eles voltaram juntos, todos dizendo que haviam visto tropas inimigas. O comandante ainda não acreditou, dizendo: "Estou ordenando que você interrompa o escotismo. Não há tropas inimigas".
Os batedores decidiram pegar suas armas para salvar a comunidade. Eles conseguiram chegar a suas posições assim que o inimigo chegou à vila em vigor. "CARREGAR!" gritou o comandante da emboscada. "QUEIME AS CASAS! QUEIME AS CASAS! MATE TODOS, INCLUINDO AS MULHERES E AS CRIANÇAS! "
Os batedores salvaram todo o exército. Eles esperavam promoção, prêmios e medalhas. Em vez disso, receberam uma corte marcial fraudulenta por motim, condenação, 10 anos de prisão, dispensa desonrosa dos militares e exílio.
Há um ancião idoso no conselho da cidade de Salem, Massachusetts. Diz a lenda que ele fundou a cidade. Quando você o encontrar em sua cabana isolada na floresta, não deixe o brilho nos olhos dele fazer você pensar que ele é pacífico. Se você o acusar, ele o arruinará em frente à cidade.
Veterano
Código (eu sou um novato em python, não tenho certeza se o código é bom)
fonte
or
vez de||
? Você testou? Além disso, você provavelmente deve apontar que é Python 2.Avatar
O avatar "aleatoriamente" escolhe um jogador no início e o concentra incansavelmente pelo resto da rodada.
Esta não é uma referência a um programa de TV animado com o mesmo nome.
Baixe o tar de todos os arquivos necessários
Changelog
stdout
, apenas parastderr
.Para suprimir
stderr
também, adicione2>/dev/null
no final dorun
arquivo.Requer
mafia.c
emafia.h
, bibliotecas que escrevi, no mesmo diretório.Eles estão incluídos no download, junto com um Makefile e um script de execução.
FAÇAM
Enquanto estiver aqui, enviarei o não bot, Steve:
fonte
avatar
,erebus
,leviathan
, eragnarok
from_server
arquivo do meu bot não está sendo gravado. Você precisou definir permissões específicas ou algo assim?Leviatã
O Leviathan repete todos os jogadores no
players
arquivo e os direciona um a um.Baixar
Como no Avatar, ele requer
mafia.c
emafia.h
no mesmo diretório.Eles estão incluídos no download, junto com um Makefile e um script de execução.
fonte