Liderler Sıralaması
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
Günlük ve tüm çıktı dosyaları dahil en son eşleşmenin bir arşivi mevcuttur.
Brilliand tarafından Hesaplama kazanır! Cevabı kabul edildi, ancak bu mücadelenin sona erdiği anlamına gelmiyor. Yeni girişler göndermekten veya mevcut girişlerinizi düzenlemekten çekinmeyin ve tahtından indirmeye çalışın. Ay sonunda lidere bir ödül vereceğim.
Oyun Kuralları
Coup , 2 ile oynayacağımız 2-6 oyuncu için tasarlanmış bir kart oyunudur. Bir hazine (amaçlarımız için sonsuz) ve aşağıdaki kartların her birini 3 içeren 15 kartlık bir desteden oluşur: Büyükelçi, Assassin, Kaptan, Contessa, Duke. Oyunun başlangıcında, her oyuncuya bir jeton verilir ve rastgele iki kart dağıtılır; Amaç elinizde kart olan son oyuncu olmaktır.
Sırayla, bir oyuncu kartlarından bağımsız olarak aşağıdaki işlemlerden birini yapabilir:
- Gelir: hazineden 1 jeton al. Engellenemez ve tartışılmaz.
- Dış Yardım: hazineden 2 jeton alın. Duke'lu bir oyuncu tarafından engellenebilir. Tartışılmaz.
- Darbe: Seçtiğiniz bir rakibin kartını oyundan kaldırın. 7 jeton maliyeti. Mağdur hangi kartı atacağını seçebilir. Bir oyuncunun sırası başında 10 veya daha fazla jetonu varsa, Darbe yapması gerekir . Engellenemez ve tartışılmaz.
Kartlarına bağlı olarak, oyuncular sırayla aşağıdaki eylemlerden birini de yapabilirler:
- Değişim: Büyükelçi olan bir oyuncu desteden iki kart alabilir. Daha sonra ellerinden ve çizilen kartlardan başlangıçta sahip oldukları kadar kart seçebilirler. (Yani, sadece bir kartları varsa, kartlardan birini çekebilir veya saklayabilirler ve iki kartları varsa, dört karttan herhangi birini seçebilirler.) İstenmeyen iki kart desteye iade edilir. . Engellenemez, ancak meydan okunabilir.
- Suikastçı: Suikastçı olan bir oyuncu, rakibin kartını oyundan çıkarmak için 3 jeton harcayabilir. Mağdur hangi kartı atacağını seçebilir. Contessa olan bir oyuncu tarafından engellenebilir, bu durumda paralar iade edilmez. Meydan okunabilir, bu durumda paralar vardır döndü.
- Çal: Kaptanlı bir oyuncu rakibinden iki jeton alabilir. Rakibin bir jetonu varsa, o jetonu alacaktır. Rakibin sıfır parası varsa, Çalmayabilir. Büyükelçi veya Kaptanı olan bir oyuncu tarafından engellenebilir. Meydan okunabilir.
- Vergi: Dükü olan bir oyuncu hazineden 3 para alabilir. Engellenemez, ancak meydan okunabilir.
Coup'in zor kısmı, oyuncuların sahip oldukları kartlar hakkında yalan söylemelerine izin verilmesidir! Bu kartla ilişkili eylemi veya bloğu gerçekleştirmek için bir karta gerek yoktur.
Bir oyuncu bir kartın eylemini gerçekleştirdiğinde, herhangi bir rakip (o eylemden zarar görmeyen bir oyuncu bile) aktöre meydan okuyabilir ve bu eylem için karta sahip olduklarına inanmadıklarını söyleyebilir. Meydan okuyan doğru ise, eylem iptal edilir ve oyuncu istediği bir kartı atmalıdır (varsa harcanan paraları geri kazanmalıdır). Aksi takdirde, eylem yapılırsa, oyuncu meydan okudukları kartı desteye geri gönderir ve yeni bir kart çeker ve meydan okuyucunun kartlarından birini atması gerekir. Oyuncular, meydan okunduklarında hangi kartlara sahip oldukları konusunda dürüst olmalıdır.
Assassinate, Coup ve kayıp zorluklarla oyundan çıkarılan kartlar desteye iade edilmez, ancak kazanılan bir mücadelenin bir parçası olarak ortaya çıkan kartlar desteye iade edilir.
Bloklar, eylemler gibi meydan okunabilir. Örneğin, A oyuncusu Yabancı Yardım alır ve B oyuncusu "Bir Düküm var ve Yabancı Yardımınızı engelliyorum" diyorsa, A "Bir Dükünüz olduğuna inanmıyorum" diyebilir. Eğer bu iddia doğruysa, B bir yalana yakalandığı için kartını kaybeder ve A 2 jeton alır; değilse, A bir kart kaybeder ve para alamaz ve B Dükünü desteye geri götürüp yeni bir kart çekmelidir.
Suikastçı ile blokların ve zorlukların çalışma şekli ortadan kaldırılmalıdır. Oyuncu A'nın "Bir Suikastçım ve Oyuncu B'ye Suikast Ediyorum" dediğini varsayalım. B, A'ya meydan okumaya veya engellemeye çalışmazsa, suikast gerçekleşir: B bir kartı kaybeder ve A 3 para öder.
Alternatif olarak B, "Bir Suikastçı olduğuna inanmıyorum" diyerek meydan okuyabilir. Bu doğruysa, A bir kartı atar ve paraları iade edilir, B etkilenmez ve A'nın sırası sona erer. B'nin inancı yanlışsa ve A bir Suikastçı tutarsa, B hem kartlarını kaybeder hem de başarısız olur, biri yanlış meydan okuma için ve diğeri Suikasttan.
B yerine meydan okumak yerine, "Bir Contessa'm var ve Suikastçıyı engelliyorum" diyebilir. A B'ye inanırsa, A'nın dönüşü biter ve paraları iade edilmez. Ama A bloğa meydan okuyabilir ve "Ben bir Contessa olduğuna inanmıyorum" diyebilir. B aslında bir Contessa'ya sahipse, A yanlış meydan okuma için bir kart kaybeder. Ancak B yapmazsa, B yalandan yakalandığı için bir kartı kaybeder ve bir Suikast'tan başka bir kart kaybeder.
Yukarıdaki açıklamaya benzer bir mantık, kaptanın Çalma yeteneği için de geçerlidir, burada ya eylem ya da blok meydan okunabilir.
Bir Suikastçıya başarısızlıkla meydan okuduğunuzda veya bir Suikast'ı engellemek için bir Contessa'nız olduğunu iddia ettiğinizde yanlış bir şekilde yakalandığınızda, hem kartlarınızı kaybetmeniz hem de bir turda elenmeniz mümkündür. Meydan okumadan bir kart ve Suikast'tan bir kart kaybedersiniz.
Meydan okuma
Göreviniz Coup oynayacak bir program yazmaktır. Komut satırı argümanları olarak verilir:
- Şimdiye kadar kendisinin ve rakiplerinin eylemlerinin listesini içeren bir dosyanın adı.
- Rakibin jeton sayısını gösteren 0 ile 12 arasında bir tam sayı.
- Jeton sayısını gösteren 0 ile 12 arasında bir tam sayı.
- Bir ila dört karakter uzunluğunda, kartlarını gösteren bir dize. Normalde bu sadece programınızın sahip olduğu bir veya iki kart olacaktır, ancak programınız bir Exchange'de başarılı olduysa, n + 2 karakter uzunluğunda olacaktır, burada n kalan kart sayınızdır. Programınız daha sonra STDOUT'ta tutmak istediği n kartı çıkarmalıdır. (Programlar bu amaç dışında STDOUT'u okumamalı veya bunlara erişmemelidir - hata ayıklama çıktısı üretmek istiyorsanız, lütfen STDERR'a yazınız.)
- Yapabileceği yasal hareketleri gösteren bir veya daha fazla argüman.
(Örnek çağırma: yourprogram file.txt 1 7 '~!' a c p q
"Rakibinizde 1 jeton var. 7 jetonunuz, bir Büyükelçi ve bir Contessa var. Oyun geçmişine ve mevcut oyun durumuna göre a, c, p veya q seçiminizi dosya.txt dosyasına yazın. ")
Programınız sağlanan dosyaya eylemini gösteren bir veya (iki özel durumda) iki karakter eklemelidir. Dosyanın mevcut içeriğini başka şekilde değiştirmemelidir. İstediği yeni dosyaları oluşturabilir, ancak yalnızca çalıştığı dizinde oluşturabilir. Lütfen programınızı derlemek ve çalıştırmak için gerekli tüm komutları sağlayın.
Aşağıda Go dilinde yazılmış iki örnek rakip sağladım.
Çıktı biçimi:
I\n
: Gelir. Yasal tepkiler: herhangi bir dönüş eylemi (suikastçı / darbe paraları olduğu varsayılarak).F
: Dış yardım. Yasal tepkiler:d
(Dük olarak engelle),p
(geçmesine izin ver).C
: Darbe. Yasal tepkiler: hangisi_
,'
,<
,=
,0
senin elinde.E
: Değiş tokuş. Yasal tepkiler:q
(meydan okuma, oyuncunun bir Büyükelçisi olduğuna inanmamak)p
.T
: Vergi. Yasal tepkiler:q
(meydan okuma, oyuncunun bir Duke'a sahip olduğuna inanmamak)p
.A
: Suikâst düzenlemek. Yasal yanıtları:s
(a Contessa olarak blok),q
(challenge) ve hangisi arasında_
,'
,<
,=
,0
senin elinde.S
: Çalmak. Yasal tepkiler:a
(büyükelçi olarak blok),c
(kaptan olarak blok),q
(meydan okuma, oyuncunun kaptan olduğuna inanmama)p
.d
: Duke olarak Yabancı Yardımı engelle. Yasal tepkiler:\n
(bloğu kabul et),q
(meydan okuma, oyuncunun bir Duke'a sahip olduğuna inanmama).a
: Büyükelçi olarak çalmayı engelle. Yasal tepkiler:\n
(bloğu kabul et),q
(meydan okuma, oyuncunun bir Büyükelçi olduğuna inanmama).c
: Kaptan olarak çalmayı engelle.\n
(bloğu kabul et),q
(meydan okuma, oyuncunun Kaptan olduğuna inanmama).s
: Contessa olarak bir Suikastçıyı engelleyin. Yasal tepkiler:\n
(bloğu kabul edin),q
(meydan okuma, oyuncunun bir Contessa olduğuna inanmamak).p
: sıra size gelmediğinde bir Döviz / Vergi / Çalmak meydan geçmek. İle kullanılmazA
; bir Suikast'a meydan okumayı reddetmek_'<=0
. Yasal yanıt:\n
(sıranızı sonlandırın) ve eğer bir Exchange'de başarılı olduysanız, dördüncü komut satırı argümanından STDOUT'a tutmak istediğiniz kartları yazın.q
: en son eylem veya engellemeye meydan okuyun. Hukuki yanıt: itiraz edilen eylem için kartınız varsa, hangisi olursa olsun~^*!$
. Eğer yapmazsanız, o zaman hangisinden_'<=0
vazgeçmek istediğinizi, ardından sadece sıranız varsa bir satırsonu takip edin.~
,^
,*
,!
,$
: Bir Exchange sırasıyla bir Büyükelçi, bir Assassin, bir kaptan, bir Kontes, hem de komut satırı argümanları bu kartları göstermek için kullanılan bir Duke (ve STDOUT çıktı tutan doğruyu söylediğini olduklarını ortaya çıkarmıştır ). Yasal tepkiler: hangisi_
,'
,<
,=
,0
Elinizde var._
,'
,<
,=
,0
: Bir meydan okuma kaybolması veya couped / Suikast çünkü sırasıyla ceza olarak bir Büyükelçi ve Assassin, bir kaptan, bir Contessa ve Duke vazgeçmek. Yasal yanıtı:\n
.\n
: eğer varsa, bir bloğa meydan okumak için reddederek sıranızı sonlandırın. Yasal tepkiler: herhangi bir büyük harfli eylem (birinin suikastçı / darbe paraları ve rakibin çalma paraları olduğu varsayılarak).
Biçim aşağıdaki yararlı özelliklere sahiptir:
- Dönüşler büyük harfle başlar.
- Çizgiler kalıbı takip eder: büyük harf, küçük harf, isteğe bağlı noktalama işaretleri veya açık kartlar için 0, satırsonu.
- Yeni satırla veya boş bir dosyayla biten bir dosya, bunun programınızın sırasının başlangıcı olduğunu ve bir büyük harf eylemi seçmesi gerektiğini belirtir.
- Bir çağrıda bulunmanıza izin verilen yasal işlemler genellikle dosyadaki son karakter tarafından benzersiz olarak belirlenir. Bunun istisnası,
q
kendisiyle ilişkilendirilmiş bir mantığı olacaktır.get_legal_actions
Bunu anlamanıza yardımcı olması için hakemdeki işleve bakın . Veya komut satırında verdiğiniz yasal işlemleri kullanabilirsiniz. - Bir satırdaki çift sayıda karakter sıralamanın size ait olduğunu ve programınızdan bir eylem seçmesi, bir bloğa meydan okuması veya sırasını sonlandırması istenir.
- Bir satırdaki tek sayıda karakter, sıralamanın size ait olmadığını ve programınızdan bir kartı engellemesini, sınamasını veya açıklamasını / teslim etmesini istediğini gösterir.
Her eylem için bir örnek vereceğim.
I\n
anlaşılması en kolay olanıdır. Bir program bir Gelir madeni parası alır ve ardından sırasını bitirir. Bu, programların iki karakter basması gereken iki durumdan biridir, çünkü Gelir, rakibin hem etkilenmediği hem de engelleyemediği veya meydan okuyamayacağı tek eylemdir.
Fp\n
bir programın Dış Yardım alması anlamına gelir, daha sonra rakibi engellemeyi reddetti ( p
). Bir sonraki çağrıldığında, ilk program, son küçük harf p
ve / veya bu satırdaki çift karakter sayısı ile henüz bitmemiş olan bu dönüşü aldığını, bu nedenle yeni satırını yazarak mevcut sırasını bitirmeyi bildiğini kaydetti.
C=\n
bir programın bir Darbe başlattığı anlamına gelir. Rakibin, hattaki garip harflerle tepki vermeye çağrıldığını bilerek, bir Contessa'dan vazgeçti. Yine, ilk program bunun satırdaki çift karakterle bir sonraki çağrışımındaki eksik dönüşü olduğunu biliyordu, bu yüzden sırasını bitirmek için yeni bir satır yazdı.
Eq~<\n
bir programın Exchange ( E
) denemesi ve rakibinin ( q
) meydan okuması anlamına gelir . Değişim programı, hakikaten bir Büyükelçiye ( ~
) sahip olduğunu ve meydan okuyucunun bir Kaptan'ı ceza olarak ( <
) verdiğini ortaya koydu . Meydan okumadan çıktıktan sonra, Değişim programı tekrar dördüncü komut satırı argümanı olarak dört karakterli bir dize (veya yalnızca bir kartı varsa üç karakter) ile çağrılır. STDOUT'ta tutmak istediği kartları temsil eden karakterleri ve dosyaya yeni bir satır yazar.
Tq'\n
bir programın gerçeğe aykırı bir Vergiyi denediğini, itiraz edildiğini ve bir Suikastçıdan vazgeçtiğini gösterir. İki karakterin yazıldığı diğer durumu gösterir: eğer sıranızsa ve bir karttan vazgeçmek zorunda kalırsanız - ya bir rakibin doğru meydan okumasından (burada olduğu gibi) ya da bir bloğun yanlış meydan okumasından - her ikisini de yazmalısınız vazgeçtiğiniz kart ve sıranızı sonlandırmak için bir yeni satır.
Asq!'\n
Oyuncu B'nin oyuncu A ( A
) Suikast girişiminde bulunmaya çalıştığı , ancak A'nın onu engellemek için bir Contessa'ya sahip olduğu iddia edildi ( s
). B A'ya inanmadı ve meydan okudu ( q
). Aslında, bir Contessa ( !
) sahip olduklarını ortaya koydu . B bir Assassin'i ceza olarak bıraktı, madeni paralarını kaybetti ve '\n
bu özel durumdaki gibi iki karakter yazarak sırayla ( ) sona erdi . (A engellememeye veya meydan okumaya karar vermemiş =
olsaydı, yazabilirdi ve sonra rakibi dönüşün bittiğini ve yeni bir satır yazdığını görürdü. Çizgi A=\n
, Coup örneği gibi okuyacaktır .)
Sq*0\n
bir programın Çalma girişiminde bulunduğu anlamına gelir; rakibin, hırsızın bir Kaptan olduğuna inanmamasına meydan okuyor; ve orijinal program bir Kaptan ortaya çıkarır, bu yüzden meydan okuma başarısız olur ve meydan okuyan bir Dük'ü ceza olarak bırakır. (Rakibinin başka bir seçeneği de çalma işlemini yazarak kabul etmek olacaktır p
. Rakibi daha sonra sıranın sonunu algılayıp \n
bir satırla sonuçlanacaktı Sp\n
.)
Hakem
Programlar bu Python betiği tarafından çağrılır. Her yarışmacının hem birinci hem de ikinci sırada yer alırken diğer rakiplerle karşılaştığı on tur yapar. Kartları ve jeton sayımlarını izler ve noktalama işaretiyle bir çizgiyi iki kez bitirmek için ilk program tarafından kaybedeni belirler. Sıfırdan farklı bir durumla çıkan, dosyayı değiştiren, dosyaya yasadışı bir hareket yazan veya yasadışı bir Exchange girişiminde bulunan programlar otomatik olarak kaybedecektir. Her oyuncu, kazananlar olmadan bloklar ve zorluklar da dahil olmak üzere 100'den fazla işlem yaparsa, her iki program da kaybeder. Bir kazanana bir puan verilir. Programı en çok puan alan oyuncu kazanır.
Hakemin kaynak kodunu, özellikle get_legal_actions
işlevi okumanızı tavsiye ederim . Şartnameyi anlamanıza ve kendi programlarınızı yazmanıza yardımcı olabilir.
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)
Çeşitli
Bir program başka bir program için özel koda sahip olamaz ve programlar birbirlerine yardımcı olamaz. (Birden fazla programınız olabilir, ancak birbirleriyle hiçbir şekilde etkileşim kuramazlar.)
Programınız her iki kartını da aynı sırayla kaybederse, sadece bir tane yazmanız gerekir. Hakem, ortadan kaldırıldığını tespit edecektir.
Programların oyunun dosyadaki geçmişini incelemesi mümkün ve teşvik edilir, ancak zorunlu değildir. Böylece rakibinin sahip olduğu kartları belirleyebilir ve onları bir yalanda yakalayabilirler.
Gerçek Coup oyununda, bir aksiyona meydan okuyabilir ve daha sonra aynı sırayla engellemeye çalışabilirsiniz. Buna izin verirsem spesifikasyonu çalıştıramadım, bu nedenle belirli bir eylemi zorlayabilir veya engelleyebilirsiniz, ancak her ikisini birden yapamazsınız.
@PeterTaylor'a özür dilerim, bunu daha önce yayınladığımda bunu sandbox'a gönderip STDOUT / STDIN'de boru çıkışını ileri geri borulamak için protokolü yeniden çalışmamı önerdi. Bu işi yapmak için çok uğraştım, üzerinde tam bir gün geçirdim (orijinal meydan okumayı yazmak için tam bir gün geçirdiğimde). Ancak Borsaların bu şekilde uygulanması çok karmaşıktı, artı kendi para sayımlarını takip etmelerini isteyerek gönderimlerin karmaşıklığını artıracaktı. Bu yüzden meydan okumayı başlangıçta olduğu gibi az çok yayınladım.
S
, B programı yazarak bloklar c
, A yazarak meydan okumayı reddeder \n
. Bir çalmanın başarılı bir meydan okuması giderdi: A yazar S
, B yazarak meydan okuyor q
, A meydan okumayı yazarak kabul ediyor, örneğin _\n
Exchange dahil her turda sadece bir işlem yapabilirsiniz. Borsa'ya verilen yasal yanıtlar başarılı ve zordur.