Esempio n. 1
0
    def non_combat_movement_phase(self, game: Game) -> None:
        '''
        This is the function used in the non-combat phase. In this phase it is only allowed to move units in tiles
        that the current player own.
        The units are moved with the function game.move_unit(from_tile, to_tile, unit)

        This is just an example of how movement can be implemented.
        :param game: Is the object of the game that contains the map, units etc..
        '''
        while len(game.movable) > 0:
            if r.random() > 0.5:
                unit = game.movable[0]
                pos = unit.get_position()
                possible = []

                for tile in game.map.board[pos[0]][pos[1]].neighbours:
                    if tile.owner == game.current_player:
                        possible.append(tile)
                if len(possible) == 0:
                    game.movable.remove(game.movable[0])
                    break
                to_tile = r.choice(possible)
                if to_tile.owner == game.current_player:
                    game.move_unit_friendly(game.map.board[pos[0]][pos[1]],
                                            to_tile, unit)
            else:
                break
        game.next_phase()
Esempio n. 2
0
 def non_combat_movement_phase(self, game: Game):
     """
     This will force the bot to always advance towards the enemy
     In the non-combat moving phase.
     """
     game.border_tiles = game.calculate_border()
     while len(game.movable) > 0:
         unit = game.movable[0]
         position = unit.get_position()
         new_tile = (-1, None)
         possible_tiles = []
         for tile in game.map.board[position[0]][position[1]].neighbours:
             if tile.owner == unit.owner:
                 for border_tile in game.border_tiles:
                     value = game.calculate_distance_between_tiles(
                         tile, border_tile)
                     if new_tile[0] > value or new_tile[1] is None:
                         new_tile = (value, tile)
                         if value == 0:
                             possible_tiles.append(tile)
         if new_tile[0] == 0:
             min_units = (-1, None)
             for tile in possible_tiles:
                 if len(tile.units) < min_units[0] or min_units[1] is None:
                     min_units = (len(tile.units), tile)
             game.move_unit_friendly(
                 game.map.board[position[0]][position[1]], new_tile[1],
                 unit)
         elif new_tile[0] == -1:
             game.movable.remove(game.movable[0])
         elif new_tile[1] is not None:
             game.move_unit_friendly(
                 game.map.board[position[0]][position[1]], new_tile[1],
                 unit)
     game.next_phase()
Esempio n. 3
0
 def purchase_phase(self, game: Game):
     '''
     In this phase, one should only buy units. The purchased units are placed into game.purchases.
     :param game: Is the object of the game that contains the map, units etc..
     '''
     while True:
         possible = game.recruitable()
         if len(possible) == 0:
             game.next_phase()
             break
         choice = r.randint(0, len(possible) - 1)
         game.recruit_unit(choice)
Esempio n. 4
0
    def moving_phase(self, game: Game)-> None:
        '''
        This function will calculate the odds of winning the battle,
        if the chance is greater than the threshold defined, it will attack.



        :param game: Is the object of the game that contains the map, units etc..

        '''
        game.battles = []
        while len(game.movable) > 0:
            if r.random() > 0.01:
                unit = game.movable[0]
                position = unit.get_position()
                to_tile = r.choice(game.map.board[position[0]][position[1]].neighbours)
                if to_tile.owner != game.current_player:
                    all_units = game.find_movable_in_tile(position)
                    attack_score = self.calc_winning_odds(all_units, to_tile.units)
                    if attack_score > self.attack_threshold:
                        for current_unit in all_units:
                            game.move_unit(game.map.board[position[0]][position[1]], to_tile, current_unit)
                else:
                    game.move_unit(game.map.board[position[0]][position[1]], to_tile, unit)
            else:
                break
        game.phase = 2.5
Esempio n. 5
0
    def __init__(self):
        bot = NewBot2(attack_threshold=0.1)
        bot2 = NewBot2(attack_threshold=0.35)
        germany = Nation(name='Germany', human=False, bot=bot)
        russia = Nation(name='Russia', human=False, bot=bot2)

        x, y = 4, 4

        self.game = Game(size=(4, 4), nations=[germany, russia])
