Classement
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
Calculatrice, par Brilliand, est le gagnant! Sa réponse est acceptée, mais cela ne signifie pas que le défi est terminé. N'hésitez pas à soumettre de nouvelles entrées ou à modifier vos entrées actuelles et essayez de le faire tomber de son trône. J'offrirai une prime au leader à la fin du mois.
Règles de jeu
Coup est un jeu de cartes conçu pour 2 à 6 joueurs, auquel nous jouerons à deux. Il se compose d'un trésor de pièces (infini pour nos besoins) et d'un jeu de 15 cartes, contenant 3 de chacun des types suivants: ambassadeur, assassin, capitaine, Contessa, duc. Au début de la partie, chaque joueur reçoit une pièce et reçoit deux cartes au hasard, qu'il garde secrètes jusqu'à ce que cela soit nécessaire. Le but est d'être le dernier joueur avec des cartes en main.
À son tour, un joueur peut effectuer l'une des actions suivantes quelles que soient ses cartes:
- Revenu: prenez 1 pièce du trésor. Imblocable et incontestable.
- Aide étrangère: prenez 2 pièces du trésor. Peut être bloqué par un joueur avec un duc. Indiscutable.
- Coup: Retirez une carte d'un adversaire de votre choix du jeu. Coûte 7 pièces. La victime peut choisir la carte à défausser. Si un joueur a 10 pièces ou plus au début de son tour, il doit Couper. Imblocable et incontestable.
En fonction de leurs cartes, les joueurs peuvent également effectuer l'une des actions suivantes à leur tour:
- Échange: un joueur avec un ambassadeur peut prendre deux cartes du paquet. Ensuite, ils peuvent choisir dans leur main et les cartes tirées autant de cartes qu'ils en avaient à l'origine. (Autrement dit, s'ils n'avaient qu'une seule carte, ils peuvent l'échanger contre l'une des cartes piochées ou la conserver, et s'ils avaient deux cartes, ils peuvent choisir deux des quatre cartes.) Les deux cartes indésirables sont retournées dans le jeu. . Imblocable, mais contestable.
- Assassinat: un joueur avec un assassin peut dépenser 3 pièces pour retirer la carte d'un adversaire du jeu. La victime peut choisir la carte à défausser. Peut être bloqué par un joueur avec une Contessa, auquel cas les pièces ne sont pas restituées. Difficile, auquel cas les pièces sont retournées.
- Vol: un joueur avec un capitaine peut prendre deux pièces à son adversaire. Si l'adversaire a une pièce, il prendra cette seule pièce. Si l'adversaire n'a aucune pièce, il ne peut pas voler. Peut être bloqué par un joueur avec un ambassadeur ou un capitaine. Difficile.
- Taxe: Un joueur avec un duc peut prendre 3 pièces du trésor. Imblocable, mais contestable.
La partie délicate de Coup est que les joueurs peuvent mentir sur les cartes qu'ils ont! Il n'est pas nécessaire d'avoir une carte pour tenter d'effectuer l'action ou le blocage qui lui est associé.
Lorsqu'un joueur effectue l'action d'une carte, tout adversaire (même celui qui n'est pas blessé par cette action) peut défier l'acteur et dire qu'il ne croit pas avoir la carte pour cette action. Si le challenger a raison, l'action est annulée et l'acteur doit défausser une carte de son choix (en récupérant les pièces dépensées le cas échéant). Si ce n'est pas le cas, l'action est entreprise, l'acteur renvoie la carte sur laquelle il a été mis au défi et en pioche une nouvelle, et le challenger doit défausser une de ses cartes. Les joueurs doivent être honnêtes sur les cartes qu'ils détiennent lorsqu'ils sont mis au défi.
Les cartes éliminées du jeu avec Assassinat, Coup et les défis perdus ne sont pas retournées dans le jeu, mais les cartes révélées dans le cadre d'un défi gagné sont retournées dans le jeu.
Les blocs peuvent être contestés tout comme les actions. Par exemple, si le joueur A demande l'aide étrangère et que le joueur B dit "J'ai un duc et je bloque votre aide étrangère", A peut dire "je ne crois pas que vous ayez un duc". Si cette affirmation est correcte, B perd une carte pour avoir été pris dans un mensonge et A prend 2 pièces; si ce n'est pas le cas, A perd une carte et ne reçoit aucune pièce, et B doit retourner son duc dans le jeu et piocher une nouvelle carte.
La façon dont les blocs et les défis fonctionnent avec Assassinat doit être étoffée. Supposons que le joueur A dise "J'ai un assassin et j'assassine le joueur B". Si B n'essaie pas de défier ou de bloquer A, alors l'assassinat passe: B perd une carte et A paie 3 pièces.
Alternativement, B peut contester en disant "Je ne crois pas que vous ayez un Assassin". Si c'est vrai, A défausse une carte et leurs pièces sont retournées, tandis que B n'est pas affecté et le tour de A se termine. Si la croyance de B est incorrecte et que A détient un assassin, alors B perd ses deux cartes et échoue, un pour le défi incorrect et un pour l'assassinat.
Au lieu de contester, B pourrait dire "J'ai une Contessa et je bloque l'Assassinat". Si A croit B, alors le tour de A se termine et leurs pièces ne sont pas retournées. Mais A peut contester le blocage et dire "Je ne crois pas que vous ayez une Contessa". Si B détient en fait une Contessa, alors A perd une carte pour le défi incorrect. Mais si B ne le fait pas, alors B perd une carte pour avoir été pris dans un mensonge et une autre de l'assassinat.
Une logique similaire à l'explication ci-dessus s'applique à la capacité de vol du capitaine, où l'action ou le blocage peut être contesté.
Il est possible de perdre vos deux cartes et d'être éliminé en un tour, si vous défiez un Assassinat sans succès ou si vous êtes surpris en train de prétendre que vous avez une Contessa pour bloquer un Assassinat. Vous perdez une carte du défi et une carte de l'assassinat.
Défi
Votre tâche consiste à écrire un programme qui jouera Coup. Il sera donné comme arguments de sa ligne de commande:
- Le nom d'un fichier contenant la liste de ses actions et celles de ses adversaires jusqu'à présent.
- Un entier de 0 à 12 indiquant le nombre de pièces de l'adversaire.
- Un entier de 0 à 12 indiquant son nombre de pièces.
- Une chaîne de un à quatre caractères indiquant ses cartes. Normalement, ce sera simplement la ou les deux cartes de votre programme, mais si votre programme vient de réussir un échange, il comportera n + 2 caractères, où n est votre nombre de cartes restantes. Votre programme doit ensuite sortir les n cartes qu'il souhaite conserver sur STDOUT. (Les programmes ne doivent pas lire ou accéder à STDOUT autrement qu'à cette fin - si vous souhaitez produire une sortie de débogage, veuillez écrire à STDERR.)
- Un ou plusieurs arguments indiquant les mesures légales qu'il peut prendre.
(Exemple d'invocation:, yourprogram file.txt 1 7 '~!' a c p q
ce qui signifie «Votre adversaire a 1 pièce. Vous avez 7 pièces, un ambassadeur et une Contessa. Écrivez dans file.txt votre choix de a, c, p ou q compte tenu de l'historique du jeu et de l'état actuel du jeu. ")
Votre programme doit ajouter un ou (dans deux situations spécifiques) deux caractères au fichier fourni indiquant son action. Il ne doit pas autrement modifier le contenu existant du fichier. Il peut créer tous les nouveaux fichiers qu'il souhaite, mais uniquement dans le répertoire dans lequel il est exécuté. Veuillez fournir toutes les commandes nécessaires pour compiler et exécuter votre programme.
J'ai fourni deux exemples de concurrents ci-dessous, écrits en Go.
Le format de sortie est:
I\n
: Le revenu. Réponses légales: toute action de tour (en supposant que l'on a les pièces pour Assassiner / Coup).F
: L'aide étrangère. Réponses juridiques:d
(bloquer en tant que duc),p
(laisser passer).C
: Coup. Réponses juridiques: selon des_
,'
,<
,=
,0
est dans votre main.E
: Échange. Réponses juridiques:q
(défi, ne pas croire que le joueur a un ambassadeur),p
.T
: Impôt. Réponses juridiques:q
(défi, ne pas croire que le joueur a un duc),p
.A
: Assassiner. Réponses juridiques:s
(bloc comme Contessa),q
(défi), et celui des_
,'
,<
,=
,0
est dans votre main.S
: Voler. Réponses juridiques:a
(bloc à titre d'ambassadeur),c
(bloc en tant que capitaine),q
(défi, ne pas croire que le joueur a un capitaine),p
.d
: bloquer l'aide étrangère en tant que duc. Réponses légales:\n
(accepter le bloc),q
(contester, ne pas croire que le joueur a un duc).a
: bloquer un vol en tant qu'ambassadeur. Réponses légales:\n
(accepter le bloc),q
(contester, ne pas croire que le joueur a un ambassadeur).c
: bloquer un vol en tant que capitaine.\n
(accepter le bloc),q
(défi, ne pas croire que le joueur a un capitaine).s
: bloquez un assassin en tant que Contessa. Réponses légales:\n
(accepter le bloc),q
(contester, ne pas croire que le joueur a une Contessa).p
: passez un défi en échange / taxe / vol quand ce n'est pas votre tour. Non utilisé avecA
; pour refuser de défier un assassinat, écrivez-en un_'<=0
. Réponse juridique:\n
(terminez votre tour), et si vous venez de réussir un échange, écrivez les cartes que vous souhaitez conserver du quatrième argument de ligne de commande à STDOUT.q
: défiez l'action ou le blocage le plus récent. Réponse juridique: si vous avez la carte de l'action contestée, quelle~^*!$
qu'elle soit. Si vous ne le faites pas, alors celui de_'<=0
votre main que vous souhaitez abandonner, suivi d'une nouvelle ligne si et seulement si c'est votre tour.~
,^
,*
,!
,$
: Révélez que vous disiez la vérité sur la détention, respectivement, un ambassadeur, un assassin, un capitaine, un Contessa, et un duc (également utilisé pour représenter ces cartes dans les arguments de ligne de commande, et STDOUT sortie dans un échange ). Réponses juridiques: selon de_
,'
,<
,=
,0
vous avez dans votre main._
,'
,<
,=
,0
: Renoncer comme punition, respectivement, un ambassadeur, et Assassin, un capitaine, un Contessa, et un duc parce que vous avez perdu un défi ou ont été assassinés / couped. Réponse juridique:\n
.\n
: terminez votre tour, ce faisant en refusant de défier un bloc si applicable. Réponses juridiques: toute action en majuscule (en supposant que l'on a les pièces pour Assassinat / Coup et que l'adversaire a les pièces pour Vol).
Le format a les propriétés utiles suivantes:
- Les virages commencent par une majuscule.
- Les lignes suivent le modèle: lettre majuscule, lettres minuscules, éventuellement signes de ponctuation ou 0 pour les cartes révélées, retour à la ligne.
- Un fichier se terminant par une nouvelle ligne, ou un fichier vide, indique que c'est le début du tour de votre programme et qu'il doit choisir une action en majuscule.
- Les actions en justice que vous êtes autorisé à entreprendre pour une invocation sont généralement uniquement déterminées par le dernier caractère du fichier. L'exception est
q
, qui aura une certaine logique associée. Voir la fonctionget_legal_actions
dans l'arbitre pour aider à comprendre cela. Ou vous pouvez simplement utiliser les actions en justice qui vous sont données sur la ligne de commande. - Un nombre pair de caractères sur une ligne indique que le tour vous appartient et que votre programme est invité à choisir une action, à défier un bloc ou à terminer son tour.
- Un nombre impair de caractères sur une ligne indique que le tour n'est pas le vôtre et votre programme est invité à bloquer, défier ou révéler / rendre une carte.
Je vais donner un exemple pour chaque action.
I\n
est le plus facile à comprendre. Un programme prend une pièce de revenu, puis termine son tour. C'est l'un des deux cas où les programmes doivent imprimer deux caractères, car Income est la seule action où l'adversaire n'est pas affecté et ne peut pas bloquer ou contester.
Fp\n
signifie qu'un programme a pris l'aide étrangère, puis son adversaire a refusé de bloquer ( p
). Lors de sa prochaine invocation, le premier programme a noté que, par le dernier minuscule p
et / ou le nombre pair de caractères sur cette ligne, il a pris ce tour, qui n'est pas encore terminé, il sait donc terminer son tour en cours en imprimant un retour à la ligne.
C=\n
signifie qu'un programme a lancé un coup d'État. Son adversaire, sachant qu'il a été appelé à réagir par le nombre impair de lettres sur la ligne, a renoncé à une Contessa. Encore une fois, le premier programme savait que c'était son tour incomplet lors de sa prochaine invocation par le nombre pair de caractères sur la ligne, il a donc écrit une nouvelle ligne pour terminer son tour.
Eq~<\n
signifierait qu'un programme tentait un échange ( E
) et son adversaire le contestait ( q
). Le programme d'échange a révélé qu'il avait véritablement un ambassadeur ( ~
) et le challenger a renoncé à un capitaine en guise de punition ( <
). Après la sortie du challenger, le programme d'échange est à nouveau invoqué avec une chaîne de quatre caractères comme quatrième argument de ligne de commande (ou trois caractères, s'il n'avait qu'une seule carte). Il écrit les caractères représentant les cartes qu'il souhaite conserver dans STDOUT et une nouvelle ligne dans le fichier.
Tq'\n
signifie qu'un programme a tenté une taxe mensongère, a été contesté et a abandonné un assassin. Il illustre l'autre cas où deux caractères sont écrits: si c'est votre tour et que vous êtes obligé de renoncer à une carte - soit du défi correct d'un adversaire (comme ici) ou de votre défi incorrect d'un bloc - alors vous devez écrire les deux la carte que vous abandonnez et une nouvelle ligne pour terminer votre tour.
Asq!'\n
signifierait que le joueur B tentait d'assassiner le joueur A ( A
), mais A prétendait avoir une Contessa pour le bloquer ( s
). B n'a pas cru A et a contesté ( q
). A a révélé qu'ils avaient en fait une Contessa ( !
). B a renoncé à un assassin en guise de punition, a perdu ses pièces et a terminé son tour ( '\n
), écrivant deux personnages comme dans ce cas particulier. (Si A avait décidé de ne pas bloquer ou contester, il aurait pu écrire =
, puis son adversaire aurait vu que le tour était terminé et écrit une nouvelle ligne. La ligne aurait alors lu A=\n
, comme l'exemple du coup d'Etat.)
Sq*0\n
signifie qu'un programme tente un vol; l'adversaire défie, ne croyant pas que le voleur a un capitaine; et le programme original révèle un capitaine, donc le défi échoue et le challenger abandonne un duc comme punition. (Une autre option pour son adversaire serait d'accepter le Vol en écrivant p
. Son adversaire détecterait alors la fin de son tour et écrirait \n
, résultant en une ligne de Sp\n
.)
L'arbitre
Les programmes seront invoqués par ce script Python. Il effectue dix tours, dans lesquels chaque compétiteur affronte tous les autres concurrents tout en allant en premier et en deuxième. Il suit les cartes et le nombre de pièces et détermine le perdant par le premier programme pour terminer une ligne avec un signe de ponctuation deux fois. Les programmes qui se terminent avec un état différent de zéro, modifient le fichier, écrivent un déplacement illégal dans le fichier ou tentent un échange illégal seront automatiquement perdus. Si chaque joueur effectue plus de 100 actions, y compris des blocs et des défis, sans gagnant, les deux programmes perdent. Un gagnant obtient un point. Le joueur dont le programme marque le plus de points gagne.
Je vous suggère de lire le code source de l'arbitre, en particulier la get_legal_actions
fonction. Cela peut vous aider à comprendre les spécifications et à écrire vos propres programmes.
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)
Divers
Un programme ne peut pas avoir de code spécifique pour un autre programme et les programmes ne peuvent pas s'entraider. (Vous pouvez avoir plusieurs programmes, mais ils ne peuvent en aucun cas interagir les uns avec les autres.)
Si votre programme perd ses deux cartes au cours du même tour, il suffit d'en écrire une. L'arbitre détectera qu'il a été éliminé.
Il est possible et encouragé, mais pas obligatoire, que les programmes examinent l'historique du jeu dans le fichier. Ce faisant, ils peuvent déterminer quelles cartes leur adversaire prétend avoir et les attraper dans un mensonge.
Dans le vrai jeu de Coup, vous pouvez défier une action puis tenter de la bloquer au même tour. Je ne pourrais pas faire fonctionner la spécification si je le permettais, vous pouvez donc contester ou bloquer une action donnée, mais pas les deux.
Mes excuses à @PeterTaylor, qui la dernière fois que j'ai posté cela, m'a suggéré de le poster dans le bac à sable et de retravailler le protocole pour diriger la sortie dans les deux sens dans STDOUT / STDIN. J'ai essayé, tellement difficile de faire fonctionner ça, en y passant une journée entière (alors que j'avais déjà passé une journée entière à écrire le défi d'origine). Mais les échanges se sont révélés très compliqués à mettre en œuvre de cette façon, et cela aurait augmenté la complexité des soumissions en les obligeant à garder une trace de leur propre nombre de pièces. J'ai donc posté le challenge plus ou moins tel qu'il était à l'origine.
la source
S
, le programme B bloque en écrivantc
, A refuse de contester en écrivant\n
. Un défi réussi d'un vol irait: A écritS
, B défis en écrivantq
, A concède le défi en écrivant par exemple_\n
, vous ne pouvez effectuer qu'une seule action par tour, y compris Exchange. Les réponses juridiques à Exchange sont pass et challenge.Réponses:
Calculatrice
Planifie sa série de coups gagnants et défie tout ce qui pourrait l'empêcher de gagner.
Transfuge
Dit la vérité au début, mais commence à mentir quand elle cesse d'être contestée. A également un comportement de solveur. (Une approximation de la façon dont je me comporte lorsque je joue à ce jeu avec des humains)
Bandit
Essaie de se débarrasser des ambassadeurs et capitaines de l'adversaire et gagnez en volant.
Meurtre sanglant
En contrepartie de Bandit, celui-ci fait tapis avec une stratégie Duke + Assassin.
la source
Solveur
Le solveur essaie de se rappeler quelles cartes ont été jouées avant et quels ont été les coups précédents de l'adversaire.
c'est la 2ème version pas encore terminée (et c'est un gros bordel maintenant)
pour le faire fonctionner sur le noeud 10 ajouter
competitors.append(Player("Solver", ["node", "--experimental-modules", "./solver.mjs"]))
si noeud 12
competitors.append(Player("Solver", ["node", "./solver.js"]))
attention au type de fichier
la source
Avocat
L'avocat parcourt le monde avec prudence, ne mentant jamais, bloquant quand c'est possible, défiant quand ce n'est pas à son détriment immédiat. Il n'attaque pas, sauf si le coupage l'exige, mais il prendra les pièces aussi souvent que possible afin de faire un coup rapide. Il est assez intelligent pour sacrifier des cartes qu'il n'utilise pas en premier, mais pas assez intelligent pour les utiliser pour s'en débarrasser et en obtenir de nouvelles.
Il y a probablement des bogues dans ce programme. Lorsque vous les trouverez, faites-le moi savoir.
la source
Aléatoire
Random ne sait pas quoi faire, il sélectionne donc au hasard quelque chose de légal.
Challenger
Challenger ne fait confiance à personne dans ce jeu de tromperie. Si vous faites quelque chose de contestable, il vous défiera. Sinon, il prend juste des revenus à chaque tour et essaie de vous couper s'il a les pièces.
Compilez ces programmes avec
go build random.go/challenger.go
et exécutez avec./random
ou./challenger
.la source
Percepteur
Le Taxman est là pour percevoir la taxe. Utilise un assassin s'il en a un. Ne bloque que s'ils ont la carte à bloquer. Défis aléatoires.
Écrit en c #, j'ai passé beaucoup trop de temps à construire une hiérarchie de classe pour toutes les différentes actions qui peuvent être entreprises.
Edit: Maintenant avec une logique améliorée comme ne prétendant pas avoir un duc quand ils ont abandonné un duc après avoir été mis au défi. N'essaie plus non plus d'assassiner continuellement si l'adversaire bloque avec contessa (et n'est pas contesté).
la source
determine_turn_effects()
, l'action Steal prend toutes les pièces de l'adversaire. Il devrait prendre au plus deux pièces.Avocat Rando Aggro
Semblable à l'avocat, il ne fait que des choses légales. Cependant, il assassine, frappe plus tôt et choisit certaines actions au hasard (comme quand défier).
la source
Masque
Le masque est un maître du déguisement. Il empêche les adversaires de garder une trace de ses cartes en échangeant chaque fois qu'il agit ou bloque. Sa stratégie gagnante consiste à prendre 3 pièces en tant que duc, puis assassiner.
Compilez avec
go build mask.go
, exécutez avec./mask
.la source
Joueur
Le joueur a une stratégie étoffée mais fait confiance à son instinct lorsqu'une situation n'est pas prise en compte dans sa stratégie gagnante. Il essaie de voler beaucoup et frappe / assassine autant que possible.
Écrit en Python3:
Statisticien
Connaît sa stratégie gagnante, tout comme le joueur, mais fait toujours confiance aux probabilités maximales au lieu de les échantillonner au hasard.
la source
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
place de la carte à laquelle elles souhaitent renoncer. Dans une telle situation, il est préférable de riposter avec un bloc ou un défi. Si Gambler avait remporté les 5 matchs perdus comme celui-ci, il aurait pris la première place.