def move_utility(board, block, start_regionid, end_regionid, is_stay, turn):
    """
	returns between 0 and 1
	probability that it will choose again
	"""
    start_region = search.region_id_to_object(board, start_regionid)
    end_region = search.region_id_to_object(board, end_regionid)

    move_utility = 0
    if regroup.noble_home_to_object(board, start_regionid):
        if is_stay:
            move_utility += .4

    simulation_dict = simulations.simulation([block],
                                             end_region.blocks_present, list(),
                                             list())
    move_utility += retreat.retreat(board, end_regionid, [], simulation_dict,
                                    True, turn)['Staying value'] / 150

    if move_utility >= 1:
        move_utility = 0.8
    elif move_utility == 0:
        move_utility = 0.2

    return move_utility
def value_blocks(board, regionid):
    valuable_blocks = {'WALLACE': 18, 'KING': 22, 'EDWARD': 16, 'HOBELARS': 13}
    value = 0
    region = search.region_id_to_object(board, regionid)
    for block in region.blocks_present:
        if block.name in valuable_blocks:
            value += valuable_blocks[block.name]
    return value
def max_health(board, region):
    """
	region is regionid
	"""

    region = search.region_id_to_object(board, region)
    health_sum = 0
    for block in region.blocks_present:
        health_sum += block.attack_strength
    return health_sum
    def find_all_borders(self, regionID_list):
        '''
		returns a list of all bordering regionIDs in a list of regionIDs
		'''
        return_list = list()
        for element in regionID_list:
            for i, border in enumerate(self.static_borders[element]):

                if border == "B" or border == "R":
                    return_list.append(search.region_id_to_object(self, i))

        return return_list
    def find_adjacent_regions_object(self, region):
        '''
		Returns a list of all bordering regions of a region, given its region
		'''

        return_list = []
        for i, border in enumerate(self.static_borders[region.regionID]):

            if border == "B" or border == "R":
                return_list.append(search.region_id_to_object(self, i))

        return return_list
    def add_to_location(self, block, location):
        '''
		takes a board, block, and region object
		removes block from its current region 
		puts it into the new location
		'''

        if type(location) == int:
            location = search.region_id_to_object(self, location)

        if location == 'scottish pool':
            self.regions[find_location(
                self, block).regionID].blocks_present.remove(block)

            self.scot_pool.append(block)
        elif location == 'english pool':
            self.regions[find_location(
                self, block).regionID].blocks_present.remove(block)
            self.eng_pool.append(block)
            print("Sent" + block.name + ' to ' + location.name)

        else:
            if location.regionID != find_location(self, block):
                #print(block)
                region = find_location(self, block)
                #print(find_location(self,block))
                #print(block)
                remove_region_id = find_location(self, block).regionID
                #print(remove_region_id)
                #print(self.regions[remove_region_id].blocks_present)
                self.remove_from_region(block, remove_region_id)
                #print(block)
                #print(region)
                self.regions[location.regionID].blocks_present.append(block)

            print("Sent " + block.name + " to " + location.name)
