Papan peringkat
154 Calculator
144 Taxman
138 Statistician
137 Solver
137 RandoAggroLawyer
136 Gambler
134 Turncoat
119 Lawyer
119 BloodyMurder
113 Bandit
79 Challenger
74 Mask
64 Random
Arsip pertandingan terbaru, termasuk log dan semua file output, tersedia.
Kalkulator, oleh Brilliand, adalah pemenangnya! Jawabannya diterima, tetapi itu tidak berarti tantangannya sudah berakhir. Jangan ragu untuk mengirim entri baru atau mengedit entri Anda saat ini dan mencoba menjatuhkannya dari singgasananya. Saya akan memberikan hadiah kepada pemimpin di akhir bulan.
Aturan main
Kudeta adalah permainan kartu yang dirancang untuk 2-6 pemain, yang akan kami mainkan dengan dua. Ini terdiri dari perbendaharaan koin (tak terbatas untuk tujuan kita) dan setumpuk 15 kartu, berisi 3 masing-masing jenis berikut: Duta Besar, Pembunuh, Kapten, Contessa, Duke. Di awal permainan, setiap pemain diberikan satu koin dan dibagikan dua kartu secara acak, yang mereka rahasiakan sampai diperlukan. Tujuannya adalah menjadi pemain terakhir dengan kartu di tangan Anda.
Pada gilirannya, seorang pemain dapat mengambil salah satu tindakan berikut terlepas dari kartu mereka:
- Penghasilan: ambil 1 koin dari kas. Tidak terblokir dan tidak tertandingi.
- Bantuan Asing: ambil 2 koin dari kas. Dapat diblokir oleh pemain dengan Duke. Tidak dapat ditentang.
- Kudeta: Keluarkan kartu dari satu lawan pilihan Anda dari permainan. Biaya 7 koin. Korban dapat memilih kartu yang akan dibuang. Jika seorang pemain memiliki 10 koin atau lebih pada awal giliran mereka, mereka harus Kudeta. Tidak terblokir dan tidak tertandingi.
Tergantung pada kartu mereka, pemain juga dapat mengambil salah satu tindakan berikut sebagai giliran mereka:
- Pertukaran: pemain dengan Duta Besar dapat mengambil dua kartu dari dek. Kemudian mereka dapat memilih dari tangan mereka dan kartu yang diambil sebanyak kartu yang semula mereka miliki. (Yaitu, jika mereka hanya memiliki satu kartu, mereka dapat menukarnya dengan salah satu kartu yang diambil atau menyimpannya, dan jika mereka memiliki dua kartu, mereka dapat memilih dua dari empat kartu.) Kedua kartu yang tidak diinginkan dikembalikan ke geladak. . Tidak terblokir, tetapi menantang.
- Membunuh: pemain dengan Assassin dapat menghabiskan 3 koin untuk mengeluarkan kartu lawan dari permainan. Korban dapat memilih kartu yang akan dibuang. Dapat diblokir oleh pemain dengan Contessa, dalam hal ini koin tidak dikembalikan. Challengeable, dalam hal ini koin yang dikembalikan.
- Mencuri: Seorang pemain dengan Kapten dapat mengambil dua koin dari lawan mereka. Jika lawan memiliki satu koin, mereka akan mengambil satu koin itu. Jika lawan memiliki koin nol, mereka mungkin tidak Mencuri. Dapat diblokir oleh pemain dengan Duta Besar atau Kapten. Dapat ditantang.
- Pajak: Seorang pemain dengan Duke dapat mengambil 3 koin dari perbendaharaan. Tidak terblokir, tetapi menantang.
Bagian rumit dari Coup adalah bahwa pemain diperbolehkan berbohong tentang kartu apa yang mereka miliki! Seseorang tidak perlu memiliki kartu untuk mencoba melakukan tindakan atau blok yang terkait dengannya.
Ketika seorang pemain melakukan tindakan kartu, lawan mana pun (bahkan orang yang tidak dirugikan oleh tindakan itu) dapat menantang aktor dan mengatakan bahwa mereka tidak percaya mereka memiliki kartu untuk tindakan itu. Jika penantang benar, tindakan dibatalkan dan aktor harus membuang satu kartu pilihan mereka (mendapatkan kembali koin yang mereka habiskan jika berlaku). Jika tidak, tindakan diambil, aktor mengembalikan kartu yang ditantang ke geladak dan menarik yang baru, dan penantang harus membuang salah satu kartu mereka. Pemain harus jujur tentang kartu apa yang mereka pegang saat ditantang.
Kartu yang dihilangkan dari bermain dengan Assassinate, Coup, dan tantangan yang hilang tidak dikembalikan ke geladak, tetapi kartu yang terungkap sebagai bagian dari tantangan yang dimenangkan dikembalikan ke geladak.
Blok dapat ditantang seperti halnya tindakan. Misalnya, jika pemain A mengklaim Bantuan Luar Negeri dan pemain B mengatakan "Saya memiliki Duke dan saya memblokir Bantuan Luar Negeri Anda", A mungkin mengatakan "Saya tidak percaya Anda memiliki Duke." Jika pernyataan itu benar, B kehilangan kartu karena tertangkap basah dan A mengambil 2 koin; jika tidak, A kehilangan kartu dan tidak mendapat koin, dan B harus mengembalikan Duke mereka ke geladak dan menggambar kartu baru.
Cara blok dan tantangan bekerja dengan Assassinate harus disempurnakan. Misalkan Pemain A mengatakan "Saya punya Assassin, dan saya Assassinate Player B". Jika B tidak berusaha untuk menantang atau memblokir A, maka pembunuhan terjadi: B kehilangan kartu dan A membayar 3 koin.
Atau, B dapat menantang dengan mengatakan "Saya tidak percaya Anda memiliki Assassin". Jika itu benar, maka A membuang kartu dan koin mereka dikembalikan, sedangkan B tidak terpengaruh, dan giliran A berakhir. Jika kepercayaan B salah dan A memegang Assassin, maka B kehilangan kedua kartu mereka dan gagal, satu untuk tantangan yang salah dan satu dari Pembunuhan.
Alih-alih menantang, B bisa mengatakan "Saya punya Contessa, dan saya memblokir Assassinate". Jika A percaya B, maka giliran A berakhir dan koin mereka tidak dikembalikan. Tapi A dapat menantang blok dan berkata, "Aku tidak percaya kamu punya Contessa." Jika B memang memegang Contessa, maka A kehilangan kartu karena tantangan yang salah. Tetapi jika B tidak, maka B kehilangan satu kartu karena tertangkap dalam kebohongan dan satu lagi dari Pembunuhan.
Logika yang mirip dengan penjelasan di atas berlaku untuk kemampuan Mencuri Kapten, di mana aksi atau blok dapat ditantang.
Dimungkinkan untuk kehilangan kedua kartu Anda dan dihilangkan dalam satu kesempatan, jika Anda tidak berhasil menantang seorang Pembunuh atau Anda kedapatan mengklaim bahwa Anda memiliki Contessa untuk memblokir Pembunuhan. Anda kehilangan satu kartu dari tantangan dan satu kartu dari Pembunuhan.
Tantangan
Tugas Anda adalah menulis sebuah program yang akan memainkan Coup. Ini akan diberikan sebagai argumen baris perintahnya:
- Nama file yang berisi daftar tindakannya dan tindakan lawannya sejauh ini.
- Integer dari 0 hingga 12 menunjukkan jumlah koin lawan.
- Integer dari 0 hingga 12 menunjukkan jumlah koinnya.
- Sebuah string dengan panjang satu hingga empat karakter menunjukkan kartunya. Biasanya ini hanya akan menjadi satu atau dua kartu yang dimiliki program Anda, tetapi jika program Anda baru saja berhasil di Exchange, panjangnya akan menjadi n + 2 karakter, di mana n adalah jumlah kartu yang tersisa. Program Anda kemudian harus mengeluarkan kartu n yang ingin disimpan untuk STDOUT. (Program tidak boleh membaca atau mengakses STDOUT selain untuk tujuan ini - jika Anda ingin menghasilkan keluaran debug, silakan menulis ke STDERR.)
- Satu atau lebih argumen yang menunjukkan langkah hukum yang mungkin dibuatnya.
(Contoh doa:, yang yourprogram file.txt 1 7 '~!' a c p q
berarti "Lawan Anda memiliki 1 koin. Anda memiliki 7 koin, seorang Duta Besar, dan Contessa. Menulis ke file.txt pilihan Anda dari a, c, p, atau q mengingat sejarah permainan dan keadaan permainan saat ini. ")
Program Anda harus menambahkan satu atau (dalam dua situasi tertentu) dua karakter ke file yang disediakan menunjukkan tindakannya. Tidak boleh mengubah konten file yang ada. Itu dapat membuat file baru yang diinginkannya, tetapi hanya di dalam direktori di mana ia dijalankan. Harap berikan semua perintah yang diperlukan untuk mengkompilasi dan menjalankan program Anda.
Saya telah memberikan dua contoh pesaing di bawah ini, yang ditulis dalam Go.
Format output adalah:
I\n
: Penghasilan. Tanggapan hukum: setiap tindakan belokan (dengan asumsi seseorang memiliki koin untuk Assassinate / Coup).F
: Bantuan asing. Respons hukum:d
(diblokir sebagai Duke),p
(biarkan lewat).C
: Kudeta. Tanggapan hukum: mana dari_
,'
,<
,=
,0
adalah di tangan Anda.E
: Pertukaran. Tanggapan hukum:q
(menantang, tidak percaya pemain memiliki Duta Besar)p
,.T
: Pajak. Tanggapan hukum:q
(menantang, tidak percaya pemain memiliki Duke)p
,.A
: Dibunuh. Tanggapan hukum:s
(blok sebagai Contessa),q
(tantangan), dan mana dari_
,'
,<
,=
,0
adalah di tangan Anda.S
: Mencuri. Tanggapan hukum:a
(blok sebagai Duta Besar),c
(blok sebagai Kapten),q
(tantangan, tidak percaya pemain memiliki Kapten)p
,.d
: blok Bantuan Asing sebagai Duke. Tanggapan hukum:\n
(terima blok),q
(tantang, tidak percaya pemain memiliki Duke).a
: blokir Mencuri sebagai Duta Besar. Respons hukum:\n
(terima blok),q
(tantang, tidak percaya pemain memiliki Duta Besar).c
: blokir Mencuri sebagai Kapten.\n
(terima blok),q
(tantang, tidak percaya pemain memiliki Kapten).s
: blokir Assassinate sebagai Contessa. Respons hukum:\n
(terima blok),q
(tantang, tidak percaya pemain memiliki Contessa).p
: lulus menantang Pertukaran / Pajak / Curi ketika bukan giliran Anda. Tidak digunakan denganA
; untuk menolak untuk menantang pembunuhan, tulis salah satu dari_'<=0
. Respons hukum:\n
(akhiri giliran Anda), dan jika Anda baru saja berhasil di Exchange, tulis kartu yang ingin Anda simpan dari argumen baris perintah keempat menjadi STDOUT.q
: tantang tindakan atau blok terbaru. Respons hukum: jika Anda memiliki kartu untuk tindakan yang ditantang, pilih yang mana~^*!$
. Jika tidak, maka dari mana saja_'<=0
dari tangan Anda yang ingin Anda menyerah, diikuti oleh baris baru jika dan hanya jika giliran Anda.~
,^
,*
,!
,$
: Mengungkapkan bahwa Anda mengatakan yang sebenarnya tentang memegang, masing-masing, Duta, Assassin, Kapten, sebuah Contessa, dan Duke (juga digunakan untuk mewakili kartu ini dalam argumen baris perintah, dan STDOUT output dalam Exchange ). Tanggapan hukum: mana dari_
,'
,<
,=
,0
Anda memiliki di tangan Anda._
,'
,<
,=
,0
: Menyerah sebagai hukuman, masing-masing, Duta, dan Assasin, Kapten, sebuah Contessa, dan Duke karena Anda kehilangan tantangan atau yang Dibunuh / couped. Respon hukum:\n
.\n
: akhiri giliran Anda, dengan menolak untuk menantang blok jika ada. Respons hukum: setiap tindakan huruf besar (dengan asumsi seseorang memiliki koin untuk Assassinate / Coup dan lawan memiliki koin untuk Steal).
Format ini memiliki properti berguna berikut:
- Ternyata mulai dengan huruf kapital.
- Garis mengikuti pola: huruf besar, huruf kecil, tanda baca opsional atau 0 untuk kartu yang terbuka, baris baru.
- File yang diakhiri dengan baris baru, atau file kosong, menunjukkan bahwa itu adalah permulaan giliran program Anda dan harus memilih tindakan huruf besar.
- Tindakan hukum yang diizinkan untuk Anda lakukan pada doa biasanya ditentukan secara unik oleh karakter terakhir dalam file. Pengecualiannya adalah
q
, yang akan memiliki beberapa logika yang terkait dengannya. Lihat fungsiget_legal_actions
di arbiter untuk membantu memahami hal ini. Atau Anda bisa menggunakan tindakan hukum yang Anda berikan pada baris perintah. - Sejumlah karakter pada garis menunjukkan bahwa giliran itu milik Anda dan program Anda diminta untuk memilih tindakan, menantang blok, atau mengakhiri gilirannya.
- Sejumlah karakter aneh pada sebuah baris menunjukkan bahwa giliran itu bukan milik Anda dan program Anda diminta untuk memblokir, menantang, atau mengungkapkan / menyerahkan kartu.
Saya akan memberikan contoh untuk setiap tindakan.
I\n
adalah yang termudah untuk dipahami. Suatu program mengambil satu koin Penghasilan, lalu mengakhiri gilirannya. Ini adalah salah satu dari dua kasus di mana program harus mencetak dua karakter, karena Penghasilan adalah satu-satunya tindakan di mana lawan tidak terpengaruh dan tidak dapat memblokir atau menantang.
Fp\n
berarti bahwa satu program mengambil Bantuan Luar Negeri, maka lawannya menolak untuk memblokir ( p
). Pada doa berikutnya, program pertama mencatat bahwa dengan huruf kecil terakhir p
dan / atau jumlah karakter pada baris ini, ia mengambil giliran ini, yang belum berakhir, jadi ia tahu untuk mengakhiri gilirannya saat ini dengan mencetak baris baru.
C=\n
berarti bahwa satu program meluncurkan Kudeta. Lawannya, tahu bahwa itu dipanggil untuk bereaksi dengan jumlah huruf aneh di telepon, menyerahkan Contessa. Sekali lagi, program pertama tahu bahwa ini adalah giliran tidak lengkap pada permohonan berikutnya dengan jumlah genap di telepon, jadi ia menulis baris baru untuk mengakhiri gilirannya.
Eq~<\n
akan berarti bahwa satu program mencoba Exchange ( E
) dan lawannya ditantang ( q
). Program Pertukaran mengungkapkan bahwa sebenarnya memiliki Duta Besar ( ~
) dan penantang menyerahkan Kapten sebagai hukuman ( <
). Setelah penantang keluar, program Saling menukar dipanggil lagi dengan string empat karakter sebagai argumen baris perintah keempat (atau tiga karakter, jika hanya memiliki satu kartu). Itu menulis karakter yang mewakili kartu yang ingin disimpan untuk STDOUT dan baris baru ke file.
Tq'\n
berarti bahwa satu program mencoba Pajak yang tidak benar, ditantang, dan menyerahkan Assassin. Ini menggambarkan kasus lain di mana dua karakter ditulis: jika giliran Anda dan Anda dipaksa untuk memberikan kartu - baik dari tantangan lawan yang benar (seperti di sini) atau dari tantangan salah blok Anda - maka Anda harus menulis keduanya kartu yang Anda menyerah dan baris baru untuk mengakhiri giliran Anda.
Asq!'\n
akan berarti bahwa Pemain B berusaha untuk membunuh pemain A ( A
), tetapi A mengklaim memiliki Contessa untuk memblokirnya ( s
). B tidak percaya A dan menantang ( q
). A mengungkapkan bahwa mereka memang memiliki Contessa ( !
). B menyerahkan seorang Assassin sebagai hukuman, kehilangan koin mereka, dan mengakhiri giliran mereka ( '\n
), menulis dua karakter seperti dalam kasus khusus itu. (Jika A memutuskan untuk tidak memblokir atau menantang, itu bisa saja ditulis =
, dan kemudian lawannya akan melihat bahwa giliran telah berakhir dan menulis baris baru. Baris itu kemudian akan membaca A=\n
, seperti contoh Kudeta.)
Sq*0\n
berarti satu program mencoba Mencuri; lawan menantang, tidak percaya si pencuri memiliki Kapten; dan program asli mengungkapkan Kapten, jadi tantangannya tidak berhasil dan penantang menyerahkan Duke sebagai hukuman. (Pilihan lain untuk lawannya adalah untuk menerima Steal dengan menulis p
. Lawannya kemudian akan mendeteksi akhir gilirannya dan menulis \n
, menghasilkan garis Sp\n
.)
Arbiter
Program akan dipanggil oleh skrip Python ini. Ini melakukan sepuluh putaran, di mana setiap pesaing menghadapi setiap pesaing lainnya saat keduanya dan kedua. Ini melacak jumlah kartu dan koin dan menentukan pecundang oleh program pertama untuk mengakhiri garis dengan tanda baca dua kali. Program yang keluar dengan status tidak nol, memodifikasi file, menulis perpindahan ilegal ke file, atau upaya Exchange ilegal akan secara otomatis hangus. Jika setiap pemain melakukan lebih dari 100 aksi, termasuk blok dan tantangan, tanpa pemenang, maka kedua program kalah. Pemenang diberikan satu poin. Pemain yang programnya mencetak poin terbanyak, menang.
Saya sarankan Anda membaca kode sumber Arbiter, terutama get_legal_actions
fungsinya. Ini dapat membantu Anda memahami spesifikasi dan menulis program Anda sendiri.
import itertools
import os
import random
import subprocess
class Player:
def __init__(self, name, command):
self.name = name
self.command = command
self.score = 0
self.coins = 1
self.cards = ""
actions_dict = {
'E': '_', 'T': '0', 'A': "'", 'S': '<',
'd': '0', 'a': '_', 'c': '<', 's': '='
}
punishment_to_reveal = {'_': '~', "'": '^', '<': '*', '=': '!', '0': '$'}
reveal_to_punishment = {
punishment_to_reveal[k]: k for k in punishment_to_reveal
}
def get_legal_actions(history, player, opponent):
c = history[-1]
result = ""
# Our turn begins; choose an action.
if c == '\n':
if player.coins >= 10:
return ["C"]
ret = ['I\n'] + list("FET")
if player.coins >= 3:
ret.append("A")
if player.coins >= 7:
ret.append('C')
if opponent.coins > 0:
ret.append("S")
return ret
# Opponent attempted foreign aid; can pass or claim Duke to block.
elif c == 'F':
return list('dp')
# We have been Couped; must surrender a card.
elif c == 'C':
return player.cards
# We failed a challenge; must surrender a card and print a newline
# if it is our turn.
elif c in '~^*!$':
if history[-3] in 'acds':
return [card + '\n' for card in player.cards]
return player.cards
# Opponent attempted Exchange or Tax; can pass or challenge.
elif c == 'E' or c == 'T':
return list('pq')
# Opponent attempted an Assassination; can block, challenge, or give in.
elif c == 'A':
return list('sq') + player.cards
# Opponent attempted to Steal; can pass, block as Ambassador/Captain,
# or challenge.
elif c == 'S':
return list('acpq')
# Opponent blocked; can challenge or withdraw.
elif c in 'acds':
return list('q\n')
# Opponent passed on blocking Foreign Aid/Tax/Exchange or they gave up a
# card as punishment, must end turn.
elif c in "p_'<=0":
return ['\n']
# Opponent challenged us.
elif c == 'q':
challenged_action = history[-2]
# If we have the card they challenged us over, must reveal it.
necessary_card = actions_dict[challenged_action]
if necessary_card in player.cards:
return [punishment_to_reveal[necessary_card]]
# Otherwise, we can give up either of our cards, writing a newline
# if it is our turn.
if challenged_action in 'acds':
return list(player.cards)
else:
return [card + '\n' for card in player.cards]
else:
return None
deck = ['_', "'", '<', '=', '0'] * 3
random.shuffle(deck)
def determine_turn_effects(line, output, cards, current_player, opponent):
last_action = line[-2]
# Only operate if the opponent declined to challenge (p) or the
# program successfully challenged their block
if last_action in "p_'<=0":
primary_action = line[0]
# Foreign Aid
if primary_action == 'F':
print current_player.name, "received 2 coins of Foreign Aid"
current_player.coins += 2
# Tax
elif primary_action == 'T':
print current_player.name, "received 3 coins of Tax"
current_player.coins += 3
# Steal
elif primary_action == 'S':
stolen_coins = 1 if opponent.coins == 1 else 2
print current_player.name,\
"stole %d coins from %s" % (stolen_coins, opponent.name)
current_player.coins += stolen_coins
opponent.coins -= stolen_coins
# Exchange, store desired cards and replace undesired ones
elif primary_action == 'E':
print current_player.name, "tried to take %r" % output, "from", cards
legal_outputs = [''.join(p) for p in itertools.permutations(
cards, len(current_player.cards))]
if output not in legal_outputs:
print current_player.name, "forfeits by illegal exchange"
return opponent
current_player.cards = [
reveal_to_punishment[c] for c in output
]
undesired_cards = list(cards)
for c in output:
undesired_cards.remove(c)
for card in undesired_cards:
deck.append(reveal_to_punishment[card])
random.shuffle(deck)
# Coins are not returned from a successful Contessa block
elif last_action == 's':
print current_player.name, "lost 3 coins from a Contessa block"
current_player.coins -= 3
return None
def play_game(player1, player2, round_number, game_number):
outfilename = os.path.abspath(__file__)[:-len(__file__)] + '_'.join([
player1.name, player2.name, str(round_number), str(game_number)
]) + '.txt'
print outfilename
f = open(outfilename, 'w')
f.close()
players_list = [player1, player2]
player1.cards = [deck.pop(), deck.pop()]
player2.cards = [deck.pop(), deck.pop()]
current_player_index = 0
for i in range(200):
current_player = players_list[current_player_index]
opponent = players_list[(current_player_index+1) % 2]
legal_actions = []
original_contents = []
original_contents_joined = ""
with open(outfilename, 'r') as outfile:
original_contents = outfile.readlines()
original_contents_joined = ''.join(original_contents)
if len(original_contents) == 0:
legal_actions = ['I\n'] + list("FEST")
else:
legal_actions = get_legal_actions(
original_contents[-1], current_player, opponent)
if not legal_actions:
print "Error: file ended in invalid character"
return current_player
# Has the player completed an Exchange? Pass them new cards if so.
exchange_cards = ""
old_last_line = original_contents[-1] if len(original_contents) > 0 else '\n'
if old_last_line[-1] != '\n' and old_last_line[0] == 'E' and \
len(old_last_line) % 2 == 0 and old_last_line[-1] in "p_'<=0":
exchange_cards = punishment_to_reveal[deck.pop()] + \
punishment_to_reveal[deck.pop()]
cards = exchange_cards + ''.join(
punishment_to_reveal[card] for card in current_player.cards)
args = current_player.command + [
outfilename,
str(opponent.coins),
str(current_player.coins),
cards
] + legal_actions
print ' '.join(args)
output = ""
os.chdir(current_player.name)
try:
output = subprocess.check_output(args)
# Competitors that fail to execute must forfeit
except subprocess.CalledProcessError:
print current_player.name, "forfeits by non-zero exit status"
return opponent
finally:
os.chdir('..')
new_contents = []
new_contents_joined = ""
with open(outfilename, 'r') as outfile:
new_contents = outfile.readlines()
new_contents_joined = ''.join(new_contents)
if original_contents_joined != new_contents_joined[:-2] and \
original_contents_joined != new_contents_joined[:-1]:
print current_player.name, "forfeits by modifying the file"
print "old:", original_contents
print "new:", new_contents
return opponent
new_last_line = new_contents[-1]
the_move_made = ""
for action in legal_actions:
if new_last_line.endswith(action):
the_move_made = action
break
# Competitors that make an illegal move must forfeit
if not the_move_made:
print current_player.name, "forfeits with an illegal move,",\
"last line: %r" % new_last_line
print opponent.name, "wins!"
return opponent
print current_player.name, "played %r" % the_move_made
# Side effects of moves.
#
# Income, give the current player a coin.
if the_move_made == "I\n":
print current_player.name, "received 1 coin of income"
current_player.coins += 1
# The program surrendered a card on its turn; take it away.
elif len(the_move_made) == 2:
print current_player.name, "lost a card from being challenged"
current_player.cards.remove(the_move_made[0])
# Coins are not returned from a successful Contessa block
if new_last_line[-3] == '!':
print current_player.name, "lost 3 coins from a Contessa block"
current_player.coins -= 3
# The program surrendered a card when it was not its turn.
elif the_move_made in "_'<=0":
print current_player.name, "gave up a", the_move_made
current_player.cards.remove(the_move_made)
if new_last_line[0] == 'C':
opponent.coins -= 7
elif new_last_line[0] == 'A':
opponent.coins -= 3
# Did the program unsuccessfully challenge an Assassination
# (e.g. Aq^0\n)
# or get caught falsely blocking with a Contessa
# (e.g. Asq0\n)?
# If yes, it loses right away.
if new_last_line[0] == 'A' and new_last_line[1] in 'qs' and \
len(new_last_line) == 4:
print current_player.name, "lost both cards in the same turn."
print opponent.name, "wins!"
return opponent
elif the_move_made == 'S':
print current_player.name, "attempted Steal"
elif the_move_made == 'T':
print current_player.name, "attempted Tax"
elif the_move_made == 'A':
print current_player.name, "attempted Assassinate"
elif the_move_made == 'C':
print current_player.name, "launched a Coup"
elif the_move_made == 'F':
print current_player.name, "attempted Foreign Aid"
elif the_move_made == 'E':
print current_player.name, "attempted Exchange"
elif the_move_made == 'q':
print current_player.name, "challenged"
elif the_move_made == 'p':
print current_player.name, "passed"
elif the_move_made == 'a':
print current_player.name, "blocked with an Ambassador"
elif the_move_made == 'c':
print current_player.name, "blocked with a Captain"
elif the_move_made == 's':
print current_player.name, "blocked with a Contessa"
elif the_move_made == 'd':
print current_player.name, "blocked with a Duke"
# The program revealed a card from an opponent's unsuccessful challenge.
# Give it a new card.
# Special case: a program whose Exchange is unsuccessfully challenged
# may keep the Ambassador it revealed in the Exchange, so give a new
# card for a revealed Ambassador only if it was used to block a Steal.
elif the_move_made in '^*!$' or (the_move_made == '~' and
new_last_line[0] == 'S'):
p = reveal_to_punishment[the_move_made]
current_player.cards.remove(p)
current_player.cards.append(deck.pop())
deck.append(p)
random.shuffle(deck)
print current_player.name, "did have a", the_move_made
# The program ended its turn. We must examine the rest of the line to
# determine the side effects.
elif the_move_made == '\n':
potential_winner = determine_turn_effects(
new_last_line, output.strip(), cards, current_player,
opponent)
if potential_winner:
print potential_winner.name,\
"wins because their opponent made an illegal exchange!"
return potential_winner
# One player has lost all their cards. Victory for the opponent!
if current_player.cards == []:
print opponent.name, "wins by eliminating both opponent cards!"
return opponent
current_player_index += 1
current_player_index %= 2
return None
competitors = []
competitors.append(Player("Challenger", ["./challenger"]))
competitors.append(Player("Random", ["./random"]))
# ...More competitors here
for i in range(10):
print "-- Round", i
j = 0
for pairing in itertools.permutations(competitors, 2):
player1, player2 = pairing
print '--- Game', j, ':', player1.name, 'vs.', player2.name
winner = play_game(player1, player2, i, j)
if not winner:
j += 1
continue
winner.score += 1
player1.coins = 1
player1.cards = ""
player2.coins = 1
player2.cards = ""
deck = ['_', "'", '<', '=', '0'] * 3
random.shuffle(deck)
j += 1
competitors.sort(reverse=True, key=lambda player: player.score)
for player in competitors:
print '%5d %s' % (player.score, player.name)
Lain-lain
Satu program tidak dapat memiliki kode khusus untuk program lain, dan program tidak dapat saling membantu. (Anda mungkin memiliki banyak program, tetapi mereka tidak dapat berinteraksi satu sama lain dengan cara apa pun.)
Jika program Anda kehilangan kedua kartunya dalam giliran yang sama, ia hanya perlu menulis satu. Arbiter akan mendeteksi bahwa ia telah dihilangkan.
Dimungkinkan dan didorong, tetapi tidak diwajibkan, bagi program untuk memeriksa sejarah gim dalam file. Dengan melakukan itu mereka dapat menentukan kartu apa yang diklaim dimiliki lawan dan menangkapnya dalam kebohongan.
Dalam gim kudeta yang sebenarnya, Anda dapat menantang suatu tindakan dan kemudian mencoba untuk memblokirnya pada giliran yang sama. Saya tidak dapat membuat spesifikasi berfungsi jika saya mengizinkannya, jadi Anda dapat menantang atau memblokir tindakan yang diberikan, tetapi tidak keduanya.
Permintaan maaf saya kepada @PeterTaylor, yang pada waktu sebelumnya saya memposting ini menyarankan agar saya mempostingnya ke kotak pasir dan mengerjakan ulang protokol untuk mengirim keluar dan keluar pipa di STDOUT / STDIN. Saya mencoba begitu, sangat sulit untuk membuatnya bekerja, menghabiskan satu hari penuh di atasnya (ketika saya sudah menghabiskan satu hari penuh menulis tantangan asli). Tetapi Pertukaran terbukti sangat rumit untuk diterapkan seperti itu, ditambah lagi itu akan meningkatkan kompleksitas pengiriman dengan mengharuskan mereka untuk melacak jumlah koin mereka sendiri. Jadi saya telah memposting tantangan kurang lebih seperti aslinya.
sumber
S
, program B memblokir dengan menulisc
, A menolak tantangan dengan menulis\n
. Tantangan Steal yang berhasil adalah: A menulisS
, B menantang dengan menulisq
, A mengakui tantangan dengan menulis misalnya_\n
, Anda hanya dapat mengambil satu tindakan per giliran, termasuk Exchange. Respons hukum terhadap Exchange lulus dan menantang.Jawaban:
Kalkulator
Merencanakan serangkaian langkah kemenangannya, dan menantang apa pun yang akan mencegahnya menang.
Pengkhianat
Mengatakan yang sebenarnya pada awalnya, tetapi mulai berbohong ketika berhenti ditantang. Juga memiliki beberapa perilaku solver. (Perkiraan bagaimana saya berperilaku saat bermain game ini dengan manusia)
Bandit
Mencoba menyingkirkan Duta dan Kapten lawan, dan menang dengan mencuri.
Pembunuhan berdarah
Sebagai lawan dari Bandit, yang ini cocok dengan strategi Duke + Assassin.
sumber
Solver
Solver mencoba mengingat kartu apa yang dimainkan sebelumnya dan apa gerakan lawan sebelumnya.
ini adalah versi ke-2 yang belum selesai (dan sekarang berantakan)
untuk membuatnya bekerja pada simpul 10 tambahkan
competitors.append(Player("Solver", ["node", "--experimental-modules", "./solver.mjs"]))
jika simpul 12
competitors.append(Player("Solver", ["node", "./solver.js"]))
hati-hati dengan jenis file
sumber
Pengacara
Pengacara membuat jalannya dengan hati-hati melalui dunia, tidak pernah berbohong, menghalangi bila mungkin, menantang ketika tidak segera merugikannya. Dia tidak menyerang kecuali jika diminta melalui kuping, tetapi akan mengambil koin sesering mungkin untuk kudeta dengan cepat. Dia cukup pintar untuk mengorbankan kartu yang tidak dia gunakan pertama kali, tetapi tidak cukup pintar untuk menggunakannya untuk menyingkirkannya dan mendapatkan yang baru.
Mungkin ada bug dalam program ini. Ketika Anda menemukan mereka, tolong beri tahu saya.
sumber
Acak
Random tidak tahu apa yang harus dilakukan, jadi dia secara acak memilih sesuatu yang legal.
Penantang
Challenger tidak mempercayai siapa pun dalam permainan tipuan ini. Jika Anda melakukan sesuatu yang menantang, dia akan menantang Anda. Kalau tidak, dia hanya mengambil penghasilan setiap belokan dan mencoba untuk menggugat Anda jika dia memiliki koin.
Kompilasi program-program ini dengan
go build random.go/challenger.go
dan jalankan dengan./random
atau./challenger
.sumber
Petugas pajak
Taxman ada di sini untuk mengambil pajak. Gunakan pembunuh jika mereka memilikinya. Hanya memblokir jika mereka memiliki kartu untuk diblokir. Secara acak tantangan.
Ditulis dalam c #, saya menghabiskan terlalu lama membangun hirarki kelas untuk semua tindakan berbeda yang dapat diambil.
Sunting: Sekarang dengan logika yang ditingkatkan seperti tidak mengklaim memiliki adipati ketika mereka menyerah adipati setelah ditantang. Juga tidak lagi mencoba untuk terus membunuh jika lawan memblok dengan contessa (dan tidak ditantang).
sumber
determine_turn_effects()
, tindakan Mencuri mengambil semua koin lawan. Itu harus mengambil paling banyak dua koin.Rando Aggro Pengacara
Mirip dengan pengacara, itu hanya melakukan hal-hal hukum. Namun Assassinates, kudeta sebelumnya, dan ia memilih beberapa tindakan secara acak (seperti kapan harus Tantangan).
sumber
Topeng
Topeng adalah master penyamaran. Dia mencegah lawan dari melacak kartunya dengan Bertukar setiap kali dia bertindak atau memblokir. Strategi kemenangannya adalah mengambil 3 koin sebagai Duke, lalu Assassinate.
Kompilasi dengan
go build mask.go
, jalankan dengan./mask
.sumber
Penjudi
Penjudi memiliki strategi yang disempurnakan tetapi mempercayai ususnya ketika suatu situasi tidak diperhitungkan dalam strategi kemenangannya. Dia mencoba mencuri banyak dan kudeta / pembunuhan bila memungkinkan.
Ditulis dalam Python3:
Ahli statistik
Tahu strategi kemenangannya, seperti penjudi, tetapi selalu mempercayai probabilitas maksimum alih-alih mengambil sampel secara acak dari mereka.
sumber
Traceback (most recent call last): File "gambler.py", line 94, in <module> otherhand = guess_opponents_hand() File "gambler.py", line 61, in guess_opponents_hand card_counts[card_give_up.index(card_1)] -= 1 ValueError: ['_'] is not in list
.\n
alih-alih kartu yang ingin mereka menyerah. Dalam situasi seperti itu, lebih baik melawan dengan rintangan atau tantangan. Jika Gambler memenangkan 5 pertandingan yang hangus seperti ini, itu akan terjadi di tempat pertama.