예제 #1
0
파일: game.py 프로젝트: JaWSnl/the-ai-games
class Game(object):
    def __init__(self, game_state=GameState(), starting_armies=0):
        self.__state = game_state
        self.__starting_armies = starting_armies
        self.__attack_sampler = None
        self.__transfer_sampler = None
        self.__pick_starting_regions_sampler = None
        self.__deployment_sampler = None
        self.__place_logic = PlaceLogic(self.__state)  # TODO remove
        self.__attack_logic = AttackLogic(self.__state)
        self.__transfer_logic = TransferLogic(self.__state)

    def pick_starting_regions(self, pickable_regions):
        starting_regions = []
        situation = self.__state.situation
        for i in range(0, 6):
            region, situation = self.__pick_starting_regions_sampler.best_sample(pickable_regions,
                                                                                 situation)
            starting_regions.append(region)
            pickable_regions = [r for r in pickable_regions if r != region]
        return starting_regions

    def place_armies(self):
        return self.__place_logic.place_armies(self.__starting_armies)

    def make_moves(self):
        my_regions = self.__state.situation.get_player_regions(self.__state.player)
        moves = []
        for region in my_regions:
            foreign_neighbors = self.__state.situation.foreign_neighbors(region, self.__state.player)
            if foreign_neighbors:
                moves += self.__attack_logic.attacks_for(region)
            else:
                moves += self.__transfer_logic.transfers_for(region)
        return moves

    def init_samplers(self):
        self.__attack_sampler = AttackSampler(self.__state.player_profile)
        self.__transfer_sampler = TransferSampler(self.__state.player_profile)
        self.__pick_starting_regions_sampler = PickStartingRegionsSampler(self.__state.player_profile)
        self.__deployment_sampler = DeploymentSampler(self.__state.player_profile)

    def process_command(self, input_command):
        output_commands = []
        map = self.__state.map
        if isinstance(input_command, SuperRegionsCmd):
            map.init_super_regions(input_command.super_region_to_reward())
        elif isinstance(input_command, RegionsCmd):
            map.init_regions(input_command.region_to_super_region())
        elif isinstance(input_command, NeighborsCmd):
            map.init_neighbors(input_command.region_to_neighbors())
            # After this command, we have a fully initialized map, so we can create a situation
            self.__state.init_situation()
            self.init_samplers()
        elif isinstance(input_command, PickStartingRegionsRequestCmd):
            output_commands = [PickStartingRegionsCmd(' '.join(self.pick_starting_regions(input_command.regions())))]
        elif isinstance(input_command, UpdateMapCmd):
            for region in self.__state.situation.get_player_regions(self.__state.player):
                region.owner = self.__state.opponent
            for update in input_command.map_updates():
                self.__state.situation.update_map(update)
        elif isinstance(input_command, OpponentMovesCmd):
            for command in input_command.opponent_commands():
                if isinstance(command, PickStartingRegionsCmd):
                    self.__state.situation.update_opponent_picked_regions(command.regions())
                elif isinstance(command, MoveCmd):
                    self.__state.situation.update_opponent_moved(command.move(), self.__state.player)
                elif isinstance(command, PlaceArmiesCmd):
                    self.__state.situation.update_opponent_placed_armies(command.placed_armies())
                else:
                    pass
        elif isinstance(input_command, BotNameCmd):
            self.__state.player = input_command.bot_name()
        elif isinstance(input_command, OpponentNameCmd):
            self.__state.opponent = input_command.bot_name()
        elif isinstance(input_command, StartingArmiesCmd):
            self.__starting_armies = input_command.num_armies()
        elif isinstance(input_command, PlaceArmiesRequestCmd):
            output_commands = [PlaceArmiesCmd(placed.output()) for placed in self.place_armies()]
            if not output_commands:
                output_commands = [DontMoveCmd()]
        elif isinstance(input_command, MoveRequestCmd):
            output_commands = [MoveCmd(move.output()) for move in self.make_moves()]
            if not output_commands:
                output_commands = [DontMoveCmd()]
        else:
            raise UnknownCommandException(input_command)

        return output_commands