Exemplo n.º 7
0
def go_home(board, noble, eng_type, scot_type):
    '''
	takes a noble from the location that they are at and then transports them
	home. also takes board object and the side that the computer is playing
	if there is more than 1 home location, it randomly picks one.
	changes allegiance based on who controls home area
	'''

    if type(noble.home_location) == int:
        print(noble.name)
        if noble.home_location == find_location(board, noble).regionID:

            print(noble.name + " is already home.")

        elif not board.regions[
                noble.home_location].blocks_present or board.regions[
                    noble.home_location].blocks_present[
                        0].allegiance == noble.allegiance:

            print(noble.name)
            start = find_location(board, noble).regionID
            board.remove_from_region(noble, start)

            board.regions[noble.home_location].blocks_present.append(noble)

        else:

            noble.allegiance = board.regions[
                noble.home_location].blocks_present[0].allegiance

            print(noble.name + '\'s allegiance was changed to ' +
                  board.regions[
                      noble.home_location].blocks_present[0].allegiance)

            start = find_location(board, noble).regionID
            board.remove_from_region(noble, start)

            board.regions[noble.home_location].blocks_present.append(noble)

    else:

        possible_locations = []

        new_locations = []

        for home in noble.home_location:

            new_locations.append(home)

            if not board.regions[home].blocks_present or board.regions[
                    home].blocks_present[0].allegiance == noble.allegiance:

                possible_locations.append(board.regions[home])

        else:

            if not possible_locations:
                print(noble.name + ' changes their allegiance')
                if noble.allegiance == "SCOTLAND":

                    noble.allegiance == "ENGLAND"
                    board.scot_roster.remove(noble)
                    board.eng_roster.append(noble)

                else:

                    noble.allegiance == "SCOTLAND"
                    board.eng_roster.remove(noble)
                    board.scot_roster.append(noble)
                print(
                    'IN THE BOARD NOBLE ALLEGIANCE IS: ',
                    search.block_name_to_object(board.all_blocks, noble.name))
                noble_choice = search.region_id_to_object(
                    board,
                    choose_location(new_locations, noble.allegiance, eng_type,
                                    scot_type, noble))
                print(noble.name + ' went home to ' +
                      board.regions[noble_choice.regionID].name)

                add_to_location(board, noble, noble_choice)

            else:

                noble_new_home = choose_location(possible_locations,
                                                 noble.allegiance, eng_type,
                                                 scot_type, noble)

                #add_to_location(board,noble,noble_new_home)
                current_loca = find_location(board, noble)

                board.remove_from_region(noble, current_loca.regionID)
                board.regions[noble_new_home.regionID].blocks_present.append(
                    noble)
    return noble
def vic_utility(board, role):
    """
	evaluates the value of playing the victuals card with the chosen region and blocks
	"""

    #decide whether you want to play victuals based on chosen region and block list
    region_dict = victuals_region_utility(board, role)

    chosen_region_ID = weighted_prob.weighted_prob(region_dict)
    #convert from id to Region
    chosen_region = search.region_id_to_object(board, chosen_region_ID)

    #choosing blocks to victual and adding them to victual_block_list
    victual_block_list = []

    for counter in range(3):
        blocks_dict = victuals_block_utility(chosen_region, role)
        victual_block_list.append(weighted_prob.weighted_prob(blocks_dict))

    utility_value = 0.00000000001
    hits_taken = 0
    for block_id in victual_block_list:
        block = search.block_id_to_object(board.all_blocks, block_id)
        #for scotland:
        #if block is king and he needs it
        if block.name == 'KING' and block.current_strength < block.attack_strength:
            utility_value += .9
        #if block is wallace and he needs it
        elif block.name == 'WALLACE' and block.current_strength < block.attack_strength:
            utility_value += .8
        #for england:
        #if block is edward and he needs it
        if block.name == 'EDWARD' and block.current_strength < block.attack_strength:
            utility_value += .85
        #if block is hobelars and he needs it
        elif block.name == 'HOBELARS' and block.current_strength < block.attack_strength:
            utility_value += .7

        #if block is type noble and he needs it
        elif type(
                block
        ) == blocks.Noble and block.current_strength < block.attack_strength:
            utility_value += .65
        #if block is below full health
        elif block.current_strength < block.attack_strength:
            utility_value += .2

        hits_taken += block.attack_strength - block.current_strength

    #to maximize 3 healing points
    if hits_taken >= 3:
        utility_value += .25
    elif hits_taken == 2:
        utility_value += .1

    #to convert victual block list to blocks from blockIDs before it's returned
    return_victual_block_lst = []
    for blockID in victual_block_list:
        block = search.block_id_to_object(board.all_blocks, block_id)
        return_victual_block_lst.append(block)

    return utility_value, return_victual_block_lst
