Mafia (หรือที่รู้จักกันในนาม Werewolf) เป็นเกมปาร์ตี้ที่เล่นอย่างคร่าวๆดังนี้:
- เกมเริ่มต้นในวันที่ 0 หลังจากทุก
n
คืนn
มา หลังจากทุกคืนn
มาถึงวันn+1
หนึ่ง เช่นD0, N0, D1, N1, D2, N2
... - ในตอนเช้าของวันที่ 0 โฮสต์จะเลือกผู้เล่นอย่างลับ ๆ เพื่อเติมเต็มบทบาทบางอย่าง:
- ผู้เล่นจำนวนหนึ่งกลายเป็นมาเฟีย ทุกคืนมาเฟียทุกคนเลือกผู้เล่น ในรุ่งอรุณของวันถัดไปผู้เล่นที่ถูกเลือกโดย mafiosos ส่วนใหญ่จะถูกฆ่า พวกเขาถูกลบออกจากเกมอย่างถาวรและมีการเปิดเผยบทบาทของพวกเขาต่อสาธารณะ มาเฟียชิด
- ผู้เล่นบางคนกลายเป็นตำรวจ ทุกคืนตำรวจแต่ละคนเลือกผู้เล่น ในรุ่งอรุณของวันถัดไปตำรวจจะรับรู้ถึงการจัดเรียงของผู้เล่น หมู่บ้านชิด
- ผู้เล่นจำนวนหนึ่งกลายเป็นหมอ ทุกคืนแพทย์แต่ละคนเลือกผู้เล่น หากผู้เล่นนี้เป็นผู้เล่นคนเดียวกันกับที่มาเฟียเลือกที่จะฆ่าการกระทำของมาเฟียในคืนนั้นจะถูกยกเลิก หมู่บ้านชิด
- ผู้เล่นทุกคนที่ไม่ได้ถูกเลือกสำหรับบทบาทอื่นคือชาวบ้าน ชาวบ้านไม่มีความสามารถที่ไม่ได้แชร์ทั้งเมือง หมู่บ้านชิด
- ทุกวันยกเว้นวันที่ 0 ทั้งเมือง (นั่นคือผู้เล่นที่มีชีวิตทั้งหมด) โหวตให้ผู้เล่น ในตอนท้ายของวันผู้เล่นนั้นจะถูกลบออกจากเกมและมีการเปิดเผยบทบาทของพวกเขา (ในวันที่ 0 ทุกคนก็หนาวสั่นจนค่ำ)
- หาก ณ จุดใดไม่มี mafiosos ที่เหลืออยู่เกมจะจบลงด้วยผู้เล่นที่ได้รับชัยชนะของหมู่บ้าน (รวมถึงคนตาย)
- หาก ณ เวลาใดก็ตามผู้เล่นที่ได้รับการจัดหมู่บ้านไม่ได้มีจำนวนมากกว่าผู้เล่นที่มีแนวมาเฟียเกมจะจบลงด้วยผู้เล่นที่ได้รับการจัดแนวมาเฟียทุกคนที่ชนะ (รวมถึงผู้ตายด้วย)
สำหรับความท้าทายนี้เป้าหมายของคุณคือเขียน bot เพื่อเอาชนะบอทอื่น ๆ ที่ 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
คุณ ฉันเลือกที่จะทำเช่นนี้เพื่อให้ภาษาใด ๆ ที่สามารถทำไฟล์ I / O สามารถเข้าร่วมได้ หากภาษาของคุณทำให้การทำงานกับ stdin และ stdout ง่ายกว่าไฟล์ I / O คุณอาจต้องการเขียนrun
ไฟล์ที่มีลักษณะดังนี้:
#!/bin/bash
./real_bot.py < from_server > to_server
นี้จะทำให้มันดังนั้น stdin ที่มาจากfrom_server
ไฟล์และ stdout to_server
ไปโดยตรงไปยัง
บอทของคุณจะไม่วิ่งต่อไปในช่วงเวลาของเกม แต่จะรันเมื่อจำเป็นต้องตัดสินใจ ในทำนองเดียวกันมันจะไม่ได้รับแจ้งเมื่อมันตายมันก็จะไม่ทำงานอีกต่อไป วางแผนสำหรับสิ่งนี้โดยการบันทึกสิ่งที่คุณต้องการจดจำเป็นไฟล์และอ่านในภายหลัง คุณอาจจะสร้างการเขียนหรืออ่านจากไฟล์ในโฟลเดอร์บอทของคุณ แต่คุณอาจไม่เขียนหรืออ่านได้ทุกที่ด้านนอกของโฟลเดอร์นั้นรวมถึงการเข้าถึงเครือข่ายหรืออะไร หากบอทของคุณรู้อะไรที่ไม่ได้รับการบอกกล่าวจากภายในโฟลเดอร์หรือหากสัมผัสสิ่งที่ไม่ได้อยู่ในโฟลเดอร์บ็อตของคุณจะถูกตัดสิทธิ์
วิธีที่จะทำให้การทำงานของ ธ ปท
วัน
ที่จุดเริ่มต้นของเกมไฟล์players
จะถูกเติมด้วยรายการที่คั่นด้วย newline ของผู้เล่นทั้งหมดในเกม มันจะไม่ได้รับการอัพเดตเมื่อผู้เล่นออกจากเกม
ในตอนเช้าของวันที่ 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.
เมื่อคอนโทรลเลอร์ส่งข้อความเหล่านี้จะไม่สนใจการตอบสนองใด ๆ จากผู้เล่น วันจบแล้ว
กลางคืน
ในเวลากลางคืนทุกคนยกเว้นชาวบ้านจะใช้พลังของพวกเขา
มาเฟีย:
It is night. Vote for a victim.
คุณจะอ่าน เมื่อสิ่งนี้เกิดขึ้นให้ส่งชื่อของผู้เล่นที่คุณต้องการฆ่า
ตำรวจ:
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)
คะแนนบอคือ
บอทตัวอย่าง
Randy the Robot ไม่ใช่ผู้เล่นที่ดี แรนดี้เพิกเฉยต่อทุกสิ่งทุกอย่างโดยการสุ่มเลือกว่าจะพูดว่าใครลงคะแนนเลือกใครและกำหนดเป้าหมายด้วยอำนาจกลางคืน
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 (ฉันแก้ไขไปแล้วสองสามข้อ)
เขามอบมันไว้ที่นี่กับทุกคนที่ต้องการทำให้เสร็จและโพสต์มัน