def whoWouldIShoot(self, tank1): target = False targetDistance = PROJECTILE_RANGE * 2 # Just put it at a ridiculous range to start # get the end point for tank1's range endPoint = mathHelper.getLineEndpoint(tank1['position'], PROJECTILE_RANGE, tank1['turret']) for tankId in self.tanks: tank = self.tanks[tankId] # Don't consider self if (tank['id'] == tank1['id']): continue distanceToIntersection = mathHelper.circleOnLine(tank1['position'], endPoint, tank['position'], tank['hitRadius']) if (distanceToIntersection != False and distanceToIntersection < targetDistance): targetDistance = distanceToIntersection target = tank if target == False: return False # Ensure path is clear of solids endPoint = mathHelper.getLineEndpoint(tank1['position'], targetDistance, tank1['turret']) if self.isShotClear(tank1['position'], endPoint): return target else: return False
def whoWouldIShoot(self, tank1): target = False targetDistance = PROJECTILE_RANGE * 2 # Just put it at a ridiculous range to start # get the end point for tank1's range endPoint = mathHelper.getLineEndpoint(tank1["position"], PROJECTILE_RANGE, tank1["turret"]) for tankId in self.tanks: tank = self.tanks[tankId] # Don't consider self if tank["id"] == tank1["id"]: continue distanceToIntersection = mathHelper.circleOnLine( tank1["position"], endPoint, tank["position"], tank["hitRadius"] ) if distanceToIntersection != False and distanceToIntersection < targetDistance: targetDistance = distanceToIntersection target = tank if target == False: return False # Ensure path is clear of solids endPoint = mathHelper.getLineEndpoint(tank1["position"], targetDistance, tank1["turret"]) if self.isShotClear(tank1["position"], endPoint): return target else: return False
def obstacleInWay(self, position, size): for terrain in self.mapTerrain: if mathHelper.rectOnCircle(terrain['boundingBox']['corner'], terrain['boundingBox']['size'], position, size): return True mapLeft = 0 mapRight = self.mapSize[0] mapBottom = 0 mapTop = self.mapSize[1] if mathHelper.circleOnLine([mapLeft,mapBottom], [mapLeft,mapTop], position, size): return True if mathHelper.circleOnLine([mapLeft,mapBottom], [mapRight,mapBottom], position, size): return True if mathHelper.circleOnLine([mapLeft,mapTop], [mapRight,mapTop], position, size): return True if mathHelper.circleOnLine([mapRight,mapBottom], [mapRight,mapTop], position, size): return True return False
def obstacleInWay(self, position, size): for terrain in self.mapTerrain: if mathHelper.rectOnCircle( terrain["boundingBox"]["corner"], terrain["boundingBox"]["size"], position, size ): return True mapLeft = 0 mapRight = self.mapSize[0] mapBottom = 0 mapTop = self.mapSize[1] if mathHelper.circleOnLine([mapLeft, mapBottom], [mapLeft, mapTop], position, size): return True if mathHelper.circleOnLine([mapLeft, mapBottom], [mapRight, mapBottom], position, size): return True if mathHelper.circleOnLine([mapLeft, mapTop], [mapRight, mapTop], position, size): return True if mathHelper.circleOnLine([mapRight, mapBottom], [mapRight, mapTop], position, size): return True return False
def circleOnLine(): ## Should return the distance to an intersection point if (mathHelper.circleOnLine([0,0],[10,0],[5,1],1) != 5): raise Exception('Failed circleOnLine') if (mathHelper.circleOnLine([0,5],[10,5],[5,5],1) != 4): raise Exception('Failed circleOnLine') if (mathHelper.circleOnLine([0,5],[10,5],[0,5],1) != 1): raise Exception('Failed circleOnLine') if (mathHelper.circleOnLine([0,5],[10,5],[10,5],1) != 9): raise Exception('Failed circleOnLine') ## Should return false if (not mathHelper.circleOnLine([4.5,12.5],[14.5,5.5],[12,9],1.414) == False): raise Exception('Failed circleOnLine') if (not mathHelper.circleOnLine([4.5,12.5],[14.5,5.5],[2,3],2) == False): raise Exception('Failed circleOnLine')
def circleOnLine(): ## Should return the distance to an intersection point if (mathHelper.circleOnLine([0, 0], [10, 0], [5, 1], 1) != 5): raise Exception('Failed circleOnLine') if (mathHelper.circleOnLine([0, 5], [10, 5], [5, 5], 1) != 4): raise Exception('Failed circleOnLine') if (mathHelper.circleOnLine([0, 5], [10, 5], [0, 5], 1) != 1): raise Exception('Failed circleOnLine') if (mathHelper.circleOnLine([0, 5], [10, 5], [10, 5], 1) != 9): raise Exception('Failed circleOnLine') ## Should return false if (not mathHelper.circleOnLine([4.5, 12.5], [14.5, 5.5], [12, 9], 1.414) == False): raise Exception('Failed circleOnLine') if (not mathHelper.circleOnLine([4.5, 12.5], [14.5, 5.5], [2, 3], 2) == False): raise Exception('Failed circleOnLine')
def evade(self): for myTank in self.myTanks: threatGrid = np.zeros(7) for i in range(7): if i == 0: newPosition = myTank['position'] else: angle = 2*np.pi*i/6 newPosition = mathHelper.getLineEndpoint(myTank['position'], 2*myTank['hitRadius'], angle) # TODO: Dodge enemy turrets enemyThreats = self.intp.getThreatsToA(myTank, self.enemyTanks) for enemyTank in enemyThreats: if self.intp.canAshootB(enemyTank['tank']['id'], myTank['id']): strikeDist = mathHelper.distanceBetween(myTank['position'], enemyTank['tank']['position']) strikeDist -= self.intp.avgPeriod * enemyTank['tank']['speed'] threatGrid[i] = max(1/strikeDist, threatGrid[i]) for projectile in self.intp.projectiles: A = projectile['position'] B = mathHelper.getLineEndpoint(A, projectile['range'], projectile['direction']) strikeDist = mathHelper.circleOnLine(A, B, newPosition, myTank['hitRadius']) if strikeDist != False: threatGrid[i] = max(1/strikeDist, threatGrid[i]) if self.intp.obstacleInWay(newPosition, myTank['collisionRadius']): threatGrid[i] = max(10, threatGrid[i]) i = np.argmin(threatGrid) #if self.tankPlans[myTank['id']]['lastThreat'] <= threatGrid[i]: # i = self.tankPlans[myTank['id']]['lasti'] #direction = 0 #myNewAngle = 0 #if i == self.tankPlans[myTank['id']]['lasti'] and i!= 0: # direction = self.tankPlans[myTank['id']]['lastDirection'] # self.comm.move(myTank['id'], direction, 2*myTank['hitRadius']) # predictedDist = self.intp.avgPeriod * myTank['speed'] # myTank['predictedPosition'] = mathHelper.getLineEndpoint(myTank['position'], predictedDist, self.tankPlans[myTank['id']]['lastAngle']) if i != 0: reqAngle = 2*np.pi*i/6 myAngle = myTank['tracks'] diff = myAngle - reqAngle rotationReq = np.arctan(np.sin(diff)/ np.cos(diff)) self.comm.rotateTank(myTank['id'], rotationReq) myNewAngle = myAngle+rotationReq if myNewAngle < 0: myNewAngle += 2*np.pi if myNewAngle > 2*np.pi: myNewAngle -= 2*np.pi if myNewAngle != reqAngle: direction = "REV" else: direction = "FWD" self.comm.move(myTank['id'], direction, 2*myTank['hitRadius']) predictedDist = self.intp.avgPeriod * myTank['speed'] myTank['predictedPosition'] = mathHelper.getLineEndpoint(myTank['position'], predictedDist, myNewAngle) else: myTank['predictedPosition'] = myTank['position']
def evade(self): for myTank in self.myTanks: threatGrid = np.zeros(7) for i in range(7): if i == 0: newPosition = myTank["position"] else: angle = 2 * np.pi * i / 6 newPosition = mathHelper.getLineEndpoint(myTank["position"], 2 * myTank["hitRadius"], angle) # TODO: Dodge enemy turrets enemyThreats = self.intp.getThreatsToA(myTank, self.enemyTanks) for enemyTank in enemyThreats: if self.intp.canAshootB(enemyTank["tank"]["id"], myTank["id"]): strikeDist = mathHelper.distanceBetween(myTank["position"], enemyTank["tank"]["position"]) strikeDist -= self.intp.avgPeriod * enemyTank["tank"]["speed"] threatGrid[i] = max(1 / strikeDist, threatGrid[i]) for projectile in self.intp.projectiles: A = projectile["position"] B = mathHelper.getLineEndpoint(A, projectile["range"], projectile["direction"]) strikeDist = mathHelper.circleOnLine(A, B, newPosition, myTank["hitRadius"]) if strikeDist != False: threatGrid[i] = max(1 / strikeDist, threatGrid[i]) if self.intp.obstacleInWay(newPosition, myTank["collisionRadius"]): threatGrid[i] = max(10, threatGrid[i]) i = np.argmin(threatGrid) # if self.tankPlans[myTank['id']]['lastThreat'] <= threatGrid[i]: # i = self.tankPlans[myTank['id']]['lasti'] # direction = 0 # myNewAngle = 0 # if i == self.tankPlans[myTank['id']]['lasti'] and i!= 0: # direction = self.tankPlans[myTank['id']]['lastDirection'] # self.comm.move(myTank['id'], direction, 2*myTank['hitRadius']) # predictedDist = self.intp.avgPeriod * myTank['speed'] # myTank['predictedPosition'] = mathHelper.getLineEndpoint(myTank['position'], predictedDist, self.tankPlans[myTank['id']]['lastAngle']) if i != 0: reqAngle = 2 * np.pi * i / 6 myAngle = myTank["tracks"] diff = myAngle - reqAngle rotationReq = np.arctan(np.sin(diff) / np.cos(diff)) self.comm.rotateTank(myTank["id"], rotationReq) myNewAngle = myAngle + rotationReq if myNewAngle < 0: myNewAngle += 2 * np.pi if myNewAngle > 2 * np.pi: myNewAngle -= 2 * np.pi if myNewAngle != reqAngle: direction = "REV" else: direction = "FWD" self.comm.move(myTank["id"], direction, 2 * myTank["hitRadius"]) predictedDist = self.intp.avgPeriod * myTank["speed"] myTank["predictedPosition"] = mathHelper.getLineEndpoint(myTank["position"], predictedDist, myNewAngle) else: myTank["predictedPosition"] = myTank["position"]