Мафия (также известная как Оборотень) - это игра для вечеринок, в которой примерно так:
- Игра начинается в день 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 (я сделал несколько правок).
Он дал это здесь любому, кто хотел закончить и опубликовать это.
источник
Ответы:
зулус
run
Не все, на что я надеялся. Я могу в конечном итоге настроить его время от времени.
Как это работает v1.0
Отслеживает номер дня, кто жив, кто мертв, кто мафию, кто в деревне, роли, текущие голоса / сообщения за день и общие голоса / сообщения.
Ночь
а. Мафия - Голосуйте за любого жителя деревни, который голосовал против мафии (случайным образом), если это возможно, в противном случае случайного жителя деревни.
б. Полицейский - Расследуйте любого, кто неизвестного происхождения.
с. Доктор - сначала сохраните себя, затем сохраните копа, если он известен (я не думаю, что он когда-либо узнает об этом), спасите жителя деревни, если он известен (вероятно, тоже не знает), иначе спасите случайного человека.
День
а. Если кто-то сказал сообщение непосредственно самому себе, ответьте на него (возможны ограниченные ответы).
б. Мафия - Голосуйте за деревенского жителя, у которого больше всего голосов.
с. Селянин с любым живым мафиозным знакомым - голосуйте за мафиози.
д. Сельский житель с единственным мертвым известным мафиози - голосуйте за случайного бота, который никогда не голосовал за мафиози.
е. Житель деревни с полицейским известен - голосуйте за случайного бота, за которого проголосовал полицейский.
е. Сельский житель с мертвыми известными по признаку деревни - голосуйте за случайного бота, который голосовал за мертвых.
г. Сельчанин с голосами против себя - голосуйте за самого высокого в настоящее время проголосовавшего бота, не принадлежащего к деревне.
источник
Код примера не работал для меня, я использую Python 3, поэтому я изменил
main.py
файл, чтобы он работал.Итак, вот моя исправленная версия для Python 3, я никогда раньше не программировал на Python, так что, возможно, это ужасный код, но он работает :)
run.sh
:randy.py
:Несколько вещей я узнал, пока делал эту работу (и мне было не понятно в описании)
print
ничего не делает с игрой это какconsole.log
в jsinput()
блокирует запуск программы, это может быть полезно для пошаговой отладкиfrom_server
иto_server
очищается каждый раунд.Ctrl+C
комбинацией, что раздражает.источник
run.sh
.< from_server > to_server
это необходимо, потому что я жестко закодировал имена файлов в коде. игровой движок просто зовут./run
без труб. такinput()
иprint()
не работает с игрой.mayn.py
строка 57:os.system('./run')
randy.py
был написан на Python 2 , что вызвало проблемы../start
из исходной папки или вам нужна версия Python 3main.py
Логик
Необычный, длинный набор кода на Python, который я не собираюсь объяснять (хотя это не игра в гольф), за исключением того, что он хранит списки "друзей" и "врагов", которые первоначально были заполнены на основе случайного и / или полицейского расследования , Предупреждение: не лежите в присутствии логика.
источник
run.sh
стандарт (Выживший (версия 1.0)
конспект
Survivalist просто жестоко выживает в игре, ругая любого, кто осмелится обвинить его, независимо от того, мафия он или нет.
логика
Если вы доживете до конца игры, вы выиграете несмотря ни на что. Поэтому вы выживаете любой ценой.
Предыстория
Войска прошли через темный влажный лес.
"Лейтенант, куда мы идем?" Молодой рекрут явно не закалился до зверств, подумал командир. Ну что ж. Он ответил грубым призывом «уничтожить врага».
В деревне вражеский командир пил и смеялся вместе с другими офицерами в клубе, когда разведчик ворвался с новостями. «Для нас есть колонна длиной в несколько сотен ярдов, идущая через лес Юйлинь! Собери войска!»
Вражеский командир, явно опьяненный, неожиданно сказал: «У меня не было сообщений от других разведчиков». Разведчик (позже выживший) подумал, тогда мне придется самому собрать войска . После того, как они рассказали эту историю товарищам-разведчикам, они снова собрались вместе, и все сказали, что видели вражеские войска. Командир все еще не верил, говоря: «Я заказ вас прерывать скаутинг. Там нет ни одного войска противника».
Разведчики решили получить свое оружие, чтобы спасти сообщество. Им удалось добраться до своих позиций как раз в тот момент, когда противник прибыл в деревню с силой. "ЗАРЯД!" крикнул командир засады. "СЖИГАТЬ ДОМА! СЖИГАТЬ ДОМА! УБИТЬ ВСЕХ, ВКЛЮЧАЯ ЖЕНЩИН И ДЕТЕЙ! "
Разведчики спасли всю свою армию. Они ожидали повышения по службе, наград и медалей. Вместо этого они получили фальсифицированный военный трибунал за мятеж, осуждение, 10 лет тюрьмы, бесчестное увольнение из армии и изгнание.
В городском совете Салема, штат Массачусетс, есть старый старейшина. Легенда гласит, что он основал город. Когда вы встретите его в его изолированном домике в лесу, не позволяйте мерцанию в его глазах заставить вас думать, что он спокоен. Если вы обвините его, он погубит вас перед городом.
ветеран
Код (я новичок в Python, не уверен, что код хороший)
источник
or
вместо||
? Вы проверяли это? Кроме того, вы, вероятно, должны указать, что это Python 2.Аватар
Аватар «случайным образом» выбирает одного игрока в начале и неустанно фокусирует его до конца раунда.
Это не ссылка на одноименную анимационную телепередачу.
Скачать tar всех необходимых файлов
Изменения
stdout
, толькоstderr
.Чтобы подавить
stderr
тоже, добавьте2>/dev/null
в конецrun
файла.Это требует,
mafia.c
иmafia.h
библиотеки, которые я написал, в том же каталоге.Они включены в загрузку вместе с Makefile и скриптом запуска.
СДЕЛАТЬ
Пока я здесь, я отправлю не бот, Стив:
источник
avatar
,erebus
,leviathan
иragnarok
from_server
Файл моего бота не записывается. Вы должны были установить определенные разрешения или что-то?левиафан
Левиафан перебирает всех игроков в
players
файле и целит их один за другим.Скачать
Как и в случае с аватаром, требуется
mafia.c
иmafia.h
в том же каталоге.Они включены в загрузку вместе с Makefile и скриптом запуска.
источник