Esempio n. 6
0
 def moving_phase(self, game: Game):
     '''
     This is the phase where one is supposed to move units, in friendly and unfriendly territory.
     If the unit is moved to a unfriendly tile, it will become a battle zone.
     The units are moved with the function game.move_unit(from_tile, to_tile, unit)
     :param game: Is the object of the game that contains the map, units etc..
     '''
     game.battles = []
     while len(game.movable) > 0:
         if r.random() > 0.01:
             unit = game.movable[0]
             pos = unit.get_position()
             to_tile = r.choice(game.map.board[pos[0]][pos[1]].neighbours)
             if to_tile.owner != game.current_player:
                 self.moved[to_tile.cords.__str__()] = pos
             game.move_unit(game.map.board[pos[0]][pos[1]], to_tile, unit)
         else:
             break
     game.phase = 2.5
Esempio n. 7
0
    def unit_placement_phase(self, game: Game):
        '''
        This is the phase where one is to place the units purchased in the purchasing phase.
        One is only allowed to place units in a tile where there is industry.

        This functions randomly distributes the units.
        :param game: Is the object of the game that contains the map, units etc..

        '''
        if game.current_player in game.purchases and len(
                game.deployable_places) > 0:
            while len(game.purchases[game.current_player]) > 0:
                i = r.randint(0, len(game.deployable_places) - 1)
                tile = game.deployable_places[i]
                unit = game.purchases[game.current_player][0]
                game.purchases[game.current_player].remove(unit)
                tile.units.append(unit)
                unit.set_position(tile.cords)

        if game.is_there_a_winner()[0]:
            return True
        else:
            game.reset_all_units()
            if not game.valid_board()[0]:
                print(game.map.board)
            else:
                game.next_phase()
Esempio n. 8
0
    def prioritize_casualties(self, game: Game, values):
        """
        This bot will prioritize to delete infs over tanks.
        """
        to_be_deleted = dict()
        if 'Inf' in values[0]:
            if len(values[0]['Inf']) >= values[1]:
                for unit in values[0]['Inf']:
                    if unit.type not in to_be_deleted:
                        to_be_deleted[unit.type] = []
                    to_be_deleted[unit.type].append(unit)
                    if len(to_be_deleted[unit.type]) == values[1]:
                        break
            elif len(values[0]['Inf']) < values[1]:
                for unit in values[0]['Inf']:
                    if unit.type not in to_be_deleted:
                        to_be_deleted[unit.type] = []
                    to_be_deleted[unit.type].append(unit)
                    diff = values[1] - len(to_be_deleted[unit.type])

                for unit in values[0]['Tank']:
                    if unit.type not in to_be_deleted:
                        to_be_deleted[unit.type] = []
                    to_be_deleted[unit.type].append(unit)
                    if len(to_be_deleted[unit.type]) == diff:
                        break

        elif 'Tank' in values[0]:
            for unit in values[0]['Tank']:
                if unit.type not in to_be_deleted:
                    to_be_deleted[unit.type] = []
                to_be_deleted[unit.type].append(unit)
                if len(to_be_deleted[unit.type]) == values[1]:
                    break

        for key in to_be_deleted:
            game.take_casualties(to_be_deleted, to_be_deleted[key][0].type,
                                 len(to_be_deleted[key]))
Esempio n. 9
0
    def prioritize_casualties(self, game: Game, values: tuple) -> None:
        '''
        This function is used to randomly pick units to delete after a battle.
        After the units has been selected they are deleted by the use of game.take_casualties().
        :param game: Is the object of the game that contains the map, units etc..
        :param values: A tuple with units (dict), hit counter.
        '''
        to_be_deleted = dict()
        attacker_types = list(values[0].keys())
        for i in range(values[1]):
            unit_type = r.choice(attacker_types)
            unit = values[0][unit_type][0]
            if unit.type not in to_be_deleted:
                to_be_deleted[unit.type] = []
            to_be_deleted[unit.type].append(unit)
            values[0][unit_type].remove(unit)
            if len(values[0][unit_type]) == 0:
                values[0].pop(unit_type, None)
            attacker_types = list(values[0].keys())

        for key in to_be_deleted:
            game.take_casualties(to_be_deleted, to_be_deleted[key][0].type,
                                 len(to_be_deleted[key]))
Esempio n. 10
0
    def run_game(self, bot_1, bot_2):
        germany = Nation(name=str(bot_1.__module__), bot=bot_1)
        russia = Nation(name=str(bot_2.__module__), bot=bot_2)
        results = {}
        number_of_rounds = 100
        for i in range(0, number_of_rounds):
            game = Game(size=(6, 6), nations=[germany, russia])
            while True:
                game.bot()
                is_there_a_winner, winner = game.is_there_a_winner()
                if is_there_a_winner:
                    if 'winner' not in results:
                        results['winner'] = {}
                        results['avg_rounds'] = {}

                    if winner not in results['winner']:
                        results['winner'][winner.name] = 0
                        results['avg_rounds'][winner.name] = 0

                    results['winner'][winner.name] += 1
                    results['avg_rounds'][
                        winner.name] += game.turn / number_of_rounds
                    break
        return results