예제 #2
0
class TransferLogicTestCase(unittest.TestCase):

    def setUp(self):
        map, situation = get_sample_map1()
        self.game_state = GameState(map, "me", "he", situation=situation)
        self.transfer_logic = TransferLogic(self.game_state)

    def test_map_creation(self):
        pass

    # @unittest.skip("testing skipping")
    def test_troops_move_1_closer_to_captured_continent_edge_south_america(self):
        self.game_state.situation.update_map(MapUpdate("10", "me", 1))
        self.game_state.situation.update_map(MapUpdate("11", "me", 1))
        self.game_state.situation.update_map(MapUpdate("12", "me", 1))
        self.game_state.situation.update_map(MapUpdate("13", "me", 2))

        from_region = self.game_state.map.region("13")
        transfers = self.transfer_logic.transfers_for(from_region)
        self.assertNotEqual(0, len(transfers), "No transfer detected")
        self.assertEqual(1, len(transfers), "More than 1 transfer detected")

        expected_move = Move("me", "13", "12", 1)
        actual_move = transfers.pop()
        self.assertEqual(expected_move, actual_move)

    def test_troops_move_1_closer_to_captured_continent_edge_australia(self):
        self.game_state.situation.update_map(MapUpdate("39", "me", 1))
        self.game_state.situation.update_map(MapUpdate("40", "me", 2))
        self.game_state.situation.update_map(MapUpdate("41", "me", 1))
        self.game_state.situation.update_map(MapUpdate("42", "me", 2))

        from_region = self.game_state.map.region("40")
        transfers = self.transfer_logic.transfers_for(from_region)
        self.assertNotEqual(0, len(transfers), "No transfer detected")
        self.assertEqual(1, len(transfers), "More than 1 transfer detected")
        expected_move = Move("me", "40", "39", 1)
        actual_move = transfers.pop()
        self.assertEqual(expected_move, actual_move)

        from_region = self.game_state.map.region("42")
        transfers = self.transfer_logic.transfers_for(from_region)
        self.assertNotEqual(0, len(transfers), "No transfer detected")
        self.assertEqual(1, len(transfers), "More than 1 transfer detected")
        possible_moves = [Move("me", "42", "40", 1), Move("me", "42", "41", 1)]
        actual_move = transfers.pop()
        self.assertIn(actual_move, possible_moves)

    def test_troops_stay_at_continent_edge_when_enemy_on_other_side_australia(self):
        self.game_state.situation.update_map(MapUpdate("38", "he", 1))
        self.game_state.situation.update_map(MapUpdate("39", "me", 2))
        self.game_state.situation.update_map(MapUpdate("40", "me", 1))
        self.game_state.situation.update_map(MapUpdate("41", "me", 1))
        self.game_state.situation.update_map(MapUpdate("42", "me", 1))

        from_region = self.game_state.map.region("39")
        transfers = self.transfer_logic.transfers_for(from_region)
        self.assertEqual(0, len(transfers), "Transfer detected away from continent edge region")

    def test_troops_move_to_enemy_on_same_continent_australia(self):
        self.game_state.situation.update_map(MapUpdate("39", "he", 1))
        self.game_state.situation.update_map(MapUpdate("40", "me", 1))
        self.game_state.situation.update_map(MapUpdate("41", "me", 1))
        self.game_state.situation.update_map(MapUpdate("42", "me", 2))

        from_region = self.game_state.map.region("42")
        transfers = self.transfer_logic.transfers_for(from_region)
        self.assertNotEqual(0, len(transfers), "No transfer detected")
        self.assertEqual(1, len(transfers), "More than 1 transfer detected")
        possible_moves = [Move("me", "42", "40", 1), Move("me", "42", "41", 1)]
        actual_move = transfers.pop()
        self.assertIn(actual_move, possible_moves)

    def test_troops_move_to_enemy_on_same_continent_africa(self):
        self.game_state.situation.update_map(MapUpdate("21", "he", 1))
        self.game_state.situation.update_map(MapUpdate("22", "me", 1))
        self.game_state.situation.update_map(MapUpdate("23", "me", 1))
        self.game_state.situation.update_map(MapUpdate("24", "me", 1))
        self.game_state.situation.update_map(MapUpdate("25", "me", 2))
        self.game_state.situation.update_map(MapUpdate("26", "me", 2))

        from_region = self.game_state.map.region("26")
        transfers = self.transfer_logic.transfers_for(from_region)
        self.assertNotEqual(0, len(transfers), "No transfer detected")
        self.assertEqual(1, len(transfers), "More than 1 transfer detected")
        self.assertEqual(Move("me", "26", "23", 1), transfers.pop())

        from_region = self.game_state.map.region("25")
        transfers = self.transfer_logic.transfers_for(from_region)
        self.assertNotEqual(0, len(transfers), "No transfer detected")
        self.assertEqual(1, len(transfers), "More than 1 transfer detected")
        possible_moves = [Move("me", "25", "23", 1), Move("me", "25", "24", 1)]
        actual_move = transfers.pop()
        self.assertIn(actual_move, possible_moves)