Mafia (znana również jako wilkołak) to gra towarzyska, która działa mniej więcej tak:
- Gra rozpoczyna się w dniu 0. Po każdym dniu
n
przychodzi nocn
. Po każdej nocyn
przychodzi dzieńn+1
. tj.D0, N0, D1, N1, D2, N2
... - Na początku dnia 0 gospodarz potajemnie wybiera graczy, którzy pełnią określone role:
- Pewna liczba graczy staje się mafią. Każdej nocy każdy mafioso wybiera gracza. O świcie następnego dnia gracz wybrany przez większość mafiosów zostaje zabity. Są trwale usuwani z gry, a ich rola jest publicznie ujawniana. Dostosowane do mafii.
- Pewna liczba graczy zostaje policjantami. Każdej nocy każdy policjant wybiera gracza. Na początku następnego dnia gliniarz zdaje sobie sprawę z wyrównania graczy. Dostosowane do wsi.
- Pewna liczba graczy zostaje lekarzami. Każdej nocy każdy lekarz wybiera gracza. Jeśli ten gracz jest tym samym graczem, którego mafia postanowiła zabić, akcje mafii na tę noc zostaną anulowane. Dostosowane do wsi.
- Wszyscy gracze, którzy nie zostali wybrani do innej roli, są wieśniakami. Wieśniacy nie mają umiejętności, które nie są wspólne dla całego miasta. Dostosowane do wsi.
- Każdego dnia oprócz dnia 0 całe miasto (czyli wszyscy żyjący gracze) głosuje na gracza. Pod koniec dnia ten gracz zostaje usunięty z gry i zostaje ujawniona jego rola. (W dniu 0 wszyscy po prostu dreszcze aż do zmroku.)
- Jeśli w którymkolwiek momencie nie ma już mafiosów, gra kończy się zwycięstwem wszystkich graczy z wioski (w tym zmarłych).
- Jeśli w którymś momencie gracze wyrównani do wioski nie przewyższą liczebnie graczy wyrównanych do mafii, gra kończy się zwycięstwem wszystkich wyrównanych do mafii graczy (w tym zmarłych).
W tym wyzwaniu Twoim celem jest napisanie bota, który pokona inne boty w Mafii!
Jak zrobić działającego bota
Wszystko, co musisz mi podać, to plik o nazwie run
. Wewnątrz struktury katalogów, w której odbędzie się to wyzwanie, twój bot będzie tu mieszkał:
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/
Po run
uruchomieniu plik sprawi, że bot zrobi to samo. Należy zauważyć, że ten plik nie może wymagać żadnych argumentów wiersza poleceń ani niczego. Będzie działał dokładnie tak jak ./run
. Jeśli musisz zostać wykonany w inny sposób, musisz obejść ten problem, wykonując coś takiego:
real_bot.py
#!/bin/python2
# code goes here
run
#!/bin/bash
./real_bot.py --flags --or --whatever
Ważną rzeczą do zapamiętania jest to, że wszystkie dane wejściowe, które otrzymuje twój bot, zostaną znalezione w pliku, from_server
a program sterujący wyszuka dane wyjściowe twojego bota to_server
. Postanowiłem to zrobić w ten sposób, aby każdy język, który może wykonywać operacje we / wy pliku, mógł wziąć udział. Jeśli Twój język ułatwia pracę ze stdin i stdout niż we / wy pliku, możesz napisać run
plik, który wygląda następująco:
#!/bin/bash
./real_bot.py < from_server > to_server
Sprawi to, że stdin pochodzi z from_server
pliku, a stdout przechodzi bezpośrednio do to_server
.
Twój bot nie będzie działał przez cały czas gry. Zamiast tego zostanie uruchomiony, gdy będzie musiał podjąć decyzję. Podobnie, nie będzie informowany, kiedy będzie martwy, po prostu nie będzie już uruchamiany. Zaplanuj to, zapisując w pliku wszystko, co chcesz zapamiętać, i przeczytaj później. Można tworzyć, pisać lub czytać z dowolnego pliku w folderze bota, ale nie może pisać lub czytać gdziekolwiek poza tym folderze, w tym dostępu do sieci lub cokolwiek . Jeśli Twój bot wie coś , czego nie powiedziano w folderze lub jeśli dotyka czegoś , co nie znajduje się w tym folderze, Twój bot jest zdyskwalifikowany.
Jak zrobić funkcjonalnego bota
Dzień
Na początku gry plik players
zostanie wypełniony listą wszystkich graczy w grze rozdzieloną znakiem nowej linii. Nie będzie aktualizowany, gdy gracze opuszczą grę.
O świcie dnia 0 wszyscy gracze znajdą tę wiadomość w swoim from_server
pliku:
Rise and shine! Today is day 0.
No voting will occur today.
Be warned: Tonight the mafia will strike.
Jeśli jesteś gliną, linia You are the cop
jest dołączana na końcu. Lekarz widzi You are the doctor
. Mafia widzi You are a member of the mafia.\nYour allies are:
listę członków mafii rozdzieloną znakiem nowej linii, z wyłączeniem gracza czytającego wiadomość.
U zarania wszystkich pozostałych dni pojawi się ten komunikat:
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
zastępuje się liczbą dnia. victim
zostaje zastąpiony imieniem ofiary zeszłej nocy i victim_role
jest jednym z:
a villager
a mafioso
the cop
the doctor
cop_target
to nazwa odtwarzacza policjant badanego ostatniej nocy, i target_alignment
jest albo village
albo mafia
. Na koniec remaining_players
znajduje się lista graczy, którzy wciąż żyją w tym formacie:player1, player2, player3
Drugi wiersz jest pomijany, jeśli ostatniej nocy nie było zabójstwa, a trzeci wiersz jest wyświetlany tylko gliniarzowi.
Na przykład,
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
Gdy wiadomość zniknie z drogi, zaczyna się dzień! Każdy bot może wykonać 50 akcji w ciągu dnia, przy czym „akcja” głosuje na gracza lub mówi coś głośno.
Aby zagłosować na gracza, napisz vote player_name
do to_server
pliku i zakończ. Aby głosować, aby nikogo nie zabić, napisz vote no one
. Podczas głosowania wszyscy gracze (łącznie z tobą) zobaczą your_bot votes to kill your_selection
. Głosy są ignorowane w dniu 0.
Do wszystkich graczy można wysłać pewną liczbę wstępnie zdefiniowanych wiadomości. Identyfikator każdej możliwej wiadomości znajduje się tutaj:
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?
Wszystkie te wiadomości, z wyjątkiem pierwszych pięciu, odnoszą się do konkretnego gracza. Aby wypowiedzieć jedną z tych wiadomości, napisz say message_id player_name
. W przypadku jednej z pierwszych pięciu wiadomości po prostu napisz say message_id
. Możesz dodać opcjonalny trzeci argument do obu z nich, określając nazwę gracza, z którym rozmawiasz (wszyscy gracze nadal mogą go przeczytać, ale będą wiedzieć, kto jest zamierzonym odbiorcą).
Kiedy twój bot mówi wiadomość, wszyscy gracze czytają your_bot says "message"
, gdzie message
jest wiadomość związana z napisanym przez ciebie identyfikatorem. Jeśli wiadomość zawiera temat, jeden znak spacji i temat są wstawiane bezpośrednio po końcu wiadomości. Jeśli zawiera on adresata, jego nazwa, dwukropek i jeden znak spacji są wstawiane bezpośrednio przed wiadomością.
Pod koniec dnia wszyscy żyjący gracze są uruchamiani ostatni raz, aby zobaczyć wynik głosowania. Jeśli gracz został wykluczony, jest to napisane:
The town has killed player_name!
They were a villager
... lub a mafioso
, lub the cop
, lub the doctor
.
Jeśli żaden gracz nie został wykluczony, zamiast tego jest napisane:
The town opted to lynch no one today.
Gdy kontroler wysyła te wiadomości, ignoruje wszelkie odpowiedzi graczy. Dzień się skończył.
Noc
W nocy wszyscy oprócz wieśniaków mogą korzystać ze swojej mocy.
Mafia:
Można przeczytać It is night. Vote for a victim.
. Kiedy tak się stanie, wypisz nazwę gracza, którego chcesz zabić.
Policjant:
Można przeczytać It is night. Who would you like to investigate?
. Kiedy tak się stanie, wypisz nazwę odtwarzacza, który chcesz sprawdzić.
Lekarz:
Można przeczytać It is night. Who would you like to save?
. Kiedy tak się stanie, wypisz nazwę odtwarzacza, który chcesz chronić.
Następnie następny dzień zaczyna się jak zwykle.
Możesz uratować się tylko raz na grę.
Informacje ogólne
- Gra nie będzie działać bez 6 lub więcej graczy.
- Jedna trzecia graczy, w zaokrągleniu w dół, będzie mafią. Jeden gracz będzie lekarzem, a jeden będzie gliną. Wszyscy pozostali gracze to wieśniacy.
- Więzy w głosowaniu na wsi lub głosowanie mafii z dnia na dzień są rozstrzygane losowo.
- Nazwy botów muszą być alfanumeryczne + myślniki i podkreślenia.
- Zabronione jest bezpośrednie korzystanie z wiedzy o kodzie przeciwnika. Teoretycznie powinienem być w stanie stawić czoła botowi przeciwko botom, których nigdy wcześniej nie widziałeś, i zapewnić mu porównywalną wydajność.
- Niestety, jeśli nie mogę uruchomić twojego programu przy użyciu wyłącznie darmowego (jak w przypadku piwa) oprogramowania, będę musiał go zdyskwalifikować.
- Zastrzegam sobie prawo do zdyskwalifikowania każdego zgłoszenia, jeśli uważam je za złośliwe. Obejmuje to między innymi nadmierne zużycie czasu, pamięci lub miejsca do uruchomienia. Celowo zostawiłem limit miękki, ale pamiętaj: uruchamiam to na moim komputerze domowym, a nie superkomputerze, i nie chcę, aby wyniki trwały rok. Nie oczekuję, że będę musiał z tego korzystać, ponieważ moje standardy są dość niskie. Jest to w zasadzie „jeśli myślę, że celowo jesteś kutasem” i jeśli możesz mnie przekonać, w przeciwnym razie cofnę moją decyzję.
Punktacja
W każdej rundzie uruchomionych zostanie 100 gier (może się to zwiększyć wraz ze wzrostem liczby botów, aby wielkość próbki była wystarczająco duża, ale teoretycznie nie wpłynie to na nic). Będę rejestrować, ile razy każdy bot wygrywa jako wieśniak w porównaniu do tego, ile razy gra jako wieśniak, i to samo dla mafii. Bot villager_ratio
jest number of games won as villager / number of games played as villager
i mafia_ratio
jest taki sam, ale s/villager/mafia/g
. Wynik bota to (villager_ratio - mean villager_ratio) + (mafia_ratio - mean mafia_ratio)
.
Przykładowy bot
Randy the Robot nie jest dobrym graczem mafijnym. Randy ignoruje prawie wszystko, losowo wybierając, co powiedzieć, na kogo głosować i kogo celować za pomocą nocnych mocy.
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
Kontroler
@undergroundmonorail napisał program kontrolny dla tego wyzwania, dostępny tutaj .
Masz jeden miesiąc na kodowanie i przekazanie odpowiedzi, dam zwycięskiemu botowi (najwyższy wskaźnik wygranych remis to głosy) co najmniej 50 nagród za reputację (w zależności od tego, ile przedstawicieli mogę zarobić w ciągu miesiąca)
Oto skrypt otoki, stworzony przez @Blacksilver, do użycia ze skompilowanymi językami:
#!/bin/bash
run="./a.out"
compile="gcc bot.c"
if [ -e $run ]; then
$run
else
$compile
$run
fi
Włóż to run
.
Ten post został napisany przez @undergroundmonorail (wprowadziłem kilka zmian).
Dał go tutaj każdemu, kto chciał go dokończyć i opublikować.
źródło
Odpowiedzi:
Zulus
run
Nie wszystko, na co liczyłem, będzie. Czasami mogę go przerobić.
Jak to działa v1.0
Śledzi liczbę dni, kto żyje, kto nie żyje, kim jest mafia, który jest dostosowany do wsi, role, głosy / wiadomości z bieżącego dnia i ogólne głosy / wiadomości.
Noc
za. Mafia - głosuj na każdego wieśniaka, który głosował przeciwko mafii (losowo), jeśli to możliwe, w przeciwnym razie losowego wieśniaka.
b. Policjant - zbadaj każdego, kto ma nieznane położenie.
do. Doktorze - Najpierw zapisz siebie, a potem uratuj gliniarza, jeśli jest znany (nie sądzę, żeby kiedykolwiek wiedział to na razie), uratuj wieśniaka, jeśli jest znany (prawdopodobnie też tego nie wie), w przeciwnym razie uratuj losową osobę.
Dzień
za. Jeśli ktoś wypowiedział wiadomość bezpośrednio do siebie, odpowiedz na nią (możliwe ograniczone odpowiedzi).
b. Mafia - głosuj na wieśniaka, który ma najwięcej głosów.
do. Wieśniak ze wszystkimi żyjącymi znanymi z mafii sojusznikami - głosuj na mafioso.
re. Wieśniak ze znanymi tylko martwymi, mafijnymi - głosuj na przypadkowego bota, który nigdy nie głosował na mafioso.
mi. Wieśniak ze znanym gliną - głosuj na losowego bota, na którego gliniarz głosował.
fa. Wieśniak ze zmarłym Znany z wioski - głosuj na przypadkowego bota, który głosował na umarłych.
sol. Wieśniak z głosami przeciw własnemu głosowaniu na najwyższego głosowanego bota, który nie jest związany z wioską.
źródło
Przykładowy kod nie działał dla mnie, używam Python 3, więc zmieniłem
main.py
plik, aby działał.Oto moja stała wersja dla Pythona 3, nigdy wcześniej nie programowałem w Pythonie, więc może to jest okropny kod, ale działa :)
run.sh
:randy.py
:Kilka rzeczy, których nauczyłem się podczas tworzenia tej pracy (i nie było to dla mnie jasne w opisie)
print
nic nie robi z grą, jest jakconsole.log
w jsinput()
blokuje uruchomiony program, może być dobry do debugowania krok po krokufrom_server
ito_server
jest czyszczony w każdej rundzie.Ctrl+C
kombinacji, co jest denerwujące.źródło
run.sh
.< from_server > to_server
jest to konieczne, ponieważ na stałe zapisałem nazwy plików w kodzie. silnik gry po prostu dzwoni./run
bez rur. takinput()
iprint()
nie działa z grą.mayn.py
linia 57:os.system('./run')
randy.py
został napisany w języku Python 2 , co spowodowało problemy../start
z oryginalnego folderu lub potrzebujesz wersji Pythona 3main.py
Logik
Wyobraźnia, długa wiązka kodu Pythona, której nie zamierzam wyjaśniać (chociaż nie jest golfa), poza tym, że przechowuje listy „przyjaciół” i „wrogów”, które pierwotnie były zapełniane na podstawie losu i / lub dochodzenia gliniarza . Ostrzeżenie: nie kłam w obecności logika.
źródło
run.sh
standard (przeprowadzanie testów)Survivalist (v 1.0)
Streszczenie
Survivalist po prostu brutalnie przeżywa grę, krytykując każdego, kto ośmieli się go oskarżyć, niezależnie od tego, czy jest mafią czy nie.
Logika
Jeśli przeżyjesz do końca gry, wygrywasz bez względu na wszystko. Dlatego przeżyjesz za wszelką cenę.
Historia
Żołnierze maszerowali przez ciemny, wilgotny las.
„Poruczniku, gdzie maszerujemy?” Dowódca pomyślał, że młody rekrut najwyraźniej nie zahartował się w okrucieństwach. No cóż. Odpowiedział szorstkim słowem „zniszczyć wroga”.
W wiosce nieprzyjacielski dowódca pił i śmiał się wraz z innymi oficerami w klubie, kiedy zwiadowca wpadł z wiadomością. „Istnieje kolumna o długości kilkuset metrów, maszerująca za nami przez las Yulin! Zbierz żołnierzy!”
Dowódca wroga, najwyraźniej odurzony, powiedział nieoczekiwanie: „Nie otrzymałem żadnych raportów od innych zwiadowców”. Zwiadowca (później Survivalist) pomyślał, a potem sam będę musiał zebrać żołnierzy . Po opowiedzeniu historii innym zwiadowcom wrócili razem, wszyscy mówiąc, że widzieli wojska wroga. Dowódca wciąż nie wierzył, mówiąc: „ Rozkazuję ci przerwać zwiad. Nie ma żołnierzy wroga”.
Zwiadowcy postanowili zdobyć broń, aby uratować społeczność. Udało im się dotrzeć na swoje pozycje, gdy wróg przybył do wioski. "OPŁATA!" krzyknął dowódca zasadzki. „SPALAJ DOMY! SPALAJĄ DOMY! ZABIJ KAŻDEGO, W TYM KOBIETY I DZIECI! ”
Zwiadowcy uratowali całą armię. Oczekiwali promocji, nagród i medali. Zamiast tego dostali sfałszowany sąd wojenny za bunt, skazanie, 10 lat więzienia, niehonorowe zwolnienie z wojska i wygnanie.
W radzie miasta Salem, Massachusetts, jest starszy starszy. Legenda głosi, że założył miasto. Kiedy spotkasz go w jego odizolowanym domku w lesie, nie pozwól, by migotanie w jego oku sprawiły, że myślisz, że jest spokojny. Jeśli go oskarżysz, zrujnuje cię przed miastem.
Weteran
Kod (Jestem debiutantem w Pythonie, nie jestem pewien, czy kod jest dobry)
źródło
or
zamiast||
? Testowałeś to? Powinieneś również zauważyć, że jest to Python 2.Awatara
Awatar „losowo” wybiera jednego gracza na początku i nieustannie skupia go na resztę rundy.
To nie jest odniesienie do podobnie nazwanego animowanego programu telewizyjnego.
Pobierz tar wszystkich wymaganych plików
Dziennik zmian
stdout
, tylko dostderr
.Aby pominąć
stderr
również, dodaj2>/dev/null
na końcurun
pliku.Wymaga
mafia.c
imafia.h
bibliotek, które napisałem, w tym samym katalogu.Są one zawarte w pliku do pobrania wraz z plikiem Makefile i skryptem uruchomieniowym.
DO ZROBIENIA
Kiedy tu jestem, prześlę non-bota, Steve:
źródło
avatar
,erebus
,leviathan
, iragnarok
from_server
Plik mojego bota nie jest zapisywany. Czy musiałeś ustawić określone uprawnienia czy coś?Lewiatan
Lewiatan iteruje wszystkich graczy w
players
pliku i celuje w nich jeden po drugim.Pobieranie
Podobnie jak w przypadku Avatara, wymaga
mafia.c
i znajduje sięmafia.h
w tym samym katalogu.Są one zawarte w pliku do pobrania wraz z plikiem Makefile i skryptem uruchomieniowym.
źródło