Мафия (также известная как Оборотень) - это игра для вечеринок, в которой примерно так:
- Игра начинается в день 0. После каждого дня
n
наступает ночьn
. После каждой ночиn
наступает деньn+1
. то естьD0, N0, D1, N1, D2, N2
... - На рассвете дня 0 ведущий тайно выбирает игроков для выполнения определенных ролей:
- Некоторое количество игроков становятся мафией. Каждую ночь каждый мафиози выбирает игрока. На рассвете следующего дня игрок, выбранный большинством мафиози, погибает. Они навсегда удалены из игры, и их роль публично раскрыта. Мафия выровнен.
- Некоторое количество игроков становятся полицейскими. Каждую ночь каждый полицейский выбирает игрока. На рассвете следующего дня полицейский узнает об этой расстановке игроков. Деревня выровнен.
- Некоторое количество игроков становятся врачами. Каждую ночь каждый врач выбирает игрока. Если этот игрок является тем же игроком, которого мафия выбрала убить, действия мафии на эту ночь отменяются. Деревня выровнен.
- Все игроки, которые не выбраны для другой роли, являются сельскими жителями. У селян нет способностей, которыми не обладает весь город. Деревня выровнен.
- Каждый день, кроме дня 0, за город голосует весь город (то есть все живые игроки). В конце дня этот игрок удаляется из игры, и его роль раскрывается. (В день 0 все просто расслабляются до наступления темноты.)
- Если в какой-то момент мафиозо не осталось, игра заканчивается тем, что все равноправные деревенские игроки побеждают (включая мертвых).
- Если в какой-то момент игроки, настроенные на деревню, не превосходят по численности игроков, ориентированных на мафию, игра заканчивается победой всех игроков, ориентированных на мафию (включая мертвых).
Для этой задачи ваша цель - написать бота, чтобы побить других ботов в Mafia!
Как сделать рабочий бот
Все, что вы должны предоставить для меня, это файл с именем run
. Внутри структуры каталогов, где будет проходить этот вызов, ваш бот будет жить здесь:
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/
run
Файл, при выполнении сделает ваш бот делать свое дело. Важно отметить, что этот файл не должен требовать каких-либо аргументов командной строки или чего-либо еще. Он будет запущен именно так ./run
. Если вам нужно выполнить по-другому, вам придется обойти это, выполнив что-то вроде этого:
real_bot.py
#!/bin/python2
# code goes here
run
#!/bin/bash
./real_bot.py --flags --or --whatever
Важно отметить, что все входные данные, полученные вашим ботом, будут найдены в файле, from_server
и управляющая программа будет искать выходные данные вашего бота to_server
. Я решил сделать это таким образом, чтобы любой язык, который может выполнять файловый ввод-вывод, мог участвовать. Если ваш язык облегчает работу с stdin и stdout, чем с файловым вводом / выводом, вы можете написать run
файл, который выглядит следующим образом:
#!/bin/bash
./real_bot.py < from_server > to_server
Это сделает так, что stdin приходит из from_server
файла, а stdout - напрямую to_server
.
Ваш бот не будет работать в течение всей игры. Вместо этого он будет запущен, когда ему необходимо принять решение. Кроме того, он не будет проинформирован, когда он умрет, он просто больше не будет работать. Запланируйте это, сохранив все, что вы хотите запомнить, в файл и прочитав его позже. Вы можете создавать, писать или читать из любого файла в папке вашего бота, но вы не можете писать или читать в любом месте за пределами этой папки, в том числе доступа к сети или что - нибудь . Если ваш бот знает что- то, что ему не было сказано внутри папки, или если он касается чего- то, что не находится внутри этой папки, ваш бот дисквалифицируется.
Как сделать функционального бота
День
В начале игры файл players
будет заполнен разделенным новой строкой списком всех игроков в игре. Он не будет обновляться после выхода игроков из игры.
На рассвете дня 0 все игроки найдут это сообщение в своем from_server
файле:
Rise and shine! Today is day 0.
No voting will occur today.
Be warned: Tonight the mafia will strike.
Если вы полицейский, строка You are the cop
добавляется в конец. Доктор видит You are the doctor
. Мафия видит You are a member of the mafia.\nYour allies are:
и разделенный новой строкой список членов мафии, исключая игрока, читающего сообщение.
На заре всех остальных дней появится это сообщение:
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
заменяется номером дня. victim
заменяется именем жертвы прошлой ночи, и victim_role
является одним из:
a villager
a mafioso
the cop
the doctor
cop_target
имя игрока, которого полицейский исследовал прошлой ночью, и target_alignment
либо, village
либо mafia
. Наконец, remaining_players
список игроков, которые все еще живы в этом формате:player1, player2, player3
Вторая строка опущена, если вчера вечером не было никакого убийства, а третья строка показана только полицейскому.
Например,
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
Как только это сообщение исчезнет, день начнется! Каждый бот может совершить 50 действий в течение дня, где «действие» - это голосование за игрока или вслух что-то говорящее.
Чтобы проголосовать за игрока, напишите vote player_name
в свой to_server
файл и прекратить. Чтобы проголосовать, чтобы никого не убить, пиши vote no one
. Когда вы проголосуете, все игроки (включая вас) увидят your_bot votes to kill your_selection
. Голоса игнорируются в день 0.
Ряд заранее определенных сообщений могут быть отправлены всем игрокам. Идентификатор каждого возможного сообщения указан здесь:
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?
Все эти сообщения, кроме первых пяти, относятся к конкретному игроку. Чтобы сказать одно из этих сообщений, напишите say message_id player_name
. Для одного из первых пяти сообщений просто напишите say message_id
. Вы можете добавить необязательный третий аргумент к обоим из них, указав имя игрока, с которым вы разговариваете (все игроки могут его прочитать, но они будут знать, кто является получателем).
Когда ваш бот говорит сообщение, все игроки читают your_bot says "message"
, где message
находится сообщение, связанное с идентификатором, который вы написали. Если сообщение содержит тему, один пробел и тема вставляются непосредственно после конца сообщения. Если он включает получателя, его имя, один двоеточие и один пробел вставляются непосредственно перед сообщением.
В конце дня всех живых игроков запускают в последний раз, чтобы увидеть результат голосования. Если игрок был отозван, это написано:
The town has killed player_name!
They were a villager
... или a mafioso
, или the cop
, или the doctor
.
Если ни один игрок не был отозван, вместо этого написано:
The town opted to lynch no one today.
Когда контроллер отправляет эти сообщения, он игнорирует любой ответ от игроков. День окончен.
Ночь
Ночью все, кроме жителей деревни, могут использовать свою власть.
Mafia:
Вы будете читать It is night. Vote for a victim.
. Когда это произойдет, выведите имя игрока, которого хотите убить.
Cop:
Вы будете читать It is night. Who would you like to investigate?
. Когда это произойдет, выведите имя игрока, которого вы хотите проверить.
Доктор:
Вы будете читать It is night. Who would you like to save?
. Когда это произойдет, выведите имя игрока, которого вы хотите защитить.
После этого следующий день начинается как обычно.
Вы можете спасти себя только один раз за игру.
Главная Информация
- Игра не будет работать без 6 и более игроков.
- Одна треть игроков, округленных в меньшую сторону, станет мафией. Один игрок будет врачом, а один игрок - полицейским. Все остальные игроки - жители деревни.
- Связи в сельском голосовании или голосование мафии за ночь распределяются случайным образом.
- Имена ботов должны быть буквенно-цифровыми + тире и подчеркивания.
- Запрещено использовать знание кода оппонента напрямую. Теоретически, я должен быть в состоянии поставить вашего бота против ботов, которых вы никогда раньше не видели, и заставить его работать сравнимо.
- К сожалению, если я не смогу запустить вашу программу, используя исключительно бесплатное (как в пиве) программное обеспечение, мне придется ее дисквалифицировать.
- Я оставляю за собой право дисквалифицировать любое представление, если я считаю, что оно является вредоносным. Это включает, но не ограничивается использованием чрезмерного времени, памяти или пространства для запуска. Я намеренно оставил предел мягким, но помните: я запускаю это на своем домашнем компьютере, а не на суперкомпьютере, и я не хочу, чтобы результаты занимали год. Я не ожидаю использовать это, так как мои стандарты довольно низки. Это в основном «если я думаю, что вы нарочно придурок», и если вы можете убедить меня в обратном, я отменю свое решение.
счет
В каждом раунде будет запущено 100 игр (это может увеличиваться по мере того, как присоединяется больше ботов, чтобы размер выборки был достаточно большим, но теоретически это ни на что не повлияет). Я запишу, сколько раз каждый бот выигрывает как сельский житель по сравнению с тем, сколько раз он играет как сельский житель, и то же самое для мафии. Бот villager_ratio
есть number of games won as villager / number of games played as villager
, и mafia_ratio
такой же, но s/villager/mafia/g
. Счет бота является (villager_ratio - mean villager_ratio) + (mafia_ratio - mean mafia_ratio)
.
Пример бота
Робот Рэнди не очень хороший игрок в мафию. Рэнди почти все игнорирует, случайным образом выбирая, что сказать, за кого голосовать, а кого преследовать с помощью ночных сил.
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
контроллер
@undergroundmonorail написал управляющую программу для этой задачи, доступную здесь .
У вас есть один месяц, чтобы закодировать и сдать ответы, я дам выигравшему боту (наибольшее количество победителей - голоса), как минимум, награду в 50 репутаций (в зависимости от того, сколько представителей я могу заработать за месяц)
Вот скрипт-обертка, созданный @Blacksilver, для использования со скомпилированными языками:
#!/bin/bash
run="./a.out"
compile="gcc bot.c"
if [ -e $run ]; then
$run
else
$compile
$run
fi
Вставь это run
.
Этот пост был написан @undergroundmonorail (я сделал несколько правок).
Он дал это здесь любому, кто хотел закончить и опубликовать это.