def regroup(winner_blocks, current_board, eng_type, scot_type):
    """
	regroups after someone wins
	winner_blocks is a list of winning blocks
	current_board is board
	"""

    if winner_blocks:

        if winner_blocks[0].allegiance == 'ENGLAND':
            winner_type = eng_type
        elif winner_blocks[0].allegiance == 'SCOTLAND':
            winner_type = scot_type

        if winner_type == 'comp':
            for block in winner_blocks:

                original_location = find_location(current_board, block)
                #print(original_location)
                #print('111111111')
                #print('LOCATION OF BLOCK: ', find_location(current_board, block))
                possible_locations = regroup_locations(current_board, [block],
                                                       [], False)

                possible_locations_id = list()
                for location in possible_locations:
                    possible_locations_id.append(location.regionID)

                current_location = find_location(current_board,
                                                 winner_blocks[0])
                #Call the regrouping utility function which returns the ID of a region that the block should regroup to
                place_to_go_to = search.region_id_to_object(
                    current_board,
                    regroup_util.regroup_utility(current_board,
                                                 current_location.regionID,
                                                 possible_locations_id))

                if len(possible_locations) == 1:
                    print(block.name, ' stays')
                    continue
                else:

                    #place_to_go_to is now a regionID, now a Region
                    place_to_go_to = place_to_go_to.regionID
                    #print(place_to_go_to)
                    current_board.add_to_location(block, place_to_go_to)

                    current_board.dynamic_borders[
                        original_location.regionID][place_to_go_to] -= 1

                    if block.name == 'FRENCH':
                        block.movement_points = 0
                    print(
                        block.name, ' moved to ',
                        search.region_id_to_name(current_board,
                                                 place_to_go_to))
        elif winner_type == 'opp':
            for block in winner_blocks:

                original_location = find_location(current_board, block)
                bad_input = True
                #print('22222222')
                possible_locations = regroup_locations(current_board, [block],
                                                       [], False)

                for i, region in enumerate(possible_locations):
                    print(region.name, region.regionID, end='; ')

                while bad_input:
                    place_to_go_to_str = input(
                        'Which location to regroup to? (type number) >')
                    if not place_to_go_to_str.isdigit():
                        print('type a number')

                    else:
                        place_to_go_to = int(place_to_go_to_str)

                        for region in possible_locations:
                            if place_to_go_to == region.regionID:
                                region_to_go_to = region
                                bad_input = False
                        else:
                            print('Enter a valid region ID.')

                place_to_go_to = region_to_go_to.regionID

                if not bad_input:
                    if place_to_go_to != -1:

                        current_board.add_to_location(block, place_to_go_to)

                        current_board.dynamic_borders[
                            original_location.regionID][place_to_go_to] -= 1

                    if block.name == 'FRENCH':
                        block.movement_points = 0
                        print(
                            block.name, ' moved to ',
                            search.region_id_to_name(current_board,
                                                     place_to_go_to))

    current_board.reset_borders()
    current_board.reset_attacked_borders()
