Esempio n. 1
0
    def test_swapping_with_unintended_intent(self):
        """
        The intent is questionable.


        England:
        A Liverpool - Edinburgh
        F English Channel Convoys A Liverpool - Edinburgh

        Germany:
        A Edinburgh - Liverpool

        France:
        F Irish Sea Hold
        F North Sea Hold

        Russia:
        F Norwegian Sea Convoys A Liverpool - Edinburgh
        F North Atlantic Ocean Convoys A Liverpool - Edinburgh
        See issue 4.A.3.

        For choice a, b and c the English army in Liverpool will move by convoy
        and consequentially the two armies are swapped.

        For choice d, the 1982/2000 rulebook (which I prefer), the convoy
        depends on the "intent". England intended to convoy via the French
        fleets in the Irish Sea and the North Sea. However, the French did not
        order the convoy. The alternative route with the Russian fleets was
        unintended. The English fleet in the English Channel (with the convoy
        order) is not part of this alternative route with the Russian fleets.
        Since England still "intent" to convoy, the move from Liverpool to
        Edinburgh should be via convoy and the two armies are swapped.
        Although, you could argue that this is not really according to the
        clarification of the 2000 rulebook.

        When explicit adjacent convoying is used (DPTG, choice e), then the
        English army did not receive an order to move by convoy. So, it is just
        a head to head battle and both the army in Edinburgh and Liverpool will
        not move.
        """
        Army(self.state, 0, Nations.ENGLAND, self.territories.LIVERPOOL),
        Fleet(self.state, 0, Nations.ENGLAND, self.territories.ENGLISH_CHANNEL),
        Army(self.state, 0, Nations.GERMANY, self.territories.EDINBURGH),
        Fleet(self.state, 0, Nations.FRANCE, self.territories.IRISH_SEA),
        Fleet(self.state, 0, Nations.FRANCE, self.territories.NORTH_SEA),
        Fleet(self.state, 0, Nations.RUSSIA, self.territories.NORWEGIAN_SEA),
        Fleet(self.state, 0, Nations.RUSSIA, self.territories.NORTH_ATLANTIC),
        orders = [
            Move(self.state, 0, Nations.ENGLAND, self.territories.LIVERPOOL, self.territories.EDINBURGH),
            Convoy(self.state, 0, Nations.ENGLAND, self.territories.ENGLISH_CHANNEL, self.territories.LIVERPOOL, self.territories.EDINBURGH),
            Move(self.state, 0, Nations.GERMANY, self.territories.EDINBURGH, self.territories.LIVERPOOL),
            Hold(self.state, 0, Nations.FRANCE, self.territories.IRISH_SEA),
            Hold(self.state, 0, Nations.FRANCE, self.territories.NORTH_SEA),
            Convoy(self.state, 0, Nations.RUSSIA, self.territories.NORWEGIAN_SEA, self.territories.LIVERPOOL, self.territories.EDINBURGH),
            Convoy(self.state, 0, Nations.RUSSIA, self.territories.NORTH_ATLANTIC, self.territories.LIVERPOOL, self.territories.EDINBURGH),
        ]
        process(self.state)

        self.assertEqual(orders[0].outcome, Outcomes.FAILS)
        self.assertEqual(orders[2].outcome, Outcomes.FAILS)
Esempio n. 2
0
    def test_piece(self):

        london = CoastalTerritory(self.state, 1, 'London', 'England', [], [])
        wales = CoastalTerritory(self.state, 2, 'Wales', 'England', [], [])

        army = Army(self.state, 0, 'England', london)
        london_hold = Hold(self.state, 0, 'England', london)
        wales_hold = Hold(self.state, 0, 'England', wales)

        self.assertEqual(london_hold.piece, army)
        self.assertIsNone(wales_hold.piece)
Esempio n. 3
0
    def test_piece(self):
        state = State()

        london = CoastalTerritory(1, 'London', 'England', [], [])
        wales = CoastalTerritory(2, 'Wales', 'England', [], [])

        army = Army('England', london)
        london_hold = Hold('England', london)
        wales_hold = Hold('England', wales)

        to_register = [london, wales, army, london_hold, wales_hold]
        [state.register(o) for o in to_register]

        self.assertEqual(london_hold.piece, army)
        self.assertIsNone(wales_hold.piece)
