Mafia (también conocido como Werewolf) es un juego de mesa que se juega más o menos así:
- El juego comienza el día 0. Después de cada día
n
llega una nochen
. Después de cada nochen
llega un dían+1
. es decirD0, N0, D1, N1, D2, N2
... - Al amanecer del día 0, un anfitrión elige en secreto a los jugadores para cumplir ciertos roles:
- Algunos jugadores se convierten en la mafia. Cada noche, cada mafioso elige un jugador. Al amanecer del día siguiente, el jugador elegido por los más mafiosos es asesinado. Se eliminan permanentemente del juego y su papel se revela públicamente. Alineado con la mafia.
- Algunos jugadores se convierten en policías. Todas las noches, cada policía elige un jugador. Al amanecer del día siguiente, el policía se da cuenta de la alineación de los jugadores. Alineado con el pueblo.
- Algunos jugadores se convierten en médicos. Todas las noches, cada médico elige un jugador. Si este jugador es el mismo jugador que la mafia decidió matar, las acciones de la mafia para esa noche se cancelan. Alineado con el pueblo.
- Todos los jugadores que no son elegidos para otro papel son aldeanos. Los aldeanos no tienen habilidades que no sean compartidas por toda la ciudad. Alineado con el pueblo.
- Todos los días, excepto el día 0, toda la ciudad (es decir, todos los jugadores vivos) vota por un jugador. Al final del día, ese jugador es eliminado del juego y se revela su papel. (El día 0, todo el mundo se relaja hasta el anochecer).
- Si, en algún momento, no quedan mafiosos restantes, el juego termina con todos los jugadores alineados en la aldea victoriosos (incluidos los muertos).
- Si, en algún momento, los jugadores alineados con la aldea no superan en número a los jugadores alineados con la mafia, el juego termina con todos los jugadores alineados con la mafia victoriosos (incluidos los muertos).
Para este desafío, tu objetivo es escribir un bot para vencer a otros bots en Mafia.
Cómo hacer un bot que funcione
Todo lo que tiene que proporcionarme es un archivo llamado run
. Dentro de la estructura de directorios donde tendrá lugar este desafío, su bot vivirá aquí:
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/
El run
archivo, cuando se ejecute, hará que su bot haga lo suyo. Es importante tener en cuenta que este archivo no debe requerir ningún argumento de línea de comando ni nada. Se ejecutará exactamente como ./run
. Si necesita ser ejecutado de una manera diferente, tendrá que solucionarlo haciendo algo como esto:
real_bot.py
#!/bin/python2
# code goes here
run
#!/bin/bash
./real_bot.py --flags --or --whatever
Una cosa importante a tener en cuenta es que todas las entradas que recibe su bot se encontrarán en el archivo from_server
y el programa de control buscará la salida de su bot to_server
. Elegí hacerlo de esta manera para que cualquier idioma que pueda hacer archivos de E / S pueda participar. Si su idioma facilita el trabajo con stdin y stdout que la E / S de archivo, es posible que desee escribir un run
archivo que se vea así:
#!/bin/bash
./real_bot.py < from_server > to_server
Esto hará que stdin provenga del from_server
archivo y stdout vaya directamente a to_server
.
Tu bot no se mantendrá en funcionamiento mientras dure el juego. En su lugar, se ejecutará cuando necesite tomar una decisión. Del mismo modo, no se le informará cuando esté muerto, simplemente ya no se ejecutará. Planifique esto guardando todo lo que quiera recordar en un archivo y leyéndolo más tarde. Puede crear, escribir o leer desde cualquier archivo en la carpeta de su bot, pero no puede escribir ni leer en ningún lugar fuera de esa carpeta, incluido el acceso a la red o cualquier cosa . Si su bot sabe algo que no se le dijo desde dentro de la carpeta, o si toca algo que no está dentro de esa carpeta, su bot está descalificado.
Cómo hacer un bot funcional
Día
Al comienzo del juego, el archivo players
se completará con una lista delimitada por la nueva línea de todos los jugadores en el juego. No se actualizará cuando los jugadores abandonen el juego.
Al amanecer del día 0, todos los jugadores encontrarán este mensaje en su from_server
archivo:
Rise and shine! Today is day 0.
No voting will occur today.
Be warned: Tonight the mafia will strike.
Si usted es el policía, la línea You are the cop
se agrega al final. El doctor ve You are the doctor
. La mafia ve You are a member of the mafia.\nYour allies are:
y una lista delimitada por la nueva línea de miembros de la mafia, excluyendo al jugador que lee el mensaje.
Al amanecer de todos los demás días, aparecerá este mensaje:
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
se reemplaza con el número del día. victim
se reemplaza con el nombre de la víctima de la noche anterior y victim_role
es uno de:
a villager
a mafioso
the cop
the doctor
cop_target
es el nombre del jugador que el policía investigó anoche, y target_alignment
es village
o mafia
. Finalmente, remaining_players
hay una lista de jugadores que aún están vivos en este formato:player1, player2, player3
La segunda línea se omite si no hubo asesinato anoche, y la tercera línea se muestra solo al policía.
Por ejemplo,
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
Una vez que este mensaje está fuera del camino, ¡comienza el día! Cada bot puede realizar 50 acciones durante el día, donde una "acción" es votar por un jugador o decir algo en voz alta.
Para votar por un jugador, escriba vote player_name
en su to_server
archivo y finalice. Para votar para no matar a nadie, escribe vote no one
. Cuando vote, todos los jugadores (incluido usted) verán your_bot votes to kill your_selection
. Los votos se ignoran el día 0.
Se pueden enviar varios mensajes predefinidos a todos los jugadores. La identificación de cada mensaje posible se enumera aquí:
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?
Todos estos mensajes, excepto los primeros cinco, se refieren a un jugador específico. Para decir uno de esos mensajes, escribe say message_id player_name
. Para uno de los primeros cinco mensajes, solo escriba say message_id
. Puede agregar un tercer argumento opcional a ambos, especificando el nombre de un jugador con el que está hablando (todos los jugadores aún pueden leerlo, pero sabrán quién es el destinatario previsto).
Cuando su bot dice un mensaje, todos los jugadores leen your_bot says "message"
, ¿dónde message
está el mensaje asociado con la identificación que escribió? Si el mensaje incluye un asunto, un carácter de espacio y el asunto se insertan directamente después del final del mensaje. Si incluye un destinatario, su nombre, dos puntos y un carácter de espacio se insertan inmediatamente antes del mensaje.
Al final del día, todos los jugadores vivos se ejecutan por última vez para ver el resultado de la votación. Si se votó a un jugador, esto se escribe:
The town has killed player_name!
They were a villager
... o a mafioso
, o the cop
, o the doctor
.
Si no se votó a ningún jugador, esto se escribe en su lugar:
The town opted to lynch no one today.
Cuando el controlador envía estos mensajes, ignora cualquier respuesta de los jugadores. Se acabó el día.
Noche
Por la noche, todos menos los aldeanos pueden usar su poder.
Mafia:
Usted va a leer It is night. Vote for a victim.
. Cuando esto sucede, escribe el nombre del jugador que te gustaría matar.
Policía:
Usted va a leer It is night. Who would you like to investigate?
. Cuando esto suceda, escriba el nombre del jugador que desea verificar.
Doctor:
Usted va a leer It is night. Who would you like to save?
. Cuando esto suceda, escriba el nombre del jugador que desea proteger.
Después de esto, el día siguiente comienza de manera normal.
Puede salvarse solo una vez por juego.
Información general
- El juego no se ejecutará sin 6 o más jugadores.
- Un tercio de los jugadores, redondeados hacia abajo, serán mafiosos. Un jugador será médico y un jugador será policía. Todos los demás jugadores son aldeanos.
- Los lazos en el voto del pueblo o el voto nocturno de la mafia se resuelven al azar.
- Los nombres de los bot deben ser alfanuméricos + guiones y guiones bajos.
- Está prohibido utilizar el conocimiento del código del oponente directamente. En teoría, debería ser capaz de poner tu bot contra bots que nunca hayas visto antes y que tenga un rendimiento comparable.
- Lamentablemente, si no puedo ejecutar su programa utilizando software exclusivamente gratuito (como en cerveza), tendré que descalificarlo.
- Me reservo el derecho de descalificar cualquier envío si creo que es malicioso. Esto incluye, entre otros, el uso excesivo de tiempo, memoria o espacio para ejecutar. He dejado el límite intencionalmente en blanco, pero recuerda: estoy ejecutando esto en la computadora de mi casa, no en una supercomputadora, y no quiero que los resultados tarden un año. No espero tener que usar esto, ya que mis estándares son bastante bajos. Esto es básicamente "si creo que estás siendo un idiota a propósito", y si puedes convencerme de lo contrario, revertiré mi decisión.
Tanteo
Cada ronda, se ejecutarán 100 juegos (esto puede aumentar a medida que se unen más bots para mantener el tamaño de la muestra lo suficientemente grande, pero en teoría eso no afectará nada). Registraré cuántas veces gana cada bot como aldeano en comparación con cuántas veces juega como aldeano, y lo mismo para la mafia. Un bot villager_ratio
es number of games won as villager / number of games played as villager
, y mafia_ratio
es lo mismo pero s/villager/mafia/g
. La puntuación de un bot es (villager_ratio - mean villager_ratio) + (mafia_ratio - mean mafia_ratio)
.
Ejemplo bot
Randy the Robot no es un buen jugador de la mafia. Randy ignora casi todo, eligiendo al azar qué decir, a quién votar y a quién apuntar con poderes nocturnos.
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
@undergroundmonorail escribió un programa de control para este desafío, disponible aquí .
Tienes un mes para codificar y entregar las respuestas, le daré al bot ganador (el mayor desempate es votos) al menos una recompensa de 50 reputación (dependiendo de la cantidad de reputación que pueda ganar en un mes)
Aquí hay un script de envoltura, creado por @Blacksilver, para usar con lenguajes compilados:
#!/bin/bash
run="./a.out"
compile="gcc bot.c"
if [ -e $run ]; then
$run
else
$compile
$run
fi
Pon esto en run
.
Esta publicación fue escrita por @undergroundmonorail (hice algunas ediciones).
Se lo entregó aquí a cualquiera que quisiera terminarlo y publicarlo.