def pil_execution(board, position, role, pil_data):

    print(role)
    
    if position == 'comp':
        """
        #loop through regions to make sure there is a region that it works in
        for region_controlled in board.get_controlled_regions(role):
            new_list = []
            new_list.append(region_controlled.regionID)
            for neighbor_region in board.find_all_borders(new_list):
                if not neighbor_region.is_friendly(role) and not neighbor_region.is_neutral():
                    possible = True
        
        if possible:
            
            #make a list of possible opponent regions to be pillaged 
            possible_pill_lst = []
            for region in board.get_controlled_regions(role):
                new_list = []
                new_list.append(region.regionID)
                for neighbor_region in board.find_all_borders(new_list):
                    if not neighbor_region.is_friendly(role) and not neighbor_region.is_neutral() and neighbor_region not in possible_pill_lst:
                        possible_pill_lst.append(neighbor_region)
            
            
            chosen_subtract_region = possible_pill_lst[random.randint(0, len(possible_pill_lst) - 1)]
            
            
            # pillage combat-style
            points_pillaged = 0
            
            for x in range (0,2):
                highest_block_lst = combat.find_max_strength(chosen_subtract_region.blocks_present)
            
                if highest_block_lst:
                    block = highest_block_lst[0]
                    #strike once
                    block.get_hurt(1)
                    print(block.name + ' took one hit.')
                    points_pillaged+=1
                    
                    if block.is_dead():
                        print(block.name, 'goes to the pool')
                        if role == 'SCOTLAND':
                            board.eng_pool.append(block)
                            board.eng_roster.remove(block)
                            board.remove_from_region(block, chosen_subtract_region.regionID)
                        elif role == 'ENGLAND':
                            board.scot_pool.append(block)
                            board.scot_roster.remove(block)
                            board.remove_from_region(block, chosen_subtract_region.regionID)
                        
            
            
            
            #make a list of possible owned regions to gain points
            possible_add_lst = []
            new_list = []
            new_list.append(chosen_subtract_region.regionID)
            
            for neighbor_region in board.find_all_borders(new_list):
                if neighbor_region.is_friendly(role):
                    possible_add_lst.append(neighbor_region)
    
            #choose randomly from the list
            chosen_add_region = possible_add_lst[random.randint(0, len(possible_add_lst) - 1)]


            health_points = points_pillaged
        
            possible_add_block_list = []
            
            #list for possible blocks to heal in chosen_add_region
            for block in chosen_add_region.blocks_present:
                possible_add_block_list.append(block)
            
            while health_points > 0:

                block = possible_add_block_list[random.randint(0, len(possible_add_block_list) - 1)]
                healing_points = random.randint(0, health_points)
                block.heal_until_full(healing_points)
                health_points -= healing_points
                print(block.name + ' was healed ' + str(healing_points) + ' points.')
   
        else:
            print('There are no possible regions in which to play this card.')
        """
        
        #this is strategized, receives chosen region IDs from utility:
        region_to_pil_id = pil_data[0]
        region_to_heal_id = pil_data[1]
        region_to_pil = search.region_id_to_object(board, region_to_pil_id)
        region_to_heal = search.region_id_to_object(board, region_to_heal_id)
        
        #pillage combat style
        points_pillaged = 0
        good_list = True
        for block in region_to_pil.blocks_present:
            if block.current_strength > 0:
                good_list = True
            else:
                good_list = False
        for x in range (0,2):
            if len(region_to_pil.blocks_present) != 0 and good_list:
                highest_block_lst = combat.find_max_strength(region_to_pil.blocks_present)
            else:
                highest_block_lst = False

            if highest_block_lst:
                block = highest_block_lst[0]
                #strike once
                block.get_hurt(1)
                print(block.name + ' took one hit.')
                points_pillaged+=1
                
                if block.is_dead():
                    print(block.name + ' has been pillaged to death')
                    board.kill_block(block, role)
    
        #use weighted prob to choose blocks to add pts to
        #for block in blocks_present
        
        block_val_dict = dict()
            
            #list for possible blocks to heal in chosen_add_region
        for block in region_to_heal.blocks_present:
            utility_value = 0.0000000001
            if block.name == 'KING' and block.current_strength < block.attack_strength:
                utility_value += .5
                #if block is wallace and he needs it
            elif block.name == 'WALLACE' and block.current_strength < block.attack_strength:
                utility_value += .4
            #for england:
            #if block is edward and he needs it
            if block.name == 'EDWARD' and block.current_strength < block.attack_strength:
                utility_value += .45
            #if block is hobelars and he needs it
            elif block.name == 'HOBELARS' and block.current_strength < block.attack_strength:
                utility_value += .3
                
            #if block is type noble and he needs it
            elif type(block) == blocks.Noble and block.current_strength < block.attack_strength:
                utility_value += .25
            #if block is below full health
            elif block.current_strength < block.attack_strength:
                utility_value += .1
            
            block_val_dict[block.name] = utility_value
            
        #possible healing pts = # pts taken from other region
        health_points = points_pillaged
        
        while health_points > 0 and len(region_to_heal.blocks_present) > 0:

                #should i add something here so it doesn't choose the same blocks???
                block_name = weighted_prob.weighted_prob(block_val_dict)
                healing_points = random.randint(0, health_points)
                block.heal_until_full(healing_points)
                health_points -= healing_points
                print(block.name + ' was healed ' + str(healing_points) + ' points.')
                
        
    elif position == 'opp':
        quitt = False
        #loop through regions to make sure there is a region that it works in
        for region_controlled in board.get_controlled_regions(role):
            new_list = []
            new_list.append(region_controlled.regionID)
            for neighbor_region in board.find_all_borders(new_list):
                if not neighbor_region.is_friendly(role) and not neighbor_region.is_neutral():
                    possible = True
        
        if possible:
            
            #make a list of possible opponent regions to be pillaged 
            possible_pill_lst = []
            for region in board.get_controlled_regions(role):
                new_list = []
                new_list.append(region.regionID)
                for neighbor_region in board.find_all_borders(new_list):
                    if not neighbor_region.is_friendly(role) and not neighbor_region.is_neutral():
                        if not neighbor_region in possible_pill_lst:
                            possible_pill_lst.append(neighbor_region)
            
            print('Possible pillaging regions: ')
            for region in possible_pill_lst:
                print(region.name)
            
            
            valid_region = False
            
            while not valid_region:
                chosen_subtract_region_name = input('Which of your opponent\'s regions would you like to remove points from? Enter a name or \'none\'\n>').upper()
                
                if chosen_subtract_region_name.lower() == 'none':
                    quitt = True
                    valid_region = True
                
                if quitt:
                    valid_region = True
                else:
                    chosen_subtract_region = search.region_name_to_object(board, chosen_subtract_region_name)
                        
                    if chosen_subtract_region in possible_pill_lst:
                        valid_region = True
                        
                    else:
                        print('Invalid region.')
                        continue
            
                    # pillage combat-style
                    points_pillaged = 0
                    
                    for x in range (0,2):
                        highest_block_lst = combat.find_max_strength(chosen_subtract_region.blocks_present)
                    
                        if highest_block_lst:
                            block = highest_block_lst[0]
                            #strike once
                            block.get_hurt(1)
                            print(block.name + ' took one hit.')
                            points_pillaged+=1
                            
                            if block.is_dead():
                                board.kill_block(block, role)
                        
            
            
            
                    #make a list of possible owned regions to gain points
                    possible_add_lst = []
                    new_list = []
                    new_list.append(chosen_subtract_region.regionID)
                    
                    for neighbor_region in board.find_all_borders(new_list):
                        if neighbor_region.is_friendly(role):
                            possible_add_lst.append(neighbor_region)
                    
                    print('Possible regions to add pillaged points to: ')
                    for region in possible_add_lst:
                        print(region.name)
            
            
                    valid_region = False
                    
                    while not valid_region:
                        chosen_add_region_name = input('Which of your regions would you like to add pillaged points to? Enter a name or \'none\'\n>').upper()
                        
                        if chosen_add_region_name.lower() == 'none':
                            quitt = True
                            valid_region = True
                        
                        if not quitt:
                            chosen_add_region = search.region_name_to_object(board, chosen_add_region_name)
                                
                            if chosen_add_region in possible_add_lst:
                                valid_region = True
                                
                            else:
                                print('Invalid region.')
                                continue
            
            
                
            
                            health_points = points_pillaged
                        
                            possible_add_block_list = []
                            
                            while health_points > 0:
                                
                                #list for possible blocks to heal in chosen_add_region
                                for block in chosen_add_region.blocks_present:
                                    possible_add_block_list.append(block)
                                        
                                print('Possible blocks to heal: ')
                                for block in possible_add_block_list:
                                    print(block.name)
                                print()
                                
                                valid_input = False
                                
                                while not valid_input:
                                    
                                    print('You have ', health_points, ' health points.')
                                    block_name = input('Which block would you like to heal? Enter a name or \'none\'\n>').upper()
                                    
                                    if block_name.lower() == 'none':
                                        quitt = True
                                        valid_input = True
                                        health_points = 0
                                    #if player doesnt enter 'none'
                                    if not quitt:
                                        block = search.block_name_to_object(chosen_add_region.blocks_present, block_name)
                                        
                                        if block in possible_add_block_list:
                                            valid_input = True
                                        else:
                                            print('Invalid block.')
                                            continue
                                            

                                        valid_in = False
                                        while not valid_in:
                
                                            healing_points = input('How many points would you like to heal it? Enter an integer or \'none\'\n>')
                                            if healing_points.lower() == 'none':
                                                quitt = True
                                                valid_in = True
                                                
                                            if not quitt:
                                                if healing_points.isdigit():
                                                    healing_points = int(healing_points)
                                                    if healing_points <= 0 or healing_points > health_points:
                                                        print('You do not have that many healing points.')
                                                    else:
                                                        block.heal_until_full(healing_points)
                                                        health_points -= healing_points
                                                        print(block.name + ' was healed ' + str(healing_points) + ' points.')
                                                        valid_in = True
                                                else:
                                                    print('Invalid input.')

       
        else:
            print('There are no possible regions in which to play this card.')