Example #1
0
 def _simulate(self, action, player_status, enemy_status):
     ''' Takes away num_armies from source, and add num_armies to the destination '''
     source, destination, num_armies = action
     sim_player_status = copy.deepcopy(player_status)
     sim_source = get_territory_by_id(source['territory'], sim_player_status['territories'])
     sim_source['num_armies'] -= num_armies
     sim_dest = get_territory_by_id(destination['territory'], sim_player_status['territories'])
     sim_dest['num_armies'] += num_armies
     return (sim_player_status, enemy_status)
Example #2
0
def _our_threat(t_id, map_layout, player_status, enemy_status):
    bst = 0
    enemy_territory_ids = [t['territory'] for t in enemy_status['territories']]
    player_territory_ids = [t['territory'] for t in player_status['territories']]
    for adjacent_id in get_territory_by_id(t_id, map_layout['territories'])['adjacent_territories']:
        if adjacent_id in player_territory_ids:
            bst += get_territory_by_id(adjacent_id, player_status['territories'])['num_armies']
    bsr = float(bst) / get_territory_by_id(t_id, enemy_status['territories'])['num_armies']
    return bsr
Example #3
0
 def _simulate(self, action, player_status, enemy_status):
     ''' Takes away num_armies from source, and add num_armies to the destination '''
     source, destination, num_armies = action
     sim_player_status = copy.deepcopy(player_status)
     sim_source = get_territory_by_id(source['territory'],
                                      sim_player_status['territories'])
     sim_source['num_armies'] -= num_armies
     sim_dest = get_territory_by_id(destination['territory'],
                                    sim_player_status['territories'])
     sim_dest['num_armies'] += num_armies
     return (sim_player_status, enemy_status)
Example #4
0
def _our_threat(t_id, map_layout, player_status, enemy_status):
    bst = 0
    enemy_territory_ids = [t['territory'] for t in enemy_status['territories']]
    player_territory_ids = [
        t['territory'] for t in player_status['territories']
    ]
    for adjacent_id in get_territory_by_id(
            t_id, map_layout['territories'])['adjacent_territories']:
        if adjacent_id in player_territory_ids:
            bst += get_territory_by_id(
                adjacent_id, player_status['territories'])['num_armies']
    bsr = float(bst) / get_territory_by_id(
        t_id, enemy_status['territories'])['num_armies']
    return bsr
Example #5
0
def _distance(t_id, map_layout, player_status, enemy_status):
    q = deque()
    path = (t_id, )
    q.append(path)
    visited = set([t_id])
    while q:
        path = q.popleft()
        last_node = path[-1]
        if get_territory_by_id(last_node, enemy_status['territories']):
            return len(path) - 1
        for node in get_territory_by_id(last_node, map_layout['territories'])['adjacent_territories']:
            if node not in visited:
                visited.add(node)
                q.append(path + (node, ))
    return 99999
Example #6
0
def _distance(t_id, map_layout, player_status, enemy_status):
    q = deque()
    path = (t_id, )
    q.append(path)
    visited = set([t_id])
    while q:
        path = q.popleft()
        last_node = path[-1]
        if get_territory_by_id(last_node, enemy_status['territories']):
            return len(path) - 1
        for node in get_territory_by_id(
                last_node, map_layout['territories'])['adjacent_territories']:
            if node not in visited:
                visited.add(node)
                q.append(path + (node, ))
    return 99999
Example #7
0
 def _simulate(self, action, player_status, enemy_status):  # 0.0004
     sim_player_status = copy.deepcopy(player_status)  # 0.00035
     sim_player_status["num_armies"] += 1
     sim_player_status["num_reserves"] -= 1
     t = get_territory_by_id(action["territory"], sim_player_status["territories"])  # 9e-6
     t["num_armies"] += 1
     return (sim_player_status, enemy_status)
Example #8
0
 def reinforce(self, num_reserves):
     """ Returns {<territoryId>: <num troops deployed>} """
     if (
         self.tank_territory_id == None
         or utils.get_territory_by_id(self.tank_territory_id, self.player_status["territories"]) == None
     ):
         self.tank_territory_id = self.player_status["territories"][0]["territory"]
     return {self.tank_territory_id: num_reserves}
Example #9
0
    def fortify(self, legal_territories_to_fortify):
        """ Returns (from_territory, to_territory, num_armies_to_move), or a None value if ending turn """

        if self.target_id:

            conqueredTerritory = utils.get_territory_by_id(self.target_id, self.player_status["territories"])

            if conqueredTerritory:

                tmp_id = self.tank_territory_id
                self.tank_territory_id = self.target_id
                source = utils.get_territory_by_id(tmp_id, self.player_status["territories"])

                num_armies = source["num_armies"]
                if num_armies > 1:
                    return (tmp_id, self.target_id, num_armies - 1)

        return None