Esempio n. 4
0
    def test_support_from_unreachable_coast_not_allowed(self):
        """
        A fleet can not give support to an area that can not be reached from
        the current coast of the fleet.

        France:
        F Marseilles - Gulf of Lyon
        F Spain(nc) Supports F Marseilles - Gulf of Lyon

        Italy:
        F Gulf of Lyon Hold

        The Gulf of Lyon can not be reached from the North Coast of Spain.
        Therefore, the support of Spain is invalid and the fleet in the Gulf of
        Lyon is not dislodged.
        """
        pieces = [
            Fleet(Nations.FRANCE, self.territories.MARSEILLES),
            Fleet(Nations.FRANCE, self.territories.SPAIN, self.named_coasts.SPAIN_NC),
            Fleet(Nations.ITALY, self.territories.GULF_OF_LYON)
        ]

        fleet_marseilles_move = Move(Nations.FRANCE, self.territories.MARSEILLES, self.territories.GULF_OF_LYON)
        fleet_spain_nc_support = Support(Nations.FRANCE, self.territories.SPAIN, self.territories.MARSEILLES, self.territories.GULF_OF_LYON)
        fleet_gol_hold = Hold(Nations.ITALY, self.territories.GULF_OF_LYON)

        self.state.register(*pieces, fleet_marseilles_move, fleet_spain_nc_support, fleet_gol_hold)
        self.state.post_register_updates()
        process(self.state)

        self.assertEqual(fleet_spain_nc_support.legal_decision, Outcomes.ILLEGAL)
        self.assertEqual(fleet_spain_nc_support.illegal_message, illegal_messages.S002)
        self.assertEqual(fleet_marseilles_move.move_decision, Outcomes.FAILS)
        self.assertEqual(pieces[2].dislodged_decision, Outcomes.SUSTAINS)
Esempio n. 5
0
    def test_three_way_beleaguered_garrison(self):
        """
        In a beleaguered garrison from three sides, the adjudicator may not let
        two attacks fail and then let the third succeed.

        England:
        F Edinburgh Supports F Yorkshire - North Sea
        F Yorkshire - North Sea

        France:
        F Belgium - North Sea
        F English Channel Supports F Belgium - North Sea

        Germany:
        F North Sea Hold

        Russia:
        F Norwegian Sea - North Sea
        F Norway Supports F Norwegian Sea - North Sea

        None of the fleets move. The German fleet in the North Sea is not
        dislodged.
        """
        pieces = [
            Fleet(self.state, 0, Nations.ENGLAND, self.territories.EDINBURGH),
            Fleet(self.state, 0, Nations.ENGLAND, self.territories.YORKSHIRE),
            Fleet(self.state, 0, Nations.FRANCE, self.territories.BELGIUM),
            Fleet(self.state, 0, Nations.FRANCE,
                  self.territories.ENGLISH_CHANNEL),
            Fleet(self.state, 0, Nations.GERMANY, self.territories.NORTH_SEA),
            Fleet(self.state, 0, Nations.RUSSIA,
                  self.territories.NORWEGIAN_SEA),
            Fleet(self.state, 0, Nations.RUSSIA, self.territories.NORWAY),
        ]
        orders = [
            Support(self.state, 0, Nations.ENGLAND, self.territories.EDINBURGH,
                    self.territories.YORKSHIRE, self.territories.NORTH_SEA),
            Move(self.state, 0, Nations.ENGLAND, self.territories.YORKSHIRE,
                 self.territories.NORTH_SEA),
            Move(self.state, 0, Nations.FRANCE, self.territories.BELGIUM,
                 self.territories.NORTH_SEA),
            Support(self.state, 0, Nations.FRANCE,
                    self.territories.ENGLISH_CHANNEL, self.territories.BELGIUM,
                    self.territories.NORTH_SEA),
            Hold(self.state, 0, Nations.GERMANY, self.territories.NORTH_SEA),
            Move(self.state, 0, Nations.RUSSIA, self.territories.NORWEGIAN_SEA,
                 self.territories.NORTH_SEA),
            Support(self.state, 0, Nations.RUSSIA, self.territories.NORWAY,
                    self.territories.NORWEGIAN_SEA,
                    self.territories.NORTH_SEA),
        ]
        process(self.state)

        self.assertEqual(pieces[4].dislodged_decision, Outcomes.SUSTAINS)
        self.assertEqual(orders[0].outcome, Outcomes.SUCCEEDS)
        self.assertEqual(orders[1].outcome, Outcomes.FAILS)
        self.assertEqual(orders[2].outcome, Outcomes.FAILS)
        self.assertEqual(orders[3].outcome, Outcomes.SUCCEEDS)
        self.assertEqual(orders[5].outcome, Outcomes.FAILS)
        self.assertEqual(orders[6].outcome, Outcomes.SUCCEEDS)
