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)
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.')