def card(self, s): """Gets the card with name like 'shrine2'. Invalid name formats are an AttributeError. """ match = re.match('(.*?)([0-9]*)$', s) if match is None: raise AttributeError('Invalid card pull: ' + s) else: groups = match.groups() if len(groups) != 2: raise AttributeError('Invalid card pull: ' +s) else: try: index = int(match.group(2)) except ValueError: index = None name = match.group(1) if 'ludus' in name.lower(): name = 'Ludus Magna' elif 'maximus' in name.lower(): name = 'Circus Maximus' else: name = name[0].upper() + name[1:].lower() try: pulls = self._anon_pulls[name] except KeyError: pulls = 0 n_tot = int(cm.get_card_dict(name)['card_count']) if name.lower() == 'jack': n_tot = 6 max_index = n_tot - pulls - 1 if index is None: self._anon_pulls[name] = pulls+1 # Get anonymous cards starting from the highest index return cm.get_card(name, max_index) else: return cm.get_card(name, index)
def card(self, s): """Gets the card with name like 'shrine2'. Invalid name formats are an AttributeError. """ match = re.match('(.*?)([0-9]*)$', s) if match is None: raise AttributeError('Invalid card pull: ' + s) else: groups = match.groups() if len(groups) != 2: raise AttributeError('Invalid card pull: ' + s) else: try: index = int(match.group(2)) except ValueError: index = None name = match.group(1) if 'ludus' in name.lower(): name = 'Ludus Magna' elif 'maximus' in name.lower(): name = 'Circus Maximus' else: name = name[0].upper() + name[1:].lower() try: pulls = self._anon_pulls[name] except KeyError: pulls = 0 n_tot = int(cm.get_card_dict(name)['card_count']) if name.lower() == 'jack': n_tot = 6 max_index = n_tot - pulls - 1 if index is None: self._anon_pulls[name] = pulls + 1 # Get anonymous cards starting from the highest index return cm.get_card(name, max_index) else: return cm.get_card(name, index)
def test_add_to_nonempty_building(self): """ Add a valid material to a building with one material, but this does not complete it. """ statue = cm.get_card('Statue') temple = cm.get_card('Temple') stairway = cm.get_card('Stairway') self.p1.stockpile.set_content([statue]) self.p1.buildings = [Building(temple, 'Marble', materials=[stairway])] a = message.GameAction(message.ARCHITECT, temple, statue, None) self.game.handle(a) self.assertNotIn(statue, self.p1.stockpile) self.assertEqual(self.p1.buildings[0], Building(temple, 'Marble', materials=[stairway, statue])) self.assertFalse(self.game._player_has_active_building(self.p1, 'Temple'))
def test_add_to_empty_building(self): """ Add a valid material to a building with no materials. """ atrium = cm.get_card('Atrium') foundry = cm.get_card('Foundry') self.p1.stockpile.set_content([atrium]) self.p1.buildings = [Building(foundry, 'Brick')] a = message.GameAction(message.ARCHITECT, foundry, atrium, None) self.game.handle(a) self.assertNotIn('Atrium', self.p1.stockpile) self.assertEqual(self.p1.buildings[0].materials, Building(foundry, 'Brick', materials=[atrium]).materials) self.assertEqual(self.p1.buildings[0], Building(foundry, 'Brick', materials=[atrium])) self.assertFalse(self.game._player_has_active_building(self.p1, 'Foundry'))
def test_patron_one_from_pool(self): """ Take one card from the pool with patron action. """ atrium = cm.get_card('Atrium') self.game.pool.set_content([atrium]) a = message.GameAction(message.PATRONFROMPOOL, atrium) self.game.handle(a) self.assertNotIn('Atrium', self.game.pool) self.assertIn('Atrium', self.p1.clientele)
def test_add_to_nonempty_building(self): """ Add a valid material to a building with one material, but this does not complete it. """ statue = cm.get_card('Statue') temple = cm.get_card('Temple') stairway = cm.get_card('Stairway') self.p1.stockpile.set_content([statue]) self.p1.buildings = [Building(temple, 'Marble', materials=[stairway])] a = message.GameAction(message.ARCHITECT, temple, statue, None) self.game.handle(a) self.assertNotIn(statue, self.p1.stockpile) self.assertEqual( self.p1.buildings[0], Building(temple, 'Marble', materials=[stairway, statue])) self.assertFalse( self.game._player_has_active_building(self.p1, 'Temple'))
def test_add_to_empty_building(self): """ Add a valid material to a building with no materials. """ atrium = cm.get_card('Atrium') foundry = cm.get_card('Foundry') self.p1.stockpile.set_content([atrium]) self.p1.buildings = [Building(foundry, 'Brick')] a = message.GameAction(message.ARCHITECT, foundry, atrium, None) self.game.handle(a) self.assertNotIn('Atrium', self.p1.stockpile) self.assertEqual( self.p1.buildings[0].materials, Building(foundry, 'Brick', materials=[atrium]).materials) self.assertEqual(self.p1.buildings[0], Building(foundry, 'Brick', materials=[atrium])) self.assertFalse( self.game._player_has_active_building(self.p1, 'Foundry'))
def test_follow_role_with_jack(self): """ Follow Laborer with a Jack. """ jack = cm.get_card('Jack') self.p2.hand.set_content([jack]) a = message.GameAction(message.FOLLOWROLE, 1, jack) self.game.handle(a) self.assertEqual(self.game.expected_action, message.LABORER) self.assertIn(jack, self.p2.camp) self.assertNotIn(jack, self.p2.hand) self.assertEqual(self.p2.n_camp_actions, 1)
def test_handle_lead_role_with_orders(self): """ Leading a role sets GameState.role_led, camp actions. """ latrine = cm.get_card('Latrine') self.p1.hand.set_content([latrine]) a = message.GameAction(message.LEADROLE, 'Laborer', 1, latrine) self.game.handle(a) self.assertEqual(self.game.role_led, 'Laborer') self.assertEqual(self.p1.n_camp_actions, 1) self.assertIn(latrine, self.p1.camp) self.assertNotIn(latrine, self.p1.hand) self.assertEqual(self.game.expected_action, message.FOLLOWROLE)
def test_start_in_town(self): """ Start an in-town building. """ latrine = cm.get_card('Latrine') self.p1.hand.set_content([latrine]) a = message.GameAction(message.ARCHITECT, latrine, None, 'Rubble') self.game.handle(a) self.assertNotIn(latrine, self.p1.hand) self.assertEqual(self.p1.buildings[0], Building(latrine, 'Rubble')) self.assertFalse(self.game._player_has_active_building(self.p1, 'Latrine'))
def test_follow_role_with_nonexistent_card(self): """Follow Laborer specifying a non-existent card. This bad action should not change anything about the game state. """ latrine = cm.get_card('Latrine') self.p2.hand.set_content([]) a = message.GameAction(message.FOLLOWROLE, 1, latrine) # Monitor the gamestate for any changes mon = Monitor() mon.modified(self.game) self.assertFalse(mon.modified(self.game))
def test_handle_lead_latrine_with_jack(self): """ Leading a role sets GameState.role_led, camp actions. """ jack = cm.get_card('Jack') self.p1.hand.set_content([jack]) a = message.GameAction(message.LEADROLE, 'Laborer', 1, jack) self.game.handle(a) self.assertEqual(self.game.role_led, 'Laborer') self.assertEqual(self.p1.n_camp_actions, 1) self.assertIn(jack, self.p1.camp) self.assertNotIn(jack, self.p1.hand) self.assertEqual(self.game.expected_action, message.FOLLOWROLE)
def test_start_in_town(self): """ Start an in-town building. """ latrine = cm.get_card('Latrine') self.p1.hand.set_content([latrine]) a = message.GameAction(message.CRAFTSMAN, latrine, None, 'Rubble') self.game.handle(a) self.assertNotIn(latrine, self.p1.hand) self.assertEqual(self.p1.buildings[0], Building(latrine, 'Rubble')) self.assertFalse( self.game._player_has_active_building(self.p1, 'Latrine'))
def test_wrong_site(self): """ Use the wrong site to start a building. This invalid game action should leave the game state unchanged. """ atrium = cm.get_card('Atrium') self.p1.hand.set_content([atrium]) mon = Monitor() mon.modified(self.game) a = message.GameAction(message.CRAFTSMAN, atrium, None, 'Rubble') with self.assertRaises(GTRError): self.game.handle(a) self.assertFalse(mon.modified(self.game))
def test_illegal_out_of_town(self): """ Start a building and add a material. """ bridge = cm.get_card('Bridge') self.p1.hand.set_content([bridge]) # Empty the in-town sites of Concrete self.game.in_town_sites = ['Rubble'] mon = Monitor() mon.modified(self.game) a = message.GameAction(message.ARCHITECT, bridge, None, 'Concrete') with self.assertRaises(GTRError): self.game.handle(a) self.assertFalse(mon.modified(self.game))
def test_illegal_out_of_town(self): """Try to start a building out of town without two actions. This invalid game action should leave the game state unchanged. """ atrium = cm.get_card('Atrium') self.p1.hand.set_content([atrium]) self.game.in_town_sites = ['Rubble'] mon = Monitor() mon.modified(self.game) a = message.GameAction(message.CRAFTSMAN, atrium, None, 'Brick') with self.assertRaises(GTRError): self.game.handle(a) self.assertFalse(mon.modified(self.game))
def test_follow_role_with_card_of_different_role(self): """ Follow Laborer specifying a card of the wrong role. This bad action should not change anything about the game state. """ atrium = cm.get_card('Atrium') self.p2.hand.set_content([atrium]) a = message.GameAction(message.FOLLOWROLE, 1, atrium) # Monitor the gamestate for any changes mon = Monitor() mon.modified(self.game) with self.assertRaises(GTRError): self.game.handle(a) self.assertFalse(mon.modified(self.game))
def test_fountain_skip(self): """Test using a fountain to look at the top card and then skip the action, drawing the card. """ bath = cm.get_card('Bath') self.game.library.cards.insert(0, bath) a = message.GameAction(message.USEFOUNTAIN, True) self.game.handle(a) self.assertEqual(self.p1.fountain_card, bath) self.assertEqual(self.game.expected_action, message.FOUNTAIN) a = message.GameAction(message.FOUNTAIN, None, None, None) self.game.handle(a) self.assertIn(bath, self.p1.hand) self.assertIsNone(self.p1.fountain_card) self.assertEqual(self.game.expected_action, message.THINKERORLEAD)
def test_fountain_skip(self): """Test using a fountain to look at the top card and then skip the action, drawing the card. """ bath = cm.get_card('Bath') self.game.library.cards.insert(0,bath) a = message.GameAction(message.USEFOUNTAIN, True) self.game.handle(a) self.assertEqual(self.p1.fountain_card, bath) self.assertEqual(self.game.expected_action, message.FOUNTAIN) a = message.GameAction(message.FOUNTAIN, None, None, None) self.game.handle(a) self.assertIn(bath, self.p1.hand) self.assertIsNone(self.p1.fountain_card) self.assertEqual(self.game.expected_action, message.THINKERORLEAD)
def test_add_two_materials(self): """ Add materials with subsequent architect actions. """ wall, storeroom = cm.get_cards(['Wall', 'Storeroom']) tower = cm.get_card('Tower') self.p1.stockpile.set_content([wall, storeroom]) self.p1.buildings = [Building(tower, 'Concrete')] a = message.GameAction(message.ARCHITECT, tower, wall, None) self.game.handle(a) self.assertEqual(self.p1.buildings[0], Building(tower, 'Concrete', materials=[wall])) a = message.GameAction(message.ARCHITECT, tower, storeroom, None) self.game.handle(a) self.assertEqual(self.p1.buildings[0], Building(tower, 'Concrete', materials=[wall, storeroom], complete=True))
def test_start_out_of_town(self): """ Start a building out of town. """ bridge = cm.get_card('Bridge') self.p1.hand.set_content([bridge]) # Empty the in-town sites self.game.in_town_sites = ['Rubble'] self.game.oot_allowed = True a = message.GameAction(message.ARCHITECT, bridge, None, 'Concrete') self.game.handle(a) self.assertEqual(self.p1.buildings[0], Building(bridge, 'Concrete')) self.assertEqual(3, self.game.out_of_town_sites.count('Concrete')) self.assertNotIn(bridge, self.p1.hand) self.assertEqual(self.game.expected_action, message.ARCHITECT) self.assertEqual(self.game.active_player, self.p2)
def test_add_two_materials(self): """ Add materials with subsequent architect actions. """ wall, storeroom = cm.get_cards(['Wall', 'Storeroom']) tower = cm.get_card('Tower') self.p1.stockpile.set_content([wall, storeroom]) self.p1.buildings = [Building(tower, 'Concrete')] a = message.GameAction(message.ARCHITECT, tower, wall, None) self.game.handle(a) self.assertEqual(self.p1.buildings[0], Building(tower, 'Concrete', materials=[wall])) a = message.GameAction(message.ARCHITECT, tower, storeroom, None) self.game.handle(a) self.assertEqual( self.p1.buildings[0], Building(tower, 'Concrete', materials=[wall, storeroom], complete=True))
def test_fountain_start(self): """Test using a fountain to look at the top card and then start a building with it. """ bath = cm.get_card('Bath') self.game.library.cards.insert(0,bath) a = message.GameAction(message.USEFOUNTAIN, True) self.game.handle(a) self.assertEqual(self.p1.fountain_card, bath) self.assertEqual(self.game.expected_action, message.FOUNTAIN) a = message.GameAction(message.FOUNTAIN, bath, None, 'Brick') self.game.handle(a) self.assertNotIn(bath, self.p1.hand) self.assertIsNone(self.p1.fountain_card) self.assertIn('Bath', self.p1.building_names) self.assertFalse(self.game._player_has_active_building(self.p1, 'Bath')) self.assertEqual(self.game.expected_action, message.THINKERORLEAD)
def test_fountain_start(self): """Test using a fountain to look at the top card and then start a building with it. """ bath = cm.get_card('Bath') self.game.library.cards.insert(0, bath) a = message.GameAction(message.USEFOUNTAIN, True) self.game.handle(a) self.assertEqual(self.p1.fountain_card, bath) self.assertEqual(self.game.expected_action, message.FOUNTAIN) a = message.GameAction(message.FOUNTAIN, bath, None, 'Brick') self.game.handle(a) self.assertNotIn(bath, self.p1.hand) self.assertIsNone(self.p1.fountain_card) self.assertIn('Bath', self.p1.building_names) self.assertFalse(self.game._player_has_active_building( self.p1, 'Bath')) self.assertEqual(self.game.expected_action, message.THINKERORLEAD)