Esempio n. 6
0
    def test_support_on_unreachable_destination_not_possible(self):
        """
        The destination of the move that is supported must be reachable by the
        supporting unit.

        Austria:
        A Venice Hold

        Italy:
        F Rome Supports A Apulia - Venice
        A Apulia - Venice

        The support of Rome is illegal, because Venice can not be reached from
        Rome by a fleet. Venice is not dislodged.
        """
        Army(self.state, 0, Nations.AUSTRIA, self.territories.VENICE),
        Fleet(self.state, 0, Nations.ITALY, self.territories.ROME),
        Army(self.state, 0, Nations.ITALY, self.territories.APULIA)

        # TODO finish
        Hold(self.state, 0, Nations.AUSTRIA, self.territories.VENICE)
        fleet_rome_support = Support(self.state, 0, Nations.ITALY, self.territories.ROME, self.territories.APULIA, self.territories.VENICE)
        Move(self.state, 0, Nations.ITALY, self.territories.APULIA, self.territories.VENICE)

        process(self.state)

        self.assertTrue(fleet_rome_support.illegal)
        self.assertEqual(fleet_rome_support.illegal_code, '010')
        self.assertEqual(
            fleet_rome_support.illegal_verbose,
            'Piece cannot reach that territory.'
        )
Esempio n. 7
0
 def test_serialize_state_order(self):
     london = CoastalTerritory(self.state, 1, 'London', 1, [2], [])
     Hold(self.state, 1, 1, london)
     data = TurnSchema().dump(self.state)
     order_data = (dict(data['orders'][0]))
     self.assertEqual(
         sorted(order_data.keys()),
         ['id', 'illegal', 'illegal_code', 'illegal_verbose', 'outcome']
     )
Esempio n. 8
0
    def test_hold(self):
        london = CoastalTerritory(1, 'London', 'England', [], [])
        Army('England', london)
        london_hold = Hold('England', london)

        self.assertTrue(london_hold.is_hold)
        self.assertFalse(london_hold.is_move)
        with self.assertRaises(AttributeError):
            london_hold.is_fake_class_name
