Mafia (còn được gọi là Người sói) là một trò chơi tiệc tùng có nội dung đại khái như thế này:
- Trò chơi bắt đầu vào ngày 0. Sau mỗi ngày
n
đến một đêmn
. Sau mỗi đêmn
đến một ngàyn+1
. tức làD0, N0, D1, N1, D2, N2
... - Vào rạng sáng ngày 0, một người dẫn chương trình bí mật chọn người chơi để thực hiện một số vai trò nhất định:
- Một số người chơi trở thành mafia. Mỗi đêm, mỗi mafioso chọn một người chơi. Vào buổi bình minh của ngày hôm sau, người chơi được chọn bởi hầu hết các mafiosos bị giết. Họ bị xóa vĩnh viễn khỏi trò chơi và vai trò của họ được tiết lộ công khai. Mafia phù hợp.
- Một số người chơi trở thành cảnh sát. Mỗi đêm, mỗi cảnh sát chọn một người chơi. Vào buổi sáng ngày hôm sau, cảnh sát nhận ra sự liên kết của người chơi. Làng phù hợp.
- Một số người chơi trở thành bác sĩ. Mỗi đêm, mỗi bác sĩ chọn một người chơi. Nếu người chơi này là cùng một người chơi mà mafia đã chọn để giết, thì hành động của mafia cho đêm đó sẽ bị hủy bỏ. Làng phù hợp.
- Tất cả những người chơi không được chọn cho vai trò khác là dân làng. Dân làng không có khả năng mà cả thị trấn không chia sẻ. Làng phù hợp.
- Mỗi ngày trừ ngày 0, toàn bộ thị trấn (nghĩa là tất cả người chơi còn sống) bỏ phiếu cho một người chơi. Vào cuối ngày, người chơi đó bị xóa khỏi trò chơi và vai trò của họ được tiết lộ. (Vào ngày 0, mọi người chỉ ớn lạnh cho đến khi màn đêm buông xuống.)
- Nếu, tại bất kỳ thời điểm nào, không có mafiosos còn lại, trò chơi kết thúc với tất cả người chơi liên kết làng chiến thắng (bao gồm cả người chết).
- Nếu, tại bất kỳ thời điểm nào, những người chơi liên kết làng không vượt trội so với những người chơi liên kết với mafia, trò chơi kết thúc với tất cả những người chơi phù hợp với mafia chiến thắng (bao gồm cả người chết).
Đối với thử thách này, mục tiêu của bạn là viết một bot để đánh bại các bot khác tại Mafia!
Làm thế nào để làm cho một bot làm việc
Tất cả bạn phải cung cấp cho tôi là một tập tin được gọi là run
. Bên trong cấu trúc thư mục nơi thử thách này sẽ diễn ra, bot của bạn sẽ sống ở đây:
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/
Các run
tập tin, khi được thực thi, sẽ làm cho bot của bạn làm điều đó. Điều quan trọng cần lưu ý là tệp này không được yêu cầu bất kỳ đối số dòng lệnh hoặc bất cứ điều gì. Nó sẽ được chạy chính xác như ./run
. Nếu bạn cần được thực hiện theo một cách khác, bạn sẽ phải làm việc xung quanh nó bằng cách làm một cái gì đó như thế này:
real_bot.py
#!/bin/python2
# code goes here
run
#!/bin/bash
./real_bot.py --flags --or --whatever
Một điều quan trọng cần lưu ý là tất cả đầu vào mà bot của bạn nhận được sẽ được tìm thấy trong tệp from_server
và chương trình kiểm soát sẽ tìm kiếm đầu ra của bot của bạn to_server
. Tôi đã chọn làm theo cách này để bất kỳ ngôn ngữ nào có thể thực hiện tệp I / O đều có thể tham gia. Nếu ngôn ngữ của bạn giúp làm việc với stdin và stdout dễ dàng hơn so với tệp I / O, bạn có thể muốn viết một run
tệp trông như thế này:
#!/bin/bash
./real_bot.py < from_server > to_server
Điều này sẽ làm cho nó để stdin xuất phát từ from_server
tệp và thiết bị xuất chuẩn trực tiếp đến to_server
.
Bot của bạn sẽ không chạy trong suốt thời gian của trò chơi. Thay vào đó, nó sẽ được chạy khi cần đưa ra quyết định. Tương tự như vậy, nó sẽ không được thông báo khi nó chết, nó sẽ không được chạy nữa. Lập kế hoạch cho điều này bằng cách lưu bất cứ điều gì bạn muốn ghi nhớ vào một tập tin và đọc nó sau. Bạn có thể tạo, ghi hoặc đọc từ bất kỳ tệp nào trong thư mục bot của bạn, nhưng bạn không thể viết hoặc đọc bất cứ nơi nào bên ngoài thư mục đó, bao gồm cả truy cập mạng hoặc bất cứ điều gì . Nếu bot của bạn biết bất cứ điều gì mà nó không được nói từ trong thư mục hoặc nếu nó chạm vào bất cứ thứ gì không có trong thư mục đó, thì bot của bạn sẽ bị loại.
Làm thế nào để tạo một bot chức năng
ngày
Khi bắt đầu trò chơi, tập tin players
sẽ được lấp đầy với một danh sách giới hạn dòng mới của tất cả người chơi trong trò chơi. Nó sẽ không được cập nhật khi người chơi rời khỏi trò chơi.
Vào buổi bình minh của ngày 0, tất cả người chơi sẽ tìm thấy thông báo này trong from_server
tệp của họ :
Rise and shine! Today is day 0.
No voting will occur today.
Be warned: Tonight the mafia will strike.
Nếu bạn là cảnh sát, dòng You are the cop
được nối đến cuối. Các bác thấy You are the doctor
. Mafia nhìn thấy You are a member of the mafia.\nYour allies are:
và một danh sách giới hạn các thành viên mafia, ngoại trừ người chơi đang đọc tin nhắn.
Vào buổi bình minh của tất cả các ngày khác, thông báo này sẽ xuất hiện:
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
được thay thế bằng số trong ngày. victim
được thay thế bằng tên của nạn nhân đêm qua và victim_role
là một trong:
a villager
a mafioso
the cop
the doctor
cop_target
là tên của người chơi mà cảnh sát điều tra tối qua, và target_alignment
là village
hoặc mafia
. Cuối cùng, remaining_players
là danh sách những người chơi vẫn còn sống ở định dạng này:player1, player2, player3
Dòng thứ hai được bỏ qua nếu không có lệnh giết tối qua và dòng thứ ba chỉ được hiển thị cho cảnh sát.
Ví dụ,
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
Một khi tin nhắn này được đưa ra, ngày bắt đầu! Mỗi bot có thể thực hiện 50 hành động trong suốt cả ngày, trong đó một "hành động" đang bỏ phiếu cho người chơi hoặc nói to điều gì đó.
Để bình chọn cho một người chơi, viết vote player_name
vào to_server
tập tin của bạn và chấm dứt. Để bình chọn để không giết ai, hãy viết vote no one
. Khi bạn bỏ phiếu, tất cả người chơi (bao gồm cả bạn) sẽ thấy your_bot votes to kill your_selection
. Phiếu bầu được bỏ qua vào ngày 0.
Một số tin nhắn được xác định trước có thể được gửi đến tất cả người chơi. Id của mỗi tin nhắn có thể được liệt kê ở đây:
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?
Tất cả những tin nhắn này ngoại trừ năm tin nhắn đầu tiên đều đề cập đến một người chơi cụ thể. Để nói một trong những tin nhắn đó, hãy viết say message_id player_name
. Đối với một trong năm tin nhắn đầu tiên, chỉ cần viết say message_id
. Bạn có thể thêm một đối số thứ ba tùy chọn cho cả hai đối số này, chỉ định tên của người chơi bạn đang nói chuyện (tất cả người chơi vẫn có thể đọc nó, nhưng họ sẽ biết ai là người nhận dự định).
Khi bot của bạn nói một tin nhắn, tất cả người chơi đọc your_bot says "message"
, message
tin nhắn được liên kết với id bạn đã viết ở đâu. Nếu tin nhắn bao gồm một chủ đề, một ký tự khoảng trắng và chủ đề được chèn trực tiếp sau khi kết thúc tin nhắn. Nếu nó bao gồm một người nhận, tên của họ, một dấu hai chấm và một ký tự khoảng trắng được chèn ngay trước tin nhắn.
Vào cuối ngày, tất cả người chơi còn sống được chạy lần cuối để xem kết quả bỏ phiếu. Nếu một người chơi đã được bỏ phiếu, điều này được viết:
The town has killed player_name!
They were a villager
... hoặc a mafioso
, hoặc the cop
, hoặc the doctor
.
Nếu không có người chơi nào được bỏ phiếu, điều này được viết thay thế:
The town opted to lynch no one today.
Khi bộ điều khiển gửi những tin nhắn này, nó sẽ bỏ qua mọi phản hồi từ người chơi. Ngày kết thúc.
Đêm
Vào ban đêm, mọi người trừ dân làng được sử dụng quyền lực của họ.
Xã hội đen:
Bạn sẽ đọc It is night. Vote for a victim.
. Khi điều này xảy ra, hãy xuất tên của người chơi bạn muốn giết.
Sao chép:
Bạn sẽ đọc It is night. Who would you like to investigate?
. Khi điều này xảy ra, hãy xuất tên của người chơi bạn muốn kiểm tra.
Bác sĩ:
Bạn sẽ đọc It is night. Who would you like to save?
. Khi điều này xảy ra, hãy xuất tên của người chơi bạn muốn bảo vệ.
Sau này, ngày hôm sau bắt đầu như bình thường.
Bạn có thể tự cứu mình một lần mỗi trò chơi.
Thông tin chung
- Trò chơi sẽ không chạy nếu không có 6 người chơi trở lên.
- Một phần ba số người chơi, làm tròn xuống, sẽ là mafia. Một người chơi sẽ là bác sĩ, và một người chơi sẽ là cảnh sát. Tất cả những người chơi khác là dân làng.
- Các mối quan hệ trong cuộc bỏ phiếu của làng hoặc phiếu bầu qua đêm của mafia được giải quyết ngẫu nhiên.
- Tên bot phải là chữ và số + dấu gạch ngang và dấu gạch dưới.
- Nghiêm cấm sử dụng kiến thức về mã của đối thủ trực tiếp. Về lý thuyết, tôi sẽ có thể đưa bot của bạn chống lại các bot mà bạn chưa từng thấy trước đây và nó có hiệu suất tương đương.
- Đáng tiếc, nếu tôi không thể chạy chương trình của bạn bằng phần mềm miễn phí (như bia), tôi sẽ phải loại bỏ nó.
- Tôi bảo lưu quyền không đủ tiêu chuẩn nếu tôi cho rằng đó là độc hại. Điều này bao gồm, nhưng không giới hạn trong việc sử dụng quá nhiều thời gian, bộ nhớ hoặc không gian để chạy. Tôi đã cố tình để giới hạn mềm, nhưng hãy nhớ rằng: Tôi đang chạy cái này trên máy tính ở nhà của tôi chứ không phải siêu máy tính và tôi không muốn nhận kết quả trong một năm. Tôi không mong đợi phải sử dụng cái này, vì tiêu chuẩn của tôi khá thấp. Về cơ bản, đây là "nếu tôi nghĩ bạn là một kẻ tinh ranh có chủ đích" và nếu bạn có thể thuyết phục tôi thì tôi sẽ đảo ngược quyết định của mình.
Chấm điểm
Mỗi vòng, 100 trò chơi sẽ được chạy (điều này có thể tăng lên khi nhiều bot tham gia để giữ kích thước mẫu đủ lớn, nhưng theo lý thuyết sẽ không ảnh hưởng đến bất cứ điều gì). Tôi sẽ ghi lại số lần mỗi bot chiến thắng như một dân làng so với số lần nó chơi như một dân làng, và tương tự cho mafia. Một bot villager_ratio
là number of games won as villager / number of games played as villager
, và mafia_ratio
là như nhau nhưng s/villager/mafia/g
. Điểm số của bot là (villager_ratio - mean villager_ratio) + (mafia_ratio - mean mafia_ratio)
.
Ví dụ bot
Randy the Robot không phải là một người chơi mafia giỏi. Randy bỏ qua khá nhiều thứ, chọn ngẫu nhiên những gì cần nói, bầu chọn cho ai và nhắm mục tiêu với sức mạnh ban đêm.
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
Bộ điều khiển
@undergroundmonorail đã viết một chương trình kiểm soát cho thử thách này, có sẵn ở đây .
Bạn có một tháng để viết mã và trả lời, tôi sẽ đưa bot chiến thắng (công cụ phá vỡ tỷ lệ thắng cao nhất là phiếu bầu) ít nhất là 50 tiền thưởng danh tiếng (tùy thuộc vào số tiền tôi có thể kiếm được trong một tháng)
Đây là tập lệnh bao bọc, được tạo bởi @Blacksilver, để sử dụng với các ngôn ngữ được biên dịch:
#!/bin/bash
run="./a.out"
compile="gcc bot.c"
if [ -e $run ]; then
$run
else
$compile
$run
fi
Đặt điều này trong run
.
Bài viết này được viết bởi @undergroundmonorail (Tôi đã thực hiện một vài chỉnh sửa).
Ông đã đưa nó lên đây cho bất cứ ai muốn hoàn thành và đăng nó.