import sys import math import random #---SOME INIT CODE--- random.seed() #-------------------- #---GAME INPUT--- busters_per_player = int(input()) ghost_count = int(input()) my_team_id = int(input()) #---------------- #---CONSTANT--- tile_size = 500 nx_tile = math.floor(16000/tile_size)+1 ny_tile = math.floor(9000/tile_size)+1 radius_search = 25 base_pos = [{"x":0,"y":0},{"x":16000,"y":9000}] if my_team_id: enemy_team_id = 0 else: enemy_team_id = 1 #-------------- #---ENV INFORMATION--- exploring_map = [[0 for i in range(ny_tile)] for j in range(nx_tile)] intercept_plan = [] #Plan ton intercept enemy with ghost help_plan = [] #plan to help capturing a ghost rescue_plan = [] #plan to rescue buster taht is escaping ghost_plan = [] #plan to catch ghost stun_reload = [0]*busters_per_player*2 ghost_status = [100]*ghost_count n_captured_ghost = 0 tick_counter = 0 my_score = 0 #-------------------- #---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #-------------FUNCTION------------------------------------------------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- def distance(x1, y1, x2, y2): delta_x = abs(x2 - x1) delta_y = abs(y2 - y1) return math.sqrt(pow(delta_x,2) + pow(delta_y,2)) def get_tile_pos(x,y): tile_x = math.floor(x/tile_size) tile_y = math.floor(y/tile_size) return {"x":tile_x,"y":tile_y} #Vector unit from 1 to 2 def vector_unit(x1,y1,x2,y2): dist = distance(x1,y1,x2,y2) if not dist: return {"x":0,"y":0} x_vector = (x2-x1)/dist y_vector = (y2-y1)/dist return {"x":x_vector,"y":y_vector} def get_near_entity(x,y,ghost_nfo,enemy_nfo,buster_nfo,radius): near_entity = {"ghost":[],"enemy":[],"friend":[]} for entity in ghost_nfo: if distance(x,y,entity["x"],entity["y"]) < radius: near_entity["ghost"].append(entity) for entity in enemy_nfo: if distance(x,y,entity["x"],entity["y"]) < radius: near_entity["enemy"].append(entity) for entity in buster_nfo: if distance(x,y,entity["x"],entity["y"]) < radius: near_entity["friend"].append(entity) return near_entity def update_info(ghost_nfo,enemy_nfo,buster_nfo): #-------------------- #---GENERAL UPDATE--- global tick_counter tick_counter += 1 #-------------------- #------------------------- #---UPDATE GHOST STATUS--- global n_captured_ghost,ghost_status #update hp for ghost in ghost_nfo: ghost_status[ghost["id"]] = ghost["state"] - ghost["value"] #update my caught for buster in buster_nfo: if buster["state"] == 1: ghost_status[buster["value"]] = 0 #update enemy caught for buster in enemy_nfo: if buster["state"] == 1: ghost_status[buster["value"]] = 0 n_captured_ghost = len([x for x in ghost_status if x <= 1]) #----------------------- #----------------- #---STUN RELOAD--- global stun_reload #detect enemy use stun last turn for buster in buster_nfo: if buster["value"] == 10: #enemy with stun possible and close enought closer_enemy = [enemy for enemy in enemy_nfo_memory if distance(buster["x"],buster["y"],enemy["x"],enemy["y"]) <= 1760+2*800 and stun_reload[enemy["id"]] < 1] if closer_enemy: closer_enemy.sort(key = lambda enemy:distance(buster["x"],buster["y"],enemy["x"],enemy["y"])) stun_reload[closer_enemy[0]["id"]] = 20 #decrease reload time for i in range(2*busters_per_player): stun_reload[i] -= 1 if stun_reload[i] < 0: stun_reload[i] = 0 #------------------ #-------------------------- #---UDPATE EXPLORING MAP--- global exploring_map #Each value mean a state : # 0-> never explored # -1-> no ghost # perhaps add other state later for buster in buster_nfo: visible_entity = get_near_entity(buster["x"], buster["y"], ghost_nfo, enemy_nfo, buster_nfo, 2200) buster_tile = get_tile_pos(buster["x"],buster["y"]) if not visible_entity["ghost"]: for i in range(-3,3): for j in range(-3,3): if buster_tile["x"] + i >= 0 and buster_tile["x"] + i < nx_tile and buster_tile["x"] + i >= 0 and buster_tile["x"] + i < nx_tile: exploring_map[buster_tile["x"]+i][buster_tile["y"]+j] = -1 #-------------------------- def prepare_plan(ghost_nfo,enemy_nfo,buster_nfo): #-------------------- #---INTERCEPT PLAN--- NEED TO BE IMPROVED global intercept_plan intercept_factor = 1/4 intercept_factor1 = 3/4 intercept_factor2 = 1/2 for enemy in enemy_nfo: if intercept_plan: #remove plan for same id intercept_plan = [plan for plan in intercept_plan if plan["id"] != enemy["id"]] if enemy["state"] == 1 and enemy["id"] not in current_target: enemy_vector = vector_unit(enemy["x"],enemy["y"],base_pos[enemy_team_id]["x"],base_pos[enemy_team_id]["y"]) dist_to_base = distance(enemy["x"],enemy["y"],base_pos[enemy_team_id]["x"],base_pos[enemy_team_id]["y"]) if dist_to_base > 3500: intercept_plan.append({"x":math.floor(enemy["x"]+enemy_vector["x"]*dist_to_base*intercept_factor),"y":math.floor(enemy["y"]+enemy_vector["y"]*dist_to_base*intercept_factor),"tick":math.floor(tick_counter+dist_to_base*intercept_factor/800), "id":enemy["id"]}) intercept_plan.append({"x":math.floor(enemy["x"]+enemy_vector["x"]*dist_to_base*intercept_factor1),"y":math.floor(enemy["y"]+enemy_vector["y"]*dist_to_base*intercept_factor1),"tick":math.floor(tick_counter+dist_to_base*intercept_factor1/800), "id":enemy["id"]}) intercept_plan.append({"x":math.floor(enemy["x"]+enemy_vector["x"]*dist_to_base*intercept_factor2),"y":math.floor(enemy["y"]+enemy_vector["y"]*dist_to_base*intercept_factor2),"tick":math.floor(tick_counter+dist_to_base*intercept_factor2/800), "id":enemy["id"]}) #Remove plan outpass intercept_plan = [item for item in intercept_plan if item["tick"] > tick_counter] #------------------- #---------------- #---GHOST PLAN--- TO COMPLETE global ghost_plan for ghost in ghost_nfo: if ghost_plan: #remove plan for same id ghost_plan = [plan for plan in ghost_plan if plan["id"] != ghost["id"]] #Remove plan outpass ghost_plan = [plan for plan in intercept_plan if plan["tick"] > tick_counter] #---------------- #----------------- #---RESCUE PLAN--- TO COMPLETE global rescue_plan for buster in buster_nfo: if rescue_plan: #remove plan for same id rescue_plan = [plan for plan in rescue_plan if plan["id"] != buster["id"]] #Remove plan outpass rescue_plan = [plan for plan in rescue_plan if plan["tick"] > tick_counter] #----------------- def printmap(map_): for line in map_: str_ = "" for p in line: if p == -float("inf"): str_ += "-inf" else: str_ += str(math.floor(p)) + ":" print(str_,file=sys.stderr) #---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- #-------------GAME LOOP------------------------------------------------------------------------------------------------------------------------------------------------------------------ #---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- while True: #------------------------ #---INIT VAR FOR ROUND--- enemy_nfo_memory = enemy_nfo buster_nfo = [] ghost_nfo = [] enemy_nfo = [] current_target = [] #------------------------ #------------------------- #---GET ENV INFORMATION--- entities = int(input()) # the number of busters and ghosts visible to you for i in range(entities): # entity_id: buster id or ghost id # y: position of this buster / ghost # entity_type: the team id if it is a buster, -1 if it is a ghost. # state: For busters: 0=idle, 1=carrying a ghost. # value: For busters: Ghost id being carried. For ghosts: number of busters attempting to trap this ghost. entity_id, x, y, entity_type, state, value = [int(j) for j in input().split()] if entity_type == my_team_id: buster_nfo.append({"id":entity_id, "x":x, "y":y, "state":state, "value":value}) elif entity_type == -1 : ghost_nfo.append({"id":entity_id, "x":x, "y":y, "state":state, "value":value}) else: enemy_nfo.append({"id":entity_id, "x":x, "y":y, "state":state, "value":value}) #------------------------- #--------------------------------- #---UPDATE AND PRINT INFOMATION--- update_info(ghost_nfo, enemy_nfo, buster_nfo) prepare_plan(ghost_nfo, enemy_nfo, buster_nfo) print("General Info tick = "+str(tick_counter),file=sys.stderr) print("Interception plans :",file=sys.stderr) print(intercept_plan,file=sys.stderr) print("Help plans :",file=sys.stderr) print(help_plan,file=sys.stderr) print("Ghost plans :",file=sys.stderr) print(ghost_plan,file=sys.stderr) print("Search radius = "+str(radius_search),file=sys.stderr) print("Stun reload : ",file=sys.stderr) print(stun_reload,file=sys.stderr) print("Ghost status : ",file=sys.stderr) print(ghost_status,file=sys.stderr) print("Captured Ghost = "+str(my_score),file=sys.stderr) print("Buster nfo : ",file=sys.stderr) print(buster_nfo,file=sys.stderr) print("Enemy nfo : ",file=sys.stderr) print(enemy_nfo,file=sys.stderr) print("Ghost nfo : ",file=sys.stderr) print(ghost_nfo,file=sys.stderr) printmap(exploring_map) #---------------------------------- #------------------------------------------------------------------------------------------------------------------------------------------------------ #---ACTION FOR EACH BUSTER----------------------------------------------------------------------------------------------------------------------------- for buster in buster_nfo: #-------------- #---INIT VAR--- command = "" tile_buster = get_tile_pos(buster["x"],buster["y"]) visible_entity = get_near_entity(buster["x"], buster["y"], ghost_nfo, enemy_nfo, buster_nfo, 2200) targetable_entity = get_near_entity(buster["x"], buster["y"], ghost_nfo, enemy_nfo, buster_nfo, 1760) enemy_threat = [enemy for enemy in enemy_nfo if enemy["state"] != 2 and stun_reload[enemy["id"]] <= 2 and distance(enemy["x"],enemy["y"],buster["x"],buster["y"]) < 3200] enemy_threat.sort(key = lambda enemy:distance(enemy["x"],enemy["y"],buster["x"],buster["y"])) #-------------- #------------------------ #---BUSTER CARRY GHOST--- if buster["state"] == 1 and not command: #----------------------- #---CAN RELEASE GHOST--- if distance(base_pos[my_team_id]["x"], base_pos[my_team_id]["y"], buster["x"], buster["y"]) < 1600: command = "RELEASE" + " RELEASE" my_score += 1 #----------------------- #----------------- #---CLOSE THREAT--- TO COMPLETE if enemy_threat and not command enemy_target = enemy_threat[0] dist = distance(enemy_target["x"],enemy_target["y"],buster["x"],buster["y"]) if dist > 1760: #TRY ESCAPE, IF NO WAY -> FIGHT BACK, IF CAN'T FIGHT BACK MOVE HOME #COULD ALSO TRY TO RELEASE THEN STUN IF DIST < 1760+800 (you won't move, h'll come to you, h'll bust or stun and you w'll stun else: if not stun_reload[buster["id"]]: #fight else: command = "MOVE " + str(base_pos[my_team_id]["x"]) + " " + str(base_pos[my_team_id]["y"]) + " HOME 0x17D" #FIGHT BACK or MOVE HOME (in all case you're stun next turn) #----------------- #-------------------- #---END GAME TRICK--- if my_score*2 >= ghost_count - 1 and tick_counter > 170 and not command: if enemy_nfo and distance(buster["x"],buster["y"],base_pos[enemy_team_id]["x"],base_pos[enemy_team_id]["x"]) < 8000: enemy_nfo.sort(key = lambda enemy:distance(enemy["x"],enemy["y"],buster["x"],buster["y"])) vector_away = vector_unit(enemy_nfo[0]["x"],enemy_nfo[0]["y"], buster["x"], buster["y"] ) command = "MOVE "+str(math.floor(buster["x"]+vector_away["x"]*2000))+" "+str(math.floor(buster["y"]+vector_away["y"]*2000))+" ESCAPE 0x24F" else : if my_team_id: command = "MOVE 16000 0 WIN" else: command = "MOVE 0 9000 WIN" #-------------------- #-------------------------- #---NO ENEMY -> GET BASE--- if not command: command = "MOVE " + str(base_pos[my_team_id]["x"]) + " " + str(base_pos[my_team_id]["y"]) + " HOME 0x52F" #-------------------------- #------------------------ #-------------------- #---BUSTER IS STUN--- if buster["state"] == 2 and not command: command = "MOVE 0 0 X" #-------------------- #------------------- #---ENEMY VISIBLE--- if visible_entity["enemy"] and stun_reload[buster["id"]] <= 2 and not command: #Priority on attack to enemy with ghost enemy_with_ghost = [enemy for enemy in visible_entity["enemy"] if enemy["state"] == 1] enemy_with_ghost.sort(key = lambda enemy:distance(buster["x"],buster["y"],enemy["x"],enemy["y"])) for enemy in enemy_with_ghost: dist_enemy = distance(buster["x"],buster["y"],enemy["x"],enemy["y"]) #Can attack this turn if dist_enemy < 1760 and not stun_reload[buster["id"]] and not command and enemy["id"] not in current_target and enemy["state"] != 2: command = "STUN "+str(enemy["id"])+" ATTACK 0x93C" stun_reload[buster["id"]] = 20 current_target.append(enemy["id"]) break #Can attack next turn elif not command and enemy["id"] not in current_target and stun_reload[buster["id"]] <= 2: vector_to_base = vector_unit(enemy["x"],enemy["y"],base_pos[enemy_team_id]["x"],base_pos[enemy_team_id]["y"]) next_pos_enemy = {"x":math.floor(enemy["x"]+vector_to_base["x"]*800),"y":math.floor(enemy["y"]+vector_to_base["y"]*800)} #If next pos is at distance that i will be able to attack if distance(buster["x"],buster["y"],next_pos_enemy["x"],next_pos_enemy["y"]) < 1760+800: command = "MOVE "+str(next_pos_enemy["x"]) + " "+str(next_pos_enemy["y"]) + " INTERCEPT 0x23A" #If there is ghost near_by, prepare a prevent attack if near_entity["ghost"]: near_ghost = near_entity["ghost"] near_ghost.sort(key=lambda x:x["state"]) target_ghost = near_ghost[0] #Celui qui a le moins de vie tile_ghost = get_tile_pos(target_ghost["x"],target_ghost["y"]) dist_ghost = distance(buster["x"],buster["y"],target_ghost["x"],target_ghost["y"]) #If nearer ghost soon dead and enemy near and can stun if target_ghost["state"] < 2 + target_ghost["value"]*4 and not stun_reload[buster["id"]] and not command: for enemy in near_entity["enemy"]: dist_enemy = distance(buster["x"],buster["y"],enemy["x"],enemy["y"]) if dist_enemy < 1760 and enemy["id"] not in current_target and enemy["state"] != 2: command = "STUN "+str(enemy["id"])+" PREVENT 0x83B" stun_reload[buster["id"]] = 20 current_target.append(enemy["id"]) break #------------------- #---------------- #---CHECK PLAN--- if not command: YOLO #---------------- #----------------- #---EXPLORE MAP--- if not command: YOLO #----------------- #------------------ #---SEND COMMAND--- if not command : print("MOVE 8000 4500 ?") else : print(command) #------------------ #------------------------------------------------------------------------------------------------------------------------------------------------------
Run
Reset
Share
Import
Link
Embed
Language▼
English
中文
Python Fiddle
Python Cloud IDE
Follow @python_fiddle
Browser Version Not Supported
Due to Python Fiddle's reliance on advanced JavaScript techniques, older browsers might have problems running it correctly. Please download the latest version of your favourite browser.
Chrome 10+
Firefox 4+
Safari 5+
IE 10+
Let me try anyway!
url:
Go
Python Snippet
Stackoverflow Question