def unit_roll(attacker_weak, defender_weak): if attacker_weak: return -2 elif defender_weak: return 2 else: return roll_random_between(0, 1)
def ai_best_attack(player_units, player_units_strengths, baddies, baddies_strengths, active_consumables): first_random = roll_random_float() players_tuple = zip(player_units, player_units_strengths, range(len(player_units))) best_units = [ ai_best_unit(baddies, baddies_strengths, player_unit, first_random, active_consumables, "enemy") + (i, ) for player_unit, strength, i in players_tuple if strength > 0 ] max_grade = max( [grade for baddie_index, grade, player_index in best_units]) best_pairings = [(baddie_index, grade, player_index) for baddie_index, grade, player_index in best_units if grade == max_grade and grade >= 0] if best_pairings: best_pairing = best_pairings[round( roll_random_between(0, len(best_pairings) - 1)) if len(best_pairings) > 1 else 0] #optional roll best_pairing = ( best_pairings[0][0], ) + best_pairing[1:] # bugged pairings print("best AI pairing method 1 (baddie, grade, friendly)", repr(best_pairing)) else: best_pairing = None, 0, None baddies_tuple = zip(baddies, baddies_strengths, range(len(baddies))) best_units_2 = [ ai_best_unit(player_units, player_units_strengths, baddie, first_random, active_consumables, "ally") + (i, ) for baddie, strength, i in baddies_tuple if strength > 0 ] max_grade_2 = max( [grade for player_index, grade, baddie_index in best_units_2]) best_players = [ player_index for player_index, grade, baddie_index in best_units_2 if grade == max_grade_2 ] if best_players: best_player = best_players[0] second_random = roll_random_float() best_pairing_2 = ai_best_unit( baddies, baddies_strengths, player_units[best_player], second_random, active_consumables, "enemy") + (best_player, ) print("best AI pairing method 2 (baddie, grade, friendly)", repr(best_pairing_2)) else: best_pairing_2 = None, 0, None #the poorer the better? if all units are poor against the best defender then select that one? ratio = best_pairing_2[1] / max_grade if max_grade > 0 else 0 third_random = roll_random_float() opposite_day = third_random < 0.2 if (ratio < 0.5 ) ^ opposite_day: # basically only if either method 1 or 2 is poor print("Using basic method 1", "opposite day", opposite_day) used_pairing = best_pairing else: print("Using method 2", "opposite day", opposite_day) used_pairing = best_pairing_2 return used_pairing
def assign_consumable_response(params): friendlies, friendly_strengths, baddies, baddie_strengths, active_consumables = init_battle( params) meta = {"newPVE": 0} targeted = False enemy_turn = False casting_ai = False consumables = lookup_items_by_type_and_subtype("consumable", "consumable") if params["code"] == "A0A": # Ally / merc damaged = any([ strength < get_unit_max_strength(unit, True) for unit, strength in zip(friendlies, friendly_strengths) ]) if params.get('name') == "-1": level = session["user_object"]["userInfo"]["player"][ "level"] + 5 #steele = player level + 5 else: level = 6 if params.get('name', '0')[0].isalpha(): merc = lookup_item_by_code(params["name"]) level = int(merc["level"]) else: for neighbor in session['user_object']["neighbors"]: if neighbor["uid"] == int(params.get('name', '0')): level = neighbor["level"] valid_consumables = [c for c in consumables if "-secondary" not in c and \ int(c.get("requiredLevel", "0")) <= level and \ (damaged or c["consumable"].get("-target") == 'enemy' or c["consumable"].get("-target") == 'enemy' or int(c["consumable"].get("-di","0")) >= 0) and \ 'requiredDate' not in c and \ c["consumable"].get("-allypower", "true") != "false"] if session['user_object']["userInfo"]["player"][ "tutorialProgress"] == 'tut_step_krunsch1AllyUsed': print("During tut_step_krunsch1AllyUsed: fixed N04 Air Strike") # only one occurrence of fixed allyConsumable uses an N04 valid_consumables = [lookup_item_by_code("N04")] selected_random_consumable_roll = roll_random_between( 0, len(valid_consumables) - 1) selected_random_consumable = round( selected_random_consumable_roll ) # required roll fixed allyconsumable in tutorialstep selected_consumable = valid_consumables[selected_random_consumable] handle_quest_progress(meta, progress_useAOA_consumable(selected_consumable)) elif params.get("name") == "AI": secondaries = [ get_unit_secondary(b) for b, i in zip(baddies, range(len(baddies))) if get_unit_secondary(b) is not None and not is_stunned( ("enemy", i), active_consumables) ] if len(secondaries) > 1: print("WARN: more that one secondary", repr(secondaries)) if not secondaries: print("ERROR: no secondary", repr(secondaries)) raise Exception("ERROR: no secondary", repr(secondaries)) selected_consumable = lookup_item_by_code(secondaries[0]) enemy_turn = True cast_chance = roll_random_float() cast_percent = float(selected_consumable["consumable"]["-castpercent"]) print(("Not c" if cast_chance >= cast_percent else "C") + "asting secondary power", cast_chance, ">=", cast_percent) selected_consumable = None #second targeted call will be made casting_ai = cast_chance < cast_percent #selected_consumable = None else: selected_consumable = lookup_item_by_code(params["code"]) targeted = True enemy_turn = is_affected_by_consumable( ("AI", None), {"consumable": {}}, active_consumables) handle_quest_progress( meta, progress_useGeneral_consumable(selected_consumable, enemy_turn)) # TODO: AI secondary abily Z-units if selected_consumable is not None: if selected_consumable["consumable"].get("-type") != "all": if (selected_consumable["consumable"].get("-target") == 'enemy') ^ enemy_turn: live_baddies_index = get_alive_unit_index(baddie_strengths) if targeted: targeted_baddie = int(params["id"]) #TODO enemy support heals, accuracy,... else: targeted_baddie = live_baddies_index[round( roll_random_between( 0, round(len(live_baddies_index) - 1)))] if len(live_baddies_index ) > 1 else live_baddies_index[0] apply_consumable_direct_impact(meta, selected_consumable, targeted_baddie, baddies, baddie_strengths, params, False, active_consumables) # session["battle"] = None` # handle_win(baddie_strengths, meta, {}) #TODO next map? # handle_loss() target = ('enemy', targeted_baddie) else: live_friendly_index = get_alive_unit_index(friendly_strengths) if targeted: targeted_friendly = int(params["id"]) elif enemy_turn: targeted_friendly = next( i for s, i in zip(friendly_strengths, range(len(friendly_strengths))) if s > 0 and not is_affected_by_consumable( ("ally", i), selected_consumable, active_consumables)) else: targeted_friendly = live_friendly_index[round( roll_random_between( 0, round(len(live_friendly_index) - 1)) )] if len( live_friendly_index) > 1 else live_friendly_index[0] apply_consumable_direct_impact(meta, selected_consumable, targeted_friendly, friendlies, friendly_strengths, params, True, active_consumables) target = ('ally', targeted_friendly) else: # TODO: more consumables # if consumable["consumable"].get("-type") == "all": print("Consumable", selected_consumable["-code"], selected_consumable["consumable"].get("-diweapon", ""), "affects all") if (selected_consumable["consumable"].get("-target") == 'enemy') ^ enemy_turn: for i in range(len(baddies)): apply_consumable_direct_impact(meta, selected_consumable, i, baddies, baddie_strengths, params, False, active_consumables) if not targeted and not enemy_turn and len( get_alive_unit_index(baddie_strengths)) > 1: roll_random_float() #required roll target = ('enemy', None) else: print("target allies") for i in range(len(friendlies)): apply_consumable_direct_impact(meta, selected_consumable, i, friendlies, friendly_strengths, params, True, active_consumables) if not targeted and not enemy_turn and len( get_alive_unit_index(friendly_strengths)) > 1: roll_random_float() target = ('ally', None) # for i in range(len(baddie_strengths)): # baddie_strengths[i] -= 15 # print("Baddie", i, "strength", baddie_strengths[i]) # if baddie_strengths[i] <= 0: # baddie_strengths[i] = 0 # print("Baddie", i, "down by consumable") if int(selected_consumable["consumable"].get("-duration", "0")) > 0: active_consumables.append( (selected_consumable, target, int(selected_consumable["consumable"].get("-duration", "0")))) if selected_consumable["-name"] == "consumable75": print(selected_consumable) defenseshield_activate(friendlies, active_consumables, selected_consumable) if targeted and enemy_turn: print("Consumable use ends enemy turn") process_consumable_end_turn(active_consumables, baddie_strengths, friendly_strengths, False) elif not enemy_turn: process_consumable_end_turn(active_consumables, baddie_strengths, friendly_strengths, True) handle_win(baddie_strengths, meta, params) handle_loss(friendly_strengths) report_battle_log(friendly_strengths, baddie_strengths, not enemy_turn, None, None, active_consumables) if targeted and enemy_turn: consume_consumables(active_consumables) if casting_ai: active_consumables.append(({"consumable": {}}, ("AI", None), -1)) assign_consumable_response = { "errorType": 0, "userId": 1, "metadata": meta, "data": [] } return assign_consumable_response