def NodeCost(self, node, dice): parent_cost = attack_succcess_probability(dice, node.dice) / 2 print("CALCULATED ATTACK SUCCESS PROBABILITY") print("CALCULATE DEFENDER NEIGHBOURS ATTACK SUCCESS PROBABILITY") children_prob = [] for neighboor_id in node.get_adjacent_areas(): neighboor = self.board.get_area(neighboor_id) if neighboor.get_owner_name() == self.player_name: print("IGNORE NEIGHBOURS OWNED BY PLAYER") continue child_dice = dice - 1 if child_dice == 1: print("CANT ATTACK WITH 1 DICE") break children_prob.append(attack_succcess_probability(dice - 1, neighboor.dice)) if len(children_prob) == 0: print("NO NEIGHBOURS => CORNER NODE => SAVE NODE") children_cost = 0.5 else: children_cost = sum(children_prob)/len(children_prob) / 2 print("CALCULATED DEFENDER NEIGHBOURS ATTACK SUCCESS PROBABILITY") cost = 100 - 100 * (parent_cost + children_cost) print("CALCULATED NODE COST {cost}, RANGE 0-100".format(cost=str(cost))) return cost
def expectiMin2(self, board, area, expectiMinLayers): values = [] area_dice = area.get_dice() for adjacent_area in self.possible_attacks_from_area( board, area, self.player_name): enemy_dice = adjacent_area.get_dice() if not adjacent_area.can_attack(): continue lose_prob = attack_succcess_probability(enemy_dice, area_dice) if lose_prob <= THRESHOLD: newBoard = self.updateBoardDefence( board, area, adjacent_area ) # ze na nas zautocili a vyhrali sme a s area nic nestane, oni budu mat get_dice() == 1 areaThatAttacked = newBoard.get_area(adjacent_area.get_name( )) # areaAttacked bude mat get_dice() == 1 kocku if expectiMinLayers == 0: expectiVal = self.expectiMax2(newBoard, area)[1] else: expectiVal = self.expectiMin2(newBoard, area, expectiMinLayers - 1) val = (1 - lose_prob) * expectiVal * areaThatAttacked.get_dice() values.append(val) else: # predpokladam, ze sme bitku prehrali, zobrali nam ho values.append(0.0001) return min(values) if values else 1.0
def expectiMin3(self, board, area): values = [] for adj in area.get_adjacent_areas(): adjacent_area = board.get_area(adj) if adjacent_area.get_owner_name() != self.player_name: enemy_dice = adjacent_area.get_dice() if enemy_dice == 1: continue lose_prob = attack_succcess_probability( enemy_dice, area.get_dice()) if lose_prob >= 0.2 or area.get_dice() == 8: newBoard = self.updateBoardDefence( board, area, adjacent_area ) # ze na nas zautocili a vyhrali sme a s area nic nestane, oni budu mat get_dice() == 1 areaThatAttacked = newBoard.get_area( adjacent_area.get_name() ) # areaAttacked bude mat get_dice() == 1 kocku val = (1 - lose_prob) * self.expectiMax3( newBoard, areaThatAttacked) * areaThatAttacked.get_dice() values.append(val) if not values: return 1.0 # tu by som mozno dal jednotku return min(values)
def expectiMax3(self, board, area): values = [] if area.get_dice() < 2: return 0.0 for target in self.possible_attacks_from_area(board, area, self.player_name): atk_power = area.get_dice() if atk_power < 2: continue attack_possibility_value = attack_succcess_probability( area.get_dice(), target.get_dice()) if attack_possibility_value >= 0.2 or atk_power == 8: newBoard = self.updateBoardAttack( board, area, target) # ze sme zautocili a vyhrali areaAttacked = newBoard.get_area(target.get_name( )) # areaAttacked bude mat get_dice() - 1 kociek val = attack_possibility_value * self.expectiMin3( newBoard, areaAttacked) * areaAttacked.get_dice() values.append(val) if not values: return 0.0 return max(values)
def battle_heuristic(board: Board, attacker: Area, target: Area) -> float: """Výpočet heuristiky potenciální bitvy heuristika = pst_úspěchu * koeficient(úspěch) - pst_prohry * koeficient(prohra) Args ---- board (Board): Aktuální stav herní plochy attacker (Area): Úzení ze kterého se útočí target (Area): Území na které se útočí Returns ------- float: Výsledná hodnota heuristiky. Větší znamená lepší. """ with simulate_battle(attacker, target, success=True): succ_coef = player_heuristic(board, attacker.get_owner_name()) with simulate_battle(attacker, target, success=False): fail_coef = player_heuristic(board, attacker.get_owner_name()) succ_prob = attack_succcess_probability(attacker.get_dice(), target.get_dice()) hold_prob = probability_of_holding_area(board, target.get_name(), attacker.get_dice()-1, attacker.get_owner_name()) # Pokus o přidání koeficientu pravděpodobnosti ztráty útočného pole v případě neúspěchu. # Toto nemělo žádný pozitivní výsledek na % výher. #fail_hold_prob = probability_of_holding_area(board, attacker.get_name(), 1, attacker.get_owner_name()) #return (hold_prob * succ_prob * succ_coef) - (2*(1 - fail_hold_prob) * (1 - succ_prob) * fail_coef) return (hold_prob * succ_prob * succ_coef) - ((1 - succ_prob) * fail_coef)
def MySearch(self, attacks): # Ignore - primitive riesenie self.bestMoveStack = [] for source, target in attacks: prob = attack_succcess_probability(source.dice, target.dice) if prob < 0.7: continue else: for neighboor_id in target.neighbours: neighboor = self.board.get_area(neighboor_id) prob2 = [] for neighboor2_id in neighboor.neighbours: neighboor2 = self.board.get_area(neighboor2_id) prob2.append(attack_succcess_probability(source.dice - 1, neighboor2.dice + 1)) if prob2[-1] > 0.7: break if prob2[-1] > 0.7: break if prob2[-1] > 0.7: break self.bestMoveStack.append((source, target))
def probability_of_holding_area(board, area_name, area_dice, player_name): """Copied over from AI utils, adapted for the server""" area = board.get_area_by_name(area_name) probability = 1.0 for adj in area.adjacent_areas_names: adjacent_area = board.get_area_by_name(adj) if adjacent_area.get_owner_name() != player_name: enemy_dice = adjacent_area.get_dice() if enemy_dice == 1: continue lose_prob = attack_succcess_probability(enemy_dice, area_dice) hold_prob = 1.0 - lose_prob probability *= hold_prob return probability
def get_features_client(board, atk_name, def_name): attacker = board.get_area(atk_name) defender = board.get_area(def_name) atk_owner = attacker.owner_name atk_1_neighbors = k_neighbors_client(board, 1, atk_name) atk_2_neighbors = k_neighbors_client(board, 2, atk_name) def_1_neighbors = k_neighbors_client(board, 1, def_name) def_2_neighbors = k_neighbors_client(board, 2, def_name) return ( ( # Inputs attacker.dice / 8, defender.dice / 8, attack_succcess_probability(attacker.dice, defender.dice), probability_of_holding_area_client(board, attacker.name, attacker.dice, atk_owner), probability_of_holding_area_client(board, attacker.name, 1, atk_owner), sum(area.dice for area in atk_1_neighbors if area.owner_name == atk_owner) / 100, sum(area.dice for area in atk_2_neighbors if area.owner_name == atk_owner) / 100, sum(area.dice for area in def_1_neighbors if area.owner_name != atk_owner) / 100, sum(area.dice for area in def_2_neighbors if area.owner_name != atk_owner) / 100, ), [ # Outputs 1, # Holding atk after N turns 1, # Holding def after N turns ], ( # Helper data atk_owner, attacker, defender, ), )
def expectiMax2(self, board, area): best_move = (None, 0.0) atk_power = area.get_dice() if not area.can_attack(): return best_move for target in self.possible_attacks_from_area(board, area, self.player_name): attack_possibility_value = attack_succcess_probability( atk_power, target.get_dice()) if attack_possibility_value >= THRESHOLD or atk_power == 8: newBoard = self.updateBoardAttack( board, area, target) # ze sme zautocili a vyhrali areaAttacked = newBoard.get_area(target.get_name( )) # areaAttacked bude mat get_dice() - 1 kociek val = attack_possibility_value * self.expectiMin2( newBoard, areaAttacked, self.playersCount) * areaAttacked.get_dice() if val > best_move[1]: best_move = (target.get_name(), val) return best_move