bastard merge
authorDavid Sharpe <decoydavid@gmail.com>
Sat, 17 May 2014 12:50:42 +0000 (14:50 +0200)
committerDavid Sharpe <decoydavid@gmail.com>
Sat, 17 May 2014 12:50:42 +0000 (14:50 +0200)
1  2 
naja/gameboard.py

index ed8d74f4657974079b3978ece51edbb0a30b3499,79e565e9a67bbbd380ef6e7f8cc41d6475fbfbe3..ad692e716e8ee414371c72152f04ea0672233403
@@@ -117,11 -108,10 +117,12 @@@ class GameBoard(object)
      @classmethod
      def generate_random_board(cls, deck):
          board_locations = []
 +        replacement_params = deck.get('replacement_params', None)
          for x in range(5):
              for y in range(5):
 -                board_location = LocationCard.new_location(new_choice.copy())
+                 new_choice = cls.choose_card(deck['cards'], board_locations)
-                     choice(deck['cards']).copy(), replacement_params)
 +                board_location = LocationCard.new_location(
++                    new_choice.copy(), replacement_params)
                  board_locations.append([(x, y), board_location.export()])
          return board_locations
  
              self.replace_card(position)
  
      def replace_card(self, position):
-         location = LocationCard.new_location(choice(self.locations).copy(),
+         new_choice = self.choose_card(self.locations,
+                                       self.board_locations.items(),
+                                       position)
 -        location = LocationCard.new_location(new_choice.copy())
++        location = LocationCard.new_location(new_choice.copy(),
 +                                             self.replacement_params)
          self.board_locations[position] = location
  
+     @classmethod
+     def choose_card(cls, cards, board_locations, position=None):
+         # Find which cards are at their maximum and exclude them from
+         # the choice list
+         counts = {}
+         choices = {card['card_name']: card for card in cards}
+         for pos, card in board_locations:
+             if pos == position:
+                 # skip the card we're replacing if appropriate
+                 continue
+             if isinstance(card, LocationCard):
+                 key = card.card_name
+                 max_num = card.max_number
+             else:
+                 key = card['card_name']
+                 max_num = card.get('max_number', 25)
+             counts.setdefault(key, 0)
+             counts[key] += 1
+             if counts[key] >= max_num:
+                 if key in choices:
+                     del choices[key]
+         return choice(choices.values())
      def shift_location_row(self, change, is_vertical):
          px, py = self.player.position
          shifted_locations = {}
@@@ -240,19 -248,19 +267,21 @@@ class LocationCard(object)
      """
  
      def __init__(self, card_name, bitwise_operand, location_actions,
-                  replacement_time):
 -                 max_number=25):
++                 replacement_time, max_number=25):
          self.card_name = card_name
          self.bitwise_operand = bitwise_operand
          self.actions = location_actions
+         self.max_number = max_number
          self.check_actions()
 +        self.replacement_time = replacement_time
  
      @classmethod
      def import_location(cls, state):
          location_actions = [
              cls.build_action(definition) for definition in state['actions']]
          return cls(state['card_name'], state['bitwise_operand'],
-                    location_actions, state['replacement_time'])
 -                   location_actions, state['max_number'])
++                   location_actions, state['replacement_time'],
++                   state['max_number'])
  
      @classmethod
      def build_action(cls, definition):
              bits = cls.parse_bits(definition['bits'])
          else:
              bits = cls.generate_bitwise_operand()
 +
 +        if 'replacement_time' in definition:
 +            replacement_time = definition['replacement_time']
 +        else:
 +            replacement_time = cls.generate_replacement_time(
 +                replacement_params)
 +
+         max_number = definition.get('max_number', 25)
          card_name = definition['card_name']
          return cls.import_location({
              'bitwise_operand': bits,
              'actions': definition['actions'],
+             'max_number': max_number,
              'card_name': card_name,
 +            'replacement_time': replacement_time,
          })
  
      @classmethod
          return {
              'bitwise_operand': sorted(self.bitwise_operand),
              'actions': [action.export() for action in self.actions],
+             'max_number': self.max_number,
              'card_name': self.card_name,
 +            'replacement_time': self.replacement_time,
          }
  
      def check_actions(self):