Example #10
0
    def fortify(self, legal_territories_to_fortify):
        ''' Returns (from_territory, to_territory, num_armies_to_move), or a None value if ending turn '''

        if self.target_id:

            conqueredTerritory = utils.get_territory_by_id(self.target_id, self.player_status['territories'])

            if conqueredTerritory:

                tmp_id = self.tank_territory_id
                self.tank_territory_id = self.target_id
                source = utils.get_territory_by_id(tmp_id, self.player_status['territories'])

                num_armies = source['num_armies']
                if num_armies > 1:
                    return (tmp_id, self.target_id, num_armies - 1)

        return None
Example #11
0
    def _simulate(self, action, player_status, enemy_status): # 0.0004
        # outcomes = {prob: game_state}
        outcomes = {}

        # if win
        src, dest = action

        win_prob = Battle_Computer.compute(src['num_armies'], dest['num_armies'])
        win_player_status = copy.deepcopy(player_status)
        win_enemy_status = copy.deepcopy(enemy_status)
        win_src = get_territory_by_id(action[0]['territory'], win_player_status['territories'])
        win_dest = get_territory_by_id(action[1]['territory'], win_enemy_status['territories'])
        win_src['num_armies'] = max(win_src['num_armies'] - win_dest['num_armies'], 1) # Expected winner loss
        win_dest['num_armies'] = 3 # Expected number of troops moved
        win_player_status['territories'].append(win_dest)
        win_enemy_status['territories'].remove(win_dest)
        win_state = {
            'player_status': win_player_status,
            'enemy_status': win_enemy_status
        }

        lose_prob = 1 - win_prob
        lose_player_status = copy.deepcopy(player_status)
        lose_player_status['num_armies'] -= (src['num_armies'] - 1)
        lose_enemy_status = copy.deepcopy(enemy_status)
        lose_src = get_territory_by_id(action[0]['territory'], lose_player_status['territories'])
        lose_src['num_armies'] = 1 # Number of troops remaining on battle loss
        lose_dest = get_territory_by_id(action[1]['territory'], lose_enemy_status['territories'])
        lose_dest['num_armies'] = lose_dest['num_armies'] / 2 + 1 # Expected enemy troop loss
        lose_state = {
            'player_status': lose_player_status,
            'enemy_status': lose_enemy_status
        }

        outcomes[win_prob] = win_state
        outcomes[lose_prob] = lose_state

        return outcomes
Example #12
0
    def do_battle(self):
        ''' Returns True when done, false otherwise '''
        legal_battles = self._create_set_of_legal_battles()
        battle = self.battle(legal_battles)

        if battle:
            tattack, tdefend, num_armies = battle
            legal_battles_to_ids = map(
                lambda (a, d): (a['territory'], d['territory']), legal_battles)
            if ((tattack, tdefend) not in legal_battles_to_ids):
                self._err(AttackError.ILLEGAL_ATTACK(tattack, tdefend))
            else:
                t = utils.get_territory_by_id(
                    tattack, self.player_status['territories'])
                # There must be enough troops to attack
                if num_armies > t['num_armies'] - 1:
                    self._err(
                        AttackError.NOT_ENOUGH_ARMY(tattack, tdefend,
                                                    num_armies))
                # There can't be more than 3 troops attacking
                elif num_armies > 3:
                    self._err(
                        AttackError.TOO_MUCH_ARMY(tattack, tdefend,
                                                  num_armies))
                else:
                    # Everything is valid
                    self.attack(tattack, tdefend, num_armies)
                    time.sleep(config.DELAY_BETWEEN_ACTIONS)
                    self._refresh_state()
                    if utils.get_territory_by_id(
                            tdefend, self.player_status['territories']):
                        print "Conquered"
                        attack_move = (utils.get_territory_by_id(tattack, self.player_status['territories']), \
                            utils.get_territory_by_id(tdefend, self.player_status['territories']), \
                            utils.get_territory_by_id(tattack, self.player_status['territories'])['num_armies'] - 1)
                        sim_score = self.fe.evaluate_action(
                            attack_move, self.map_layout, self.player_status,
                            self.enemy_status)
                        score = features.evaluate_fortify(
                            self.map_layout, self.player_status,
                            self.enemy_status)
                        if sim_score > score:
                            print "ATTACK MOVE!"
                            self.transfer_armies(
                                tattack, tdefend,
                                utils.get_territory_by_id(
                                    tattack, self.player_status['territories'])
                                ['num_armies'] - 1)
            return False
        else:
            return True
Example #13
0
    def do_fortify(self):
        legal_forts = self._create_set_of_legal_fortifications()
        fortification = self.fortify(legal_forts)

        if fortification:
            tfrom, tto, num_armies = fortification
            legal_forts_to_ids = map(lambda (f,t): (f['territory'], t['territory']), legal_forts)
            # Fortification must occur between adjacent territories
            if (tfrom, tto) not in legal_forts_to_ids:
                self._err(FortifyError.ILLEGAL_FORTIFY(tfrom, tto))
            else:
                t = utils.get_territory_by_id(tfrom, self.player_status['territories'])
                # There must be enough troops to move
                if num_armies > t['num_armies'] - 1:
                    self._err(FortifyError.NOT_ENOUGH_ARMY(tfrom, tto, num_armies))
                else:
                    # Everything is valid
                    self.transfer_armies(tfrom, tto, num_armies)
        else:
            self.end_turn()