Esempio n. 9
0
    def test_no_self_dislodgement_with_beleauguered_garrison(self):
        """
        An attempt to self dislodge can be combined with a beleaguered
        garrison. Such self dislodgement is still not possible.

        England:
        F North Sea Hold
        F Yorkshire Supports F Norway - North Sea

        Germany:
        F Holland Supports F Helgoland Bight - North Sea
        F Helgoland Bight - North Sea

        Russia:
        F Skagerrak Supports F Norway - North Sea
        F Norway - North Sea

        Although the Russians beat the German attack (with the support of
        Yorkshire) and the two Russian fleets are enough to dislodge the fleet
        in the North Sea, the fleet in the North Sea is not dislodged, since it
        would not be dislodged if the English fleet in Yorkshire would not give
        support. According to the DPTG the fleet in the North Sea would be
        dislodged. The DPTG is incorrect in this case.
        """
        pieces = [
            Fleet(0, Nations.ENGLAND, self.territories.NORTH_SEA),
            Fleet(0, Nations.ENGLAND, self.territories.YORKSHIRE),
            Fleet(0, Nations.GERMANY, self.territories.HOLLAND),
            Fleet(0, Nations.GERMANY, self.territories.HELGOLAND_BIGHT),
            Fleet(0, Nations.RUSSIA, self.territories.SKAGERRAK),
            Fleet(0, Nations.RUSSIA, self.territories.NORWAY),
        ]
        orders = [
            Hold(0, Nations.ENGLAND, self.territories.NORTH_SEA),
            Support(0, Nations.ENGLAND, self.territories.YORKSHIRE,
                    self.territories.NORWAY, self.territories.NORTH_SEA),
            Support(0, Nations.GERMANY, self.territories.HOLLAND,
                    self.territories.HELGOLAND_BIGHT,
                    self.territories.NORTH_SEA),
            Move(0, Nations.GERMANY, self.territories.HELGOLAND_BIGHT,
                 self.territories.NORTH_SEA),
            Support(0, Nations.RUSSIA, self.territories.SKAGERRAK,
                    self.territories.NORWAY, self.territories.NORTH_SEA),
            Move(0, Nations.RUSSIA, self.territories.NORWAY,
                 self.territories.NORTH_SEA),
        ]
        self.state.register(*pieces, *orders)
        self.state.post_register_updates()
        process(self.state)

        self.assertEqual(pieces[0].dislodged_decision, Outcomes.SUSTAINS)
        self.assertEqual(orders[2].outcome, Outcomes.SUCCEEDS)
        self.assertEqual(orders[3].outcome, Outcomes.FAILS)
        self.assertEqual(orders[4].outcome, Outcomes.SUCCEEDS)
        self.assertEqual(orders[5].outcome, Outcomes.FAILS)
Esempio n. 10
0
    def test_support_can_be_cut_with_other_coast(self):
        """
        Support can be cut from the other coast.

        England:
        F Irish Sea Supports F North Atlantic Ocean - Mid-Atlantic Ocean
        F North Atlantic Ocean - Mid-Atlantic Ocean

        France:
        F Spain(nc) Supports F Mid-Atlantic Ocean
        F Mid-Atlantic Ocean Hold

        Italy:
        F Gulf of Lyon - Spain(sc)

        The Italian fleet in the Gulf of Lyon will cut the support in Spain.
        That means that the French fleet in the Mid Atlantic Ocean will be
        dislodged by the English fleet in the North Atlantic Ocean.
        """
        pieces = [
            Fleet(self.state, 0, Nations.ENGLAND,
                  self.territories.NORTH_ATLANTIC),
            Fleet(self.state, 0, Nations.ENGLAND, self.territories.IRISH_SEA),
            Fleet(self.state,
                  0,
                  Nations.FRANCE,
                  self.territories.SPAIN,
                  named_coast=self.named_coasts.SPAIN_NC),
            Fleet(self.state, 0, Nations.FRANCE,
                  self.territories.MID_ATLANTIC),
            Fleet(self.state, 0, Nations.ITALY, self.territories.GULF_OF_LYON),
        ]
        orders = [
            Move(self.state, 0, Nations.ENGLAND,
                 self.territories.NORTH_ATLANTIC,
                 self.territories.MID_ATLANTIC),
            Support(self.state, 0, Nations.ENGLAND, self.territories.IRISH_SEA,
                    self.territories.NORTH_ATLANTIC,
                    self.territories.MID_ATLANTIC),
            Support(self.state, 0, Nations.FRANCE, self.territories.SPAIN,
                    self.territories.MID_ATLANTIC,
                    self.territories.MID_ATLANTIC),
            Hold(self.state, 0, Nations.FRANCE, self.territories.MID_ATLANTIC),
            Move(self.state, 0, Nations.ITALY, self.territories.GULF_OF_LYON,
                 self.territories.SPAIN, self.named_coasts.SPAIN_SC),
        ]

        process(self.state)

        self.assertEqual(orders[0].outcome, Outcomes.SUCCEEDS)
        self.assertEqual(orders[1].outcome, Outcomes.SUCCEEDS)
        self.assertEqual(orders[2].outcome, Outcomes.FAILS)
        self.assertEqual(orders[4].outcome, Outcomes.FAILS)
        self.assertEqual(pieces[3].dislodged_decision, Outcomes.DISLODGED)