Esempio n. 11
0
    def combat_phase(self, game: Game) -> None:
        '''
        This is the function thas performs the battle. It starts by picking a battle from the list of battles.
        This is done by using the function game.do_battle(battle_cords). (read that doc string if in doubt)
        :param game: Is the object of the game that contains the map, units etc..
        :return:
        '''
        while len(game.battles) > 0:
            results = game.do_battle(game.battles[0])
            attacker = results[0]
            defender = results[1]
            attack_finished = False
            defend_finished = False
            if attacker[1] > 0:
                attacker_count = game.find_unit_count(attacker[0])
                if attacker[1] >= attacker_count:
                    game.take_casualties(attacker[0], 'All', attacker_count)
                    attack_finished = True
                else:
                    game.current_player.bot.prioritize_casualties(
                        game, attacker)
            if defender[1] > 0:
                defender_count = game.find_unit_count(defender[0])
                if defender[1] >= defender_count:
                    game.take_casualties(defender[0], 'All', defender_count)
                    defend_finished = True
                else:
                    defender_keys = list(defender[0].keys())
                    if not defender[0][defender_keys[0]][0].owner.human:
                        defender[0][defender_keys[0]][
                            0].owner.bot.prioritize_casualties(game, defender)
                    else:
                        game.current_player = defender[0][
                            defender_keys[0]][0].owner
                        return defender

            if defend_finished and not attack_finished:
                game.conquer_tile(
                    game.map.board[game.battles[0][0]][game.battles[0][1]],
                    game.current_player)

            if attack_finished or defend_finished:
                game.battles.remove(game.battles[0])
        game.phase = 3
Esempio n. 12
0
 def initialization_phase(self, game: Game):
     '''
     Prepares for the turn. Read the docstring @phase_0()
     :param game: Is the object of the game that contains the map, units etc..
     '''
     game.phase_0()
Esempio n. 13
0
    def moving_phase(self, game: Game):
        '''
        This function would make the bot always move towards the enemy industry in an attempt to capture it, and then
        'starve' them of units.
        :param game: Is the object of the game that contains the map, units etc..
        :return:
        '''
        game.battles = []
        # Locate enemy industry
        target_tile = None
        for w in game.map.board:
            for h in w:
                if len(h.constructions) > 0 and h.owner.name is not game.current_player.name:
                    target_tile = h

        if target_tile is not None:
            while len(game.movable) > 0:
                unit = game.movable[0]
                position = unit.get_position()
                new_tile = (-1, None)
                possible_tiles = []
                for tile in game.map.board[position[0]][position[1]].neighbours:
                    value = game.calculate_distance_between_tiles(tile, target_tile)
                    if new_tile[0] > value or new_tile[1] is None:
                        new_tile = (value, tile)
                        if value == 0:
                            possible_tiles.append(tile)
                if new_tile[0] == 0:
                    min_units = (-1, None)
                    for tile in possible_tiles:
                        if len(tile.units) < min_units[0] or min_units[1] is None:
                            min_units = (len(tile.units), tile)
                    game.move_unit(game.map.board[position[0]][position[1]], new_tile[1], unit)
                elif new_tile[0] == -1:
                    game.movable.remove(game.movable[0])
                elif new_tile[1] is not None:
                    game.move_unit(game.map.board[position[0]][position[1]], new_tile[1], unit)

        elif target_tile is None:
            while len(game.movable) > 0:
                if r.random() > 0.01:
                    unit = game.movable[0]
                    position = unit.get_position()
                    to_tile = r.choice(game.map.board[position[0]][position[1]].neighbours)
                    if to_tile.owner != game.current_player:
                        all_units = game.find_movable_in_tile(position)
                        attack_score = self.calc_winning_odds(all_units, to_tile.units)
                        if attack_score > 0.15:
                            for current_unit in all_units:
                                game.move_unit(game.map.board[position[0]][position[1]], to_tile, current_unit)
                    else:
                        game.move_unit(game.map.board[position[0]][position[1]], to_tile, unit)
                else:
                    break
        game.phase = 2.5
Esempio n. 14
0
 def purchase_inf(self, game: Game):
     game.recruit_unit(1)