Example #14
0
    def do_reinforce(self):
        num_reserves = self.player_status['num_reserves']
        reinforcements = self.reinforce(num_reserves)

        # TODO handle error when placing in enemy territory
        invalid_ids = filter(lambda t_id: utils.get_territory_by_id(t_id,self.player_status['territories']) == None, reinforcements.keys())
        if invalid_ids:
            self._err(ReinforceError.TERRITORY_NOT_OWNED(invalid_ids))

        num_deployed = sum(reinforcements.values())
        # All troops must be deployed
        if (num_deployed < num_reserves):
            self._err(ReinforceError.LEFTOVER_ARMY)
        # Cannot deploy too many troops
        elif (num_deployed > num_reserves):
            self._err(ReinforceError.TOO_MUCH_ARMY)

        # Execute reinforcement
        for t_id, num_troops in reinforcements.iteritems():
            self.place_armies(t_id, num_troops)
Example #15
0
    def do_reinforce(self):
        num_reserves = self.player_status['num_reserves']
        reinforcements = self.reinforce(num_reserves)

        # TODO handle error when placing in enemy territory
        invalid_ids = filter(
            lambda t_id: utils.get_territory_by_id(
                t_id, self.player_status['territories']) == None,
            reinforcements.keys())
        if invalid_ids:
            self._err(ReinforceError.TERRITORY_NOT_OWNED(invalid_ids))

        num_deployed = sum(reinforcements.values())
        # All troops must be deployed
        if (num_deployed < num_reserves):
            self._err(ReinforceError.LEFTOVER_ARMY)
        # Cannot deploy too many troops
        elif (num_deployed > num_reserves):
            self._err(ReinforceError.TOO_MUCH_ARMY)

        # Execute reinforcement
        for t_id, num_troops in reinforcements.iteritems():
            self.place_armies(t_id, num_troops)
Example #16
0
    def do_fortify(self):
        legal_forts = self._create_set_of_legal_fortifications()
        fortification = self.fortify(legal_forts)

        if fortification:
            tfrom, tto, num_armies = fortification
            legal_forts_to_ids = map(
                lambda (f, t): (f['territory'], t['territory']), legal_forts)
            # Fortification must occur between adjacent territories
            if (tfrom, tto) not in legal_forts_to_ids:
                self._err(FortifyError.ILLEGAL_FORTIFY(tfrom, tto))
            else:
                t = utils.get_territory_by_id(
                    tfrom, self.player_status['territories'])
                # There must be enough troops to move
                if num_armies > t['num_armies'] - 1:
                    self._err(
                        FortifyError.NOT_ENOUGH_ARMY(tfrom, tto, num_armies))
                else:
                    # Everything is valid
                    self.transfer_armies(tfrom, tto, num_armies)
        else:
            self.end_turn()
Example #17
0
    def do_battle(self):
        ''' Returns True when done, false otherwise '''
        legal_battles = self._create_set_of_legal_battles()
        battle = self.battle(legal_battles)

        if battle:
            tattack, tdefend, num_armies = battle
            legal_battles_to_ids = map(lambda (a,d): (a['territory'], d['territory']), legal_battles)
            if ((tattack, tdefend) not in legal_battles_to_ids):
                self._err(AttackError.ILLEGAL_ATTACK(tattack, tdefend))
            else:
                t = utils.get_territory_by_id(tattack, self.player_status['territories'])
                # There must be enough troops to attack
                if num_armies > t['num_armies'] - 1:
                    self._err(AttackError.NOT_ENOUGH_ARMY(tattack, tdefend, num_armies))
                # There can't be more than 3 troops attacking
                elif num_armies > 3:
                    self._err(AttackError.TOO_MUCH_ARMY(tattack, tdefend, num_armies))
                else:
                    # Everything is valid
                    self.attack(tattack, tdefend, num_armies)
                    time.sleep(config.DELAY_BETWEEN_ACTIONS)
                    self._refresh_state()
                    if utils.get_territory_by_id(tdefend, self.player_status['territories']):
                        print "Conquered"
                        attack_move = (utils.get_territory_by_id(tattack, self.player_status['territories']), \
                            utils.get_territory_by_id(tdefend, self.player_status['territories']), \
                            utils.get_territory_by_id(tattack, self.player_status['territories'])['num_armies'] - 1)
                        sim_score = self.fe.evaluate_action(attack_move, self.map_layout, self.player_status, self.enemy_status)
                        score = features.evaluate_fortify(self.map_layout, self.player_status, self.enemy_status)
                        if sim_score > score:
                            print "ATTACK MOVE!"
                            self.transfer_armies(tattack, tdefend, utils.get_territory_by_id(tattack, self.player_status['territories'])['num_armies'] - 1)      
            return False
        else:
            return True
Example #18
0
 def reinforce(self, num_reserves):
     ''' Returns {<territoryId>: <num troops deployed>} '''
     if self.tank_territory_id == None or utils.get_territory_by_id(self.tank_territory_id, self.player_status['territories']) == None:
         self.tank_territory_id = self.player_status['territories'][0]['territory']
     return { self.tank_territory_id: num_reserves }