Commits

Alexander Schremmer  committed 1c91b6f

Many changes, implemented tournament etc:
* Prize cards activated
* Tournament implemented
* Moved embargo markers to game-local state
* Added render_piles hook

  • Participants
  • Parent commits 7a58e69

Comments (0)

Files changed (8)

File domination/cards/__init__.py

 
 
 class PrizeCard(Card):
-    optional = True
+    optional = False
     abstract = True
     classname = _("Prize card")
 

File domination/cards/cornucopia.py

 from domination.cards import TreasureCard, VictoryCard, CurseCard, ActionCard, \
-     AttackCard, ReactionCard, PrizeCard, CardSet, Cornucopia
-from domination.cards.base import Curse
+     AttackCard, ReactionCard, PrizeCard, CardSet, Cornucopia, CardTypeRegistry
+from domination.cards.base import Curse, Duchy, Province
 from domination.gameengine import InfoRequest, SelectCard, SelectHandCards, \
      MultipleChoice, Question, YesNoQuestion, Defended, SelectActionCard
 from domination.tools import _
 class BagOfGold(ActionCard, PrizeCard):
     name = _("Bag of Gold")
     edition = Cornucopia
-    implemented = False #This card IS implemented, but prizecard functionality is not. disabled.
     cost = 0
     desc = _("+1 Action. Claim a gold, putting it on top of your deck.")
 
 class Diadem(TreasureCard, PrizeCard):
     name = _("Diadem")
     edition = Cornucopia
-    implemented = False #This card IS implemented, but prizecard functionality is not. disabled.
     cost = 0
     worth = 2
     desc = _("When you play this, +1 Money per unused Action you have.")
 class Followers(AttackCard, PrizeCard):
     name = _("Followers")
     edition = Cornucopia
-    implemented = False #This card IS implemented, but prizecard functionality is not. disabled.
     cost = 0
     desc = _("+2 Cards. Gain an Estate. Each other player gains a Curse and discards down to 3 Cards in hand.")
 
 class Tournament(ActionCard):
     name = _("Tournament")
     edition = Cornucopia
-    implemented = False #FIXME not implemented completely
     cost = 4
     desc = _("+1 Action. Each player may reveal a Province from his hand. If you do, discard it and gain a Prize (from the Prize pile) or a Duchy, putting it on top of your deck. If no-one else does, +1 Card, +1 Money.")
 
     def activate_action(self, game, player):
         player.remaining_actions += 1
+        others_revealed = False
+        player_revealed = False
+        for other_player in game.all_players(player):
+            province_cards = [c for c in other_player.hand if isinstance(c, Province)]
+            if province_cards:
+                card = province_cards[0]
+                reply = (yield YesNoQuestion(game, other_player,
+                    _("Do you want to reveal a Province card from your hand?")))
+                if reply:
+                    if other_player is player:
+                        player_revealed = True
+                        card.discard(player)
+                        card_cls = (yield SelectCard(game, player, _("Which prize card do you want to gain?"),
+                            [type(c) for c in game.tournament_cards] + [Duchy]))
+                        card = [c for c in game.tournament_cards if isinstance(c, card_cls)][0]
+                        player.deck.append(card)
+                        game.tournament_cards.remove(card)
+                    else:
+                        others_revealed = True
+                    for info_player in game.following_participants(other_player):
+                        yield InfoRequest(game, info_player, _("%s reveals a card:", (other_player.name, )), [card])
+        if not others_revealed:
+            player.virtual_money += 1
+            player.draw_cards(1)
+
+    @classmethod
+    def on_setup_card(self, game):
+        game.tournament_cards = [c() for c in CardTypeRegistry.raw_card_classes.values() if issubclass(c, PrizeCard)]
+
+    @classmethod
+    def on_render_piles(self, game, player):
+        yield (_('Available prize cards'), True, game.tournament_cards)
+
 
 class TrustySteed(ActionCard, PrizeCard):
     name = _("Trusty Steed")
     edition = Cornucopia
-    implemented = False #This card IS implemented, but prizecard functionality is not. disabled.
+    implemented = False # XXX comment block/notification
     cost = 0
-    desc = _("Choose two: +2 Cards, +2 Actions, +2 Money, gain 4 Silvers and put your deck into the discard pile (the choices must be different.)") # Wähle zwei verschiedene: +2 Karten, +2 Aktionen, +2 Geld, nimm dir 4 Silber und lege sofort deinen kompletten Nachziehstapel ab.
-    # german and english version have different semantic, which should we follow?
+    desc = _("Choose two: +2 Cards, +2 Actions, +2 Money, gain 4 Silvers and put your deck into the discard pile (the choices must be different.)")
 
     def activate_action(self, game, player):
         actions = [("cards", _("+2 Cards")),
                    ("actions", _("+2 Actions")),
                    ("money", _("+2 Money")),
-                   ("silverdiscard", _("gain 4 Silvers and discard Hand"))]
+                   ("silverdiscard", _("Gain 4 Silvers and discard Hand"))]
 
         while True:
             answers = yield MultipleChoice(game, player, _("What do you want to do?"), actions, min_amount=2, max_amount=2)

File domination/cards/seaside.py

     cost = 2
     desc = _("+2 Money. Trash this card. Put an Embargo token on top of a Supply pile. When a player buys a card, he gains a Curse card per Embargo token on that pile.")
 
-    embargo_markers = {}
+    @classmethod
+    def on_setup_card(self, game):
+        game.embargo_markers = {}
 
     def activate_action(self, game, player):
         player.virtual_money += 2
         for info_player in game.following_participants(player):
             yield InfoRequest(game, info_player,
                     _("%s puts an Embargo token on top of:", (player.name, )), [card_cls])
-        Embargo.embargo_markers[card_cls.__name__] = Embargo.embargo_markers.get(card_cls.__name__, 0) + 1
-    
+        game.embargo_markers[card_cls.__name__] = game.embargo_markers.get(card_cls.__name__, 0) + 1
+
     @classmethod
     def on_buy_card(cls, game, player, card):
-        for i in xrange(Embargo.embargo_markers.get(card.__name__, 0)):
+        for i in xrange(game.embargo_markers.get(card.__name__, 0)):
             with fetch_card_from_supply(game, Curse) as new_card:
                 player.discard_pile.append(new_card)
                 for info_player in game.participants:
 
     @classmethod
     def on_render_card_info(cls, game, card):
-        yield (_("Embargo tokens"), Embargo.embargo_markers.get(card.__name__, 0))
+        yield (_("Embargo tokens"), game.embargo_markers.get(card.__name__, 0))
 
 
 class Lighthouse(ActionCard, DurationCard):

File domination/gameengine.py

 
 class Game(object):
     HOOKS = ["on_pre_buy_card", "on_end_of_game", "on_start_of_turn", "on_end_of_turn", "on_buy_card", "on_render_card_info",
-             "on_gain_card"]
+            "on_gain_card", "on_setup_card", "on_render_piles"]
 
     def __init__(self, name, selected_cards):
         from domination.cards import CardTypeRegistry
     def play_game(self, starting_from_checkpoint):
         if not starting_from_checkpoint:
             self.deal_cards()
+            gen = self.fire_hook("on_setup_card", self)
+            generator_forward(gen)
             for player in self.players:
                 player.prepare_hand(self.cards_to_draw)
         while True:
                 if not cards]
         return len(empty_batches)
 
+    def get_additional_piles(self, player):
+        return list(self.fire_hook("on_render_piles", self, player))
+
+
 from domination.cards import Alchemy
 from domination.cards import Prosperity
 

File domination/main.py

     if os.path.exists(path):
         return url_for('static', filename="cardimages/%s/%s.jpg" % (locale, cardcls.__name__))
 app.template_context_processors[None].append(lambda: {'app': app, 'store': get_store()})
-app.jinja_env.globals.update(gettext=_, ngettext=ngettext, make_image_url=make_image_url)
+app.jinja_env.globals.update(gettext=_, ngettext=ngettext, make_image_url=make_image_url, enumerate=enumerate)
 def finalizer(x):
     if isinstance(x, Markup):
         return x

File domination/static/style.css

 #players { float: left; }
 #infosep { clear: both; }
 #supply h3 { cursor: pointer; }
-#supplycards, #discardpilecards { display: none; }
+#supplycards { display: none; }
+.hiddenpile { display: none; }
 
 .card { display: inline-block; width: 9em; padding: 0.5em; margin: 0.5em; }
 .card h4 { margin-top: 0px; margin-bottom: 0.8em; }

File domination/templates/game.html

       <h3>{% trans %}Your discard pile{% endtrans %}</h3>
       {{ _('%i cards', player.discard_pile | count) }}
       <form><button type="button" onclick="show_pile('#discardpilecards', '{% trans %}Discard pile{% endtrans %}');">{% trans %}Show{% endtrans %}</button></form>
-      <div id="discardpilecards">
+      <div id="discardpilecards" class="hiddenpile">
         {% for card in player.discard_pile %}
           {% call macros.render_card(card, game, player) %}
           {% endcall %}
         {% endfor %}
       </div>
+      {% for i, (name, open, cards) in enumerate(game.get_additional_piles(player)) %}
+      <h3>{{ name }}</h3>
+      {{ _('%i cards', cards | count) }}
+      {% if open %}
+      <form><button type="button" onclick="show_pile('#additionalpile-{{ i }}', '{{ name }}');">{% trans %}Show{% endtrans %}</button></form>
+      <div id="additionalpile-{{ i }}" class="hiddenpile">
+        {% for card in cards %}
+          {% call macros.render_card(card, game, player) %}
+          {% endcall %}
+        {% endfor %}
+      </div>
+      {% endif %}
+      {% endfor %}
     </div>
   {% endif %}
   <div id="infosep"></div>

File domination/tests/test_gameengine.py

 
         for _ in xrange(2**8):
             yield self.do_test_run, sample_hinterlands()
+
+    def test_cornucopia(self):
+        def sample():
+            return random.sample(CardTypeRegistry.cards_from_edition(Cornucopia), 10)
+
+        for _ in xrange(2**8):
+            yield self.do_test_run, sample()