Esempio n. 11
0
    def test_register_order_updates_piece_order(self):
        state = State()
        paris = InlandTerritory(1, 'paris', Nations.FRANCE, [])
        army_paris = Army(0, Nations.FRANCE, paris)
        hold = Hold(0, Nations.FRANCE, paris)

        state.register(paris)
        state.register(army_paris)
        state.register(hold)

        self.assertEqual(army_paris.order, hold)
        self.assertEqual(hold.piece, army_paris)
Esempio n. 12
0
    def test_support_from_unreachable_coast_not_allowed(self):
        """
        A fleet can not give support to an area that can not be reached from
        the current coast of the fleet.

        France:
        F Marseilles - Gulf of Lyon
        F Spain(nc) Supports F Marseilles - Gulf of Lyon

        Italy:
        F Gulf of Lyon Hold

        The Gulf of Lyon can not be reached from the North Coast of Spain.
        Therefore, the support of Spain is invalid and the fleet in the Gulf of
        Lyon is not dislodged.
        """
        pieces = [
            Fleet(self.state, 0, Nations.FRANCE, self.territories.MARSEILLES),
            Fleet(self.state,
                  0,
                  Nations.FRANCE,
                  self.territories.SPAIN,
                  named_coast=self.named_coasts.SPAIN_NC),
            Fleet(self.state, 0, Nations.ITALY, self.territories.GULF_OF_LYON)
        ]

        fleet_marseilles_move = Move(self.state, 0, Nations.FRANCE,
                                     self.territories.MARSEILLES,
                                     self.territories.GULF_OF_LYON)
        fleet_spain_nc_support = Support(self.state, 0, Nations.FRANCE,
                                         self.territories.SPAIN,
                                         self.territories.MARSEILLES,
                                         self.territories.GULF_OF_LYON)
        Hold(self.state, 0, Nations.ITALY, self.territories.GULF_OF_LYON)

        process(self.state)

        self.assertTrue(fleet_spain_nc_support.illegal)
        self.assertEqual(fleet_spain_nc_support.illegal_code, '010')
        self.assertEqual(fleet_spain_nc_support.illegal_verbose,
                         'Piece cannot reach that territory.')
        self.assertEqual(fleet_marseilles_move.outcome, Outcomes.FAILS)
        self.assertEqual(pieces[2].dislodged_decision, Outcomes.SUSTAINS)
Esempio n. 13
0
    def test_support_on_unreachable_destination_not_possible(self):
        """
        The destination of the move that is supported must be reachable by the
        supporting unit.

        Austria:
        A Venice Hold

        Italy:
        F Rome Supports A Apulia - Venice
        A Apulia - Venice

        The support of Rome is illegal, because Venice can not be reached from
        Rome by a fleet. Venice is not dislodged.
        """
        pieces = [
            Army(Nations.AUSTRIA, self.territories.VENICE),
            Fleet(Nations.ITALY, self.territories.ROME),
            Army(Nations.ITALY, self.territories.APULIA)
        ]

        # TODO finish
        army_austria_hold = Hold(Nations.AUSTRIA, self.territories.VENICE)
        fleet_rome_support = Support(Nations.ITALY, self.territories.ROME,
                                     self.territories.APULIA,
                                     self.territories.VENICE)
        army_apulia_move = Move(Nations.ITALY, self.territories.APULIA,
                                self.territories.VENICE)

        self.state.register(*pieces, army_austria_hold, fleet_rome_support,
                            army_apulia_move)
        self.state.post_register_updates()
        process(self.state)

        self.assertEqual(fleet_rome_support.legal_decision, Outcomes.ILLEGAL)
        self.assertEqual(fleet_rome_support.illegal_message,
                         illegal_messages.S002)
Esempio n. 14
0
    def test_ordering_a_unit_of_another_country(self):
        """
        Check whether someone can not order a unit that does not belong to
        them.

        England has a fleet in London.

        Germany:
        F London - North Sea

        Order should fail.
        """
        Fleet(self.state, 0, Nations.ENGLAND, self.territories.LONDON)
        order = Move(self.state, 0, Nations.GERMANY, self.territories.LONDON, self.territories.NORTH_SEA)
        Hold(self.state, 0, Nations.ENGLAND, self.territories.LONDON)

        process(self.state)

        self.assertTrue(order.illegal)
        self.assertEqual(order.illegal_code, '001')
        self.assertEqual(
            order.illegal_verbose,
            'Cannot order a piece belonging to another nation.'
        )
Esempio n. 15
0
def data_to_state(data):
    state = State()
    data = data
    # instantiate and register territories
    for territory_data in data['territories']:
        type = territory_data.pop('type')
        territory_class = terrtitory_type_dict[type]
        if not type == 'coastal':
            territory_data.pop('shared_coast_ids')
        if type == 'sea':
            territory_data.pop('supply_center', None)
            territory_data.pop('nationality', None)
            territory_data.pop('controlled_by', None)
        territory = territory_class(**territory_data)
        state.register(territory)
    # instantiate and register named coasts
    for named_coast_data in data['named_coasts']:
        t_id = named_coast_data.pop('territory_id')
        named_coast_data['parent'] = [
            t for t in state.territories if t.id == t_id
        ][0]
        n_ids = named_coast_data.pop('neighbour_ids')
        named_coast_data['neighbours'] = [
            t for t in state.territories if t.id in n_ids
        ]
        named_coast = NamedCoast(**named_coast_data)
        state.register(named_coast)
    # instantiate and register pieces
    for piece_data in data['pieces']:
        t_id = piece_data.pop('territory_id')
        n_id = piece_data.pop('named_coast_id', None)
        type = piece_data.pop('type')
        piece_data['territory'] = [
            t for t in state.territories if t.id == t_id
        ][0]
        if type == 'fleet':
            named_coasts = [n for n in state.named_coasts if n.id == n_id]
            if named_coasts:
                piece_data['named_coast'] = named_coasts[0]
        piece_class = piece_type_dict[type]
        piece = piece_class(**piece_data)
        state.register(piece)
    # instantiate and register orders
    for order_data in data['orders']:
        type = order_data.pop('type')
        source_id = order_data.pop('source_id')
        order_data['source'] = [
            t for t in state.territories if t.id == source_id
        ][0]
        if order_data.get('target_id'):
            target_id = order_data.pop('target_id')
            order_data['target'] = [
                t for t in state.territories if t.id == target_id
            ][0]
        if order_data.get('target_coast_id'):
            target_coast_id = order_data.pop('target_coast_id')
            s = 'target_coast'
            if type == 'build':
                s = 'named_coast'
            order_data[s] = [
                n for n in state.named_coasts if n.id == target_coast_id
            ][0]
        if order_data.get('aux_id'):
            aux_id = order_data.pop('aux_id')
            order_data['aux'] = [
                t for t in state.territories if t.id == aux_id
            ][0]
        if not type == 'build':
            order_data.pop('piece_type')
        if not type == 'move':
            order_data.pop('via_convoy', None)
        order_class = order_type_dict[type]
        order = order_class(**order_data)
        state.register(order)
    # create an order for all pieces without orders
    for piece in state.pieces:
        if not piece.order:
            order_data = {
                '_id': 0,
                'nation': piece.nation,
                'source': piece.territory
            }
            hold = Hold(**order_data)
            state.register(hold)
    return state
Esempio n. 16
0
 def test_next_turn_piece_count_successful_hold(self):
     territory = InlandTerritory(self.state, 1, 'Paris', 2, [])
     Army(self.state, 1, self.nation.id, territory)
     Hold(self.state, 1, self.nation.id, territory)
     self.assertEqual(self.nation.next_turn_piece_count, 1)