def useAtPosition(x, y, func): xDiff = selfX//ai.blockSize() - x yDiff = selfY//ai.blockSize() - y targetDirection = math.atan2(yDiff, xDiff) ai.turnToRad(targetDirection) func() sendMessage("teacherbot")
def aim(targetId): if targetId == 0: pass else: if not (angleDiff < 0.25 or angleDiff > 2*math.pi - 0.25): xDiff = ai.targetX(targetId) - ai.selfX() yDiff = ai.targetY(targetId) - ai.selfY() targetDirection = math.atan2(yDiff, xDiff) ai.turnToRad(targetDirection) angleDiff = abs(targetDirection - selfHeading)
def moveToPos(selfX, selfY, targetPositionPixels, stoppingDistance): deltaX = targetPositionPixels[0] - selfX deltaY = selfY - targetPositionPixels[1] targetDirection = (math.atan2(deltaY, deltaX)) distanceToTarget = math.sqrt((targetPositionPixels[0] - selfX)**2 + (targetPositionPixels[1] - selfY)**2) isBraking = distanceToTarget < stoppingDistance if not isBraking: ai.turnToRad(targetDirection) thrust(40) else: brake(2)
def collectAim(targetId): itemX = ai.itemX(targetId) itemY = ai.itemY(targetId) itemVelX = ai.itemVelX(targetId) itemVelY = ai.itemVelY(targetId) deltaPosX = itemX - selfX deltaPosY = itemY - ai.selfY() deltaVelX = itemVelX - selfVelX deltaVelY = itemVelY - selfVelY time = time_of_impact(deltaPosX, deltaPosY, itemVelX, itemVelY, 10) targetPosition = vector_sum((deltaPosX, deltaPosY), scalar_product((deltaVelX, deltaVelY), time)) targetDirection = math.atan2(targetPosition[1], targetPosition[0]) ai.turnToRad(targetDirection)
def brake(targetSpeed=2): if selfSpeed > targetSpeed: ai.turnToRad(selfTracking + math.pi) ai.thrust()
def aim(targetId): xDiff = ai.targetX(targetId) - ai.selfX() yDiff = ai.targetY(targetId) - ai.selfY() targetDirection = math.atan2(yDiff, xDiff) ai.turnToRad(targetDirection)
def tick(): # # The API won't print out exceptions, so we have to catch and print them ourselves. # try: # # Declare global variables so we have access to them in the function # global tickCount global mode # # Reset the state machine if we die. # if not ai.selfAlive(): tickCount = 0 mode = "ready" return tickCount += 1 # # Read some "sensors" into local variables, to avoid excessive calls to the API # and improve readability. # selfX = ai.selfX() selfY = ai.selfY() selfVelX = ai.selfVelX() selfVelY = ai.selfVelY() selfSpeed = ai.selfSpeed() shotSpeed = ai.getOption("shotSpeed") selfHeading = ai.selfHeadingRad() # 0-2pi, 0 in x direction, positive toward y # Add more sensors readings here print ("tick count:", tickCount, "mode", mode) def scalar_product(lis, n): return [x * n for x in lis] def vector_sum(list1, list2): return [sum(x) for x in zip(list1, list2)] # [a, b, c] [d, e, f] # [a,d] [b, e] [c, f] def time_of_impact(px, py, vx, vy, s): a = s * s - (vx * vx + vy * vy) b = px * vx + py * vy c = px * px + py * py d = b*b + a*c t = 0 # Time if d >= 0: t = (b + math.sqrt(d)) / a if (t < 0): t = 0 return t closest_asteroid_id = 0 if mode == "ready": #print("self vel Y: ", selfVelY) if ai.selfSpeed() > 7: # We're going too fast!!! mode = "brake" # Find closest asteroid if tickCount % 1 == 0: for i in range(ai.asteroidCountScreen()): #if not 130 <= ai.radarType(i) <= 133: # We're only looking for asteroids. # continue radar_dist = ai.asteroidDist(i) if radar_dist < ai.asteroidDist(closest_asteroid_id): closest_asteroid_id = i if ai.asteroidCountScreen() > 0: mode = "aim" if mode == "aim": asteroidX = ai.asteroidX(closest_asteroid_id) asteroidY = ai.asteroidY(closest_asteroid_id) asteroidVelX = ai.asteroidVelX(closest_asteroid_id) asteroidVelY = ai.asteroidVelY(closest_asteroid_id) if asteroidX - selfX > ai.mapWidthPixels()/1.2: print("Target is to the right. Seen to the left") dx = ai.mapWidthPixels() - asteroidX asteroidX = -dx #targetPosition[0] -= ai.mapWidthPixels() if selfX - asteroidX > ai.mapWidthPixels()/1.2: print("Target is to the left. Seen to the right") dx = asteroidX asteroidX = ai.mapWidthPixels() + dx #targetPosition[0] += ai.mapWidthPixels() if asteroidY - selfY > ai.mapHeightPixels()/1.2: print("Target is above. Seen below") dx = ai.mapHeightPixels() - asteroidY asteroidY = -dx #targetPosition[1] -= ai.mapHeightPixels() if selfY - asteroidY > ai.mapHeightPixels()/1.2: print("Target is below. Seen above.") dx = asteroidY asteroidY = ai.mapHeightPixels() + dy #targetPosition[1] += ai.mapHeightPixels() time = time_of_impact(asteroidX - selfX, asteroidY - selfY, asteroidVelX, asteroidVelY, shotSpeed) targetPosition = vector_sum((asteroidX - selfX, asteroidY - selfY), scalar_product((asteroidVelX, asteroidVelY), time*1.1)) print("Map size x: ", ai.mapWidthPixels()) targetAngle = math.atan2(targetPosition[1], targetPosition[0]) ai.turnToRad(targetAngle) if abs(selfHeading - targetAngle) % 2*math.pi < 0.8: print("Firing at", targetPosition[0], ",", targetPosition[1]) ai.fireShot() mode = "ready" if mode == "brake": velocityVector = (selfVelX, selfVelY) targetAngle = math.pi + (math.atan2(velocityVector[1], velocityVector[0])) # Negative velocity vector ai.turnToRad(targetAngle) ai.thrust() selfVel = velocityVector[0] * velocityVector[0] + velocityVector[1] * velocityVector[1] if selfVel < 3: # The bot has come to a stop. mode = "ready" except: print(traceback.print_exc())
def tick(): try: global tickCount global mode if not ai.selfAlive(): tickCount = 0 mode = "ready" return tickCount += 1 selfX = ai.selfX() selfY = ai.selfY() selfVelX = ai.selfVelX() selfVelY = ai.selfVelY() selfSpeed = ai.selfSpeed() tracking = ai.selfTrackingRad() selfHeading = ai.selfHeadingRad() message = ai.scanTalkMsg(0) mass = ai.selfMass() friction = ai.getOption("friction") thrustPower = ai.getPower() def scalar_product(lis, n): return [x * n for x in lis] def vector_sum(list1, list2): return [sum(x) for x in zip(list1, list2)] def time_of_impact(px, py, vx, vy, s): a = s * s - (vx * vx + vy * vy) b = px * vx + py * vy c = px * px + py * py d = b * b + a * c t = 0 # Time if d >= 0: t = (b + math.sqrt(d)) / a if (t < 0): t = 0 return t def stopping_distance(mass, friction, thrustPower, selfSpeed): fForce = friction * mass tForce = thrustPower accTot = ((fForce / mass) + (tForce / (mass + 5))) return ((selfSpeed * selfSpeed) / (2 * accTot)) stopping_distance = stopping_distance(mass, friction, thrustPower, selfSpeed) print("tick count:", tickCount, "mode", mode) if mode == "ready": print(friction, mass, selfSpeed, thrustPower) print(selfX, selfY) if "move-to" in message: splitmessage = message.split() action = splitmessage[0] if "move-to-stop" in action: mode = "move-to-stop" if "move-to-pass" in action: mode = "move-to-pass" if mode == "move-to-pass": splitmessage = message.split() coordX = float(splitmessage[1]) coordY = float(splitmessage[2]) print(coordX, coordY) distance = math.sqrt( abs(coordX - selfX)**2 + abs(coordY - selfY)**2) time = time_of_impact((coordX - selfX), (coordY - selfY), 0, 0, 10) targetDirection = (math.atan2(coordY - selfY, coordX - selfX)) print(targetDirection) if tracking == targetDirection: ai.thrust() else: ai.turnToRad(targetDirection) ai.thrust() if distance < 10: mode == "klar" if mode == "move-to-stop": splitmessage = message.split() coordX = int(splitmessage[1]) coordY = int(splitmessage[2]) print(coordX, coordY) distance = math.sqrt( abs(coordX - selfX)**2 + abs(coordY - selfY)**2) time = time_of_impact((coordX - selfX), (coordY - selfY), 0, 0, selfSpeed + 0.000001) target_position = vector_sum( (coordX - selfX, coordY - selfY), scalar_product((0 - selfVelX, 0 - selfVelY), time)) targetDirection = (math.atan2(target_position[1], target_position[0])) print(target_position) print(targetDirection) if tickCount % 2 == 0: if abs(tracking - targetDirection) > 0.01: ai.turnToRad(targetDirection) print("vinkel", (tracking - targetDirection), "tid", time) #if abs(targetDirection-tracking) > 0.03: # ai.thrust() #ai.thrust() # if tickCount % 2 == 0: #if selfSpeed < 30: ai.thrust() #if targetDirection-tracking < -0.1: # ai.turnRad(-(tracking-targetDirection)) # ai.thrust() #if targetDirection-tracking < 0.1: # ai.turnRad(-(tracking-targetDirection)) # ai.thrust() #if not tracking == targetDirection: # ai.turnToRad(targetDirection) # ai.thrust() # if distance < 10: # mode == "klar" # print("V", selfSpeed, "tP", thrustPower, "fr", friction, "M", mass) print(stopping_distance, distance) if stopping_distance > distance: mode = "brake" if mode == "brake": ai.turnToRad(tracking + math.pi) ai.thrust() print(selfX, selfY) splitmessage = message.split() coordX = int(splitmessage[1]) coordY = int(splitmessage[2]) distance = math.sqrt( abs(coordX - selfX)**2 + abs(coordY - selfY)**2) print(distance) if selfSpeed < 2: mode = "xD" if mode == "xD": print(selfX, selfY) splitmessage = message.split() coordX = int(splitmessage[1]) coordY = int(splitmessage[2]) distance = math.sqrt( abs(coordX - selfX)**2 + abs(coordY - selfY)**2) print(distance) except: print(traceback.print_exc())
def tick(): # # The API won't print out exceptions, so we have to catch and print them ourselves. # try: # # Declare global variables so we're allowed to use them in the function # global tickCount global mode global targetId # # Reset the state machine if we die. # if not ai.selfAlive(): tickCount = 0 mode = "aim" return tickCount += 1 # # Read some "sensors" into local variables to avoid excessive calls to the API # and improve readability. # selfX = ai.selfX() selfY = ai.selfY() selfHeading = ai.selfHeadingRad() # 0-2pi, 0 in x direction, positive toward y targetCount = ai.targetCountServer() targetCountAlive = 0 for i in range(targetCount): if ai.targetAlive(i): targetCountAlive += 1 # Use print statements for debugging, either here or further down in the code. # Useful functions: round(), math.degrees(), math.radians(), etc. # os.system('clear') clears the terminal screen, which can be useful. print("tick count:", tickCount, "mode:", mode, "heading:", round(math.degrees(selfHeading)), "targets alive:", targetCountAlive) if mode == "wait": if targetCountAlive > 0: mode = "aim" elif mode == "aim": if targetCountAlive == 0: mode = "wait" return # Loop through the indexes of targets and find one that is alive, # save that index in targetId. # useful variables: targetCount, targetId # useful functions: ai.targetAlive for i in range(targetCount): if ai.targetAlive(i): targetId = i # Calculate what direction the target is in, save in # the variable targetDirection # useful variables: selfX, selfY # useful functions: math.atan2, ai.targetX, ai.targetY xDiff = ai.targetX(targetId) - ai.selfX() yDiff = ai.targetY(targetId) - ai.selfY() targetDirection = math.atan2(yDiff, xDiff) # Turn to the direction of the target # useful variables: targetDirection # useful functions: ai.turnRad, ai.turnToRa # If the ship keeps oscillating between a few angles # it may be due to latency. Only turning every second # or third tick is a simple solution (use tickCount and %) # Check if you are aiming in the direction of the target, # if so, change mode to shoot. # Note that, due to how the game handles angles, the difference # cannot be 0 for many angles. # useful variables: selfHeading, targetDirection, mode # There is a function defined below called angleDiff that # is very useful as well. if angleDiff(selfHeading, targetDirection) < 0.1 and ai.targetAlive(targetId): mode = "shoot" else: if tickCount % 3 == 0: ai.turnToRad(targetDirection) elif mode == "shoot": # Shoot the target # useful functions: ai.fireShot # if the target is destroyed, change state to aim # useful variables: targetId, mode # useful functions: ai.targetAlive ai.fireShot() if not ai.targetAlive(targetId): mode = "aim" except: # # If tick crashes, print debugging information # print(traceback.print_exc())
def tick(): #NO EXCEPTION HANDLING try: #GLOBAL VARIABLES global tickCount global mode global item global itemId global lastItemCount global latestTask global mapWidth global mapHeight global maplist global finalPath global pathThread # Does not need to be global at the moment global searchForPath, searchQueue global selfVelX, selfVelY global selfSpeed global selfTracking global finalPosition #RESET IF DEAD if not ai.selfAlive(): tickCount = 0 #Create a clear function targetPos = [] finalPath = [] mode = "idle" return tickCount += 1 #SENSORS READINGS selfX = ai.selfX() selfY = (mapHeight * ai.blockSize()) - ai.selfY() selfVelX = ai.selfVelX() selfVelY = ai.selfVelY() selfSpeed = ai.selfSpeed() selfTracking = ai.selfTrackingRad() selfHeading = ai.selfHeadingRad() mass = ai.selfMass() friction = ai.getOption("friction") thrustPower = ai.getPower() mapWidth = ai.getOption("mapwidth") mapHeight = ai.getOption("mapheight") print ("tick count:", tickCount, "mode", mode) #IN THIS MODE WE ARE WAITING FOR THE PLAYER TO GIVE THE BOT INSTRUCTIONS if mode == "idle": mode, value = getMessage() if mode == "move": finalPosition = value elif mode == "collect": item = value #IN THIS MODE WE ARE CALUCLATING PATH USING ASTAR elif mode == "move": #GET PATH searchForPath = True searchQueue.put(searchForPath) try: finalPath = pathQueue.get(timeout=1) except queue.Empty: pass #if not finalPath: #print("CALCULATING PATH") #finalPath = getPath(pixelsToBlockSize(mapWidth, mapHeight), tuple(finalPosition), mapWidth, mapHeight) # else: #SEARCH print("final path", finalPath) if finalPath: print("I HAVE A FINAL PATH!") print("FINAL PATH: ", finalPath) searchForPath = False # We have now found a path searchQueue.put(searchForPath) print("Final Path:", finalPath) print("Player Pos:","(",selfY // ai.blockSize(), selfX // ai.blockSize(),")") targetPosition = finalPath[0] if finalPath[0][1] == selfX // ai.blockSize() and finalPath[0][0] == selfY // ai.blockSize(): if len(finalPath) > 1: finalPath = finalPath[1:] else: print("REACHED TARGETPOS") sendMessage("teacherbot") finalPosition = [] finalPath = [] mode = "idle" #MOVES if finalPath and finalPosition: print("I HAVE A FINAL POSITION!") stoppingDist = stopping_distance(mass, friction, thrustPower, selfSpeed) moveToPos(selfX, selfY, [targetPosition[1]*ai.blockSize(), targetPosition[0]*ai.blockSize()], stoppingDist) else: print("NO FINAL POSITION") #TODO: Search and destroy elif mode == "destroy": pass #TODO: Astar safe path elif mode == "refuel": fuelIndex = random.randint(0, ai.fuelstationCount()) refueling = False #GET FEULSTATION X AND Y POS finalxPosition = ai.fuelstationBlockX(fuelIndex) finalyPosition = mapHeight - ai.fuelstationBlockY(fuelIndex) finalxAndyPosition = [finalyPosition - 1, finalxPosition] targetPos = finalxAndyPosition mode = "move" #TODO: USE WITH ASTAR if refueling: '''Amount of fuel in station''' if ai.fuelstationFuel(fuelIndex) > 0: '''Keep calling to refuel''' ai.refuel() else: mode = "idle" '''Number of fueltanks on server''' #ai.tankCountServer() '''Number of fuelstations on server''' #ai.fuelstationCount() #IN THIS MODE WE ARE COLLECTING ITEMS elif mode == "collect": if ai.itemCountScreen() > 0: itemOnScreen = False for i in range(ai.itemCountScreen()): if ai.itemType(i) == item: itemId = i itemOnScreen = True break if not itemOnScreen: print("No item of type " + str(item) + " on screen") mode = "idle" itemX = ai.itemX(itemId) itemY = ai.itemY(itemId) itemVelX = ai.itemVelX(itemId) itemVelY = ai.itemVelY(itemId) deltaPosX = itemX - selfX deltaPosY = itemY - ai.selfY() deltaVelX = itemVelX - selfVelX deltaVelY = itemVelY - selfVelY time = time_of_impact(deltaPosX, deltaPosY, itemVelX, itemVelY, 10) targetPosition = vector_sum((deltaPosX, deltaPosY), scalar_product((deltaVelX, deltaVelY), time)) ai.turnToRad(math.atan2(targetPosition[1], targetPosition[0])) if selfSpeed < 10: thrust(10) else: brake(2) except: print(traceback.print_exc())
def tick(): # # The API won't print out exceptions, so we have to catch and print them ourselves. # try: # # Declare global variables so we have access to them in the function # global tickCount global mode global targetId global lis # # Reset the state machine if we die. # if not ai.selfAlive(): tickCount = 0 mode = "ready" return tickCount += 1 # # Read some "sensors" into local variables, to avoid excessive calls to the API # and improve readability. # selfX = ai.selfX() selfY = ai.selfY() selfVelX = ai.selfVelX() selfVelY = ai.selfVelY() selfSpeed = ai.selfSpeed() selfHeading = ai.selfHeadingRad() selfTracking = ai.selfTrackingRad() # 0-2pi, 0 in x direction, positive toward y # Add more sensors readings here print("tick count:", tickCount, "mode", mode) if mode == "ready": for i in range(4): if ai.targetAlive(i): targetId = i break xDiff = ai.targetX(targetId) - ai.selfX() yDiff = ai.targetY(targetId) - ai.selfY() targetDirection = math.atan2(yDiff, xDiff) ai.turnToRad(targetDirection) ai.setPower(20) if selfSpeed < 20: ai.thrust() if xDiff < 400 and yDiff < 400: mode = "brake" if abs(selfHeading - selfTracking) > 0.1 and selfSpeed > 20: mode = "stab" elif mode == "stab": if selfSpeed < 2: mode = "ready" else: ai.setPower(50) ai.turnToRad(math.pi + ai.selfTrackingRad()) ai.thrust() elif mode == "brake": if selfSpeed < 2: mode = "aim" else: ai.setPower(50) ai.turnToRad(math.pi + ai.selfTrackingRad()) ai.thrust() elif mode == "aim": xDiff = ai.targetX(targetId) - ai.selfX() yDiff = ai.targetY(targetId) - ai.selfY() targetDirection = math.atan2(yDiff, xDiff) ai.turnToRad(targetDirection) angleDiff = abs(targetDirection - selfHeading) if angleDiff < 0.25 or angleDiff > 2 * math.pi - 0.25: mode = "shoot" elif mode == "shoot": ai.fireShot() xDiff = ai.targetX(targetId) - ai.selfX() yDiff = ai.targetY(targetId) - ai.selfY() targetDirection = math.atan2(yDiff, xDiff) ai.turnToRad(targetDirection) if not ai.targetAlive(targetId): mode = "ready" except: print(traceback.print_exc())