def canAshootB(self, tank1Id, tank2Id): tank1 = self.tanks[tank1Id] tank2 = self.tanks[tank2Id] ## Check if in range distance = mathHelper.distanceBetween(tank1['position'], tank2['position']) if (distance > PROJECTILE_RANGE + tank2['hitRadius']): return False ## Check that we are pointing at it angle = mathHelper.angleFromAToB(tank1['position'], tank2['position']) offset = math.asin(tank2['hitRadius']/distance) if (not mathHelper.angleInRange(tank1['turret'], angle + offset, angle - offset)): return False ## get the end point for tank1's range endPoint = mathHelper.getLineEndpoint(tank1['position'], distance, tank1['turret']) # Don't want to check if other tanks are blocking because they could move ## ## Check that no other tanks are in the way ## for tank in self.tanks: ## ## Don't consider the original 2 tanks ## if (tank['id'] == tank1Id or tank['id'] == tank2Id): ## continue ## if (mathHelper.circleOnLine(tank1['position'], endPoint, tank['position'], tank['hitRadius'])): ## return False ## Ensure path is clear of solids if self.isShotClear(tank1['position'], endPoint): return True return False
def canAshootB(self, tank1Id, tank2Id): tank1 = self.tanks[tank1Id] tank2 = self.tanks[tank2Id] ## Check if in range distance = mathHelper.distanceBetween(tank1["position"], tank2["position"]) if distance > PROJECTILE_RANGE + tank2["hitRadius"]: return False ## Check that we are pointing at it angle = mathHelper.angleFromAToB(tank1["position"], tank2["position"]) offset = math.asin(tank2["hitRadius"] / distance) if not mathHelper.angleInRange(tank1["turret"], angle + offset, angle - offset): return False ## get the end point for tank1's range endPoint = mathHelper.getLineEndpoint(tank1["position"], distance, tank1["turret"]) # Don't want to check if other tanks are blocking because they could move ## ## Check that no other tanks are in the way ## for tank in self.tanks: ## ## Don't consider the original 2 tanks ## if (tank['id'] == tank1Id or tank['id'] == tank2Id): ## continue ## if (mathHelper.circleOnLine(tank1['position'], endPoint, tank['position'], tank['hitRadius'])): ## return False ## Ensure path is clear of solids if self.isShotClear(tank1["position"], endPoint): return True return False
def correlationAtoB(self, tankA, tankB): result = { 'tankA': tankA, 'tankB': tankB } result['distance'] = mathHelper.distanceBetween(tankA['position'], tankB['position']) result['angle'] = mathHelper.angleFromAToB(tankA['position'], tankB['position']) return result
def getThreatsToA(self, tankA, enemyTanks): threats = [] for enTank in enemyTanks: ## Check if in dangerous range dangerousRange = PROJECTILE_RANGE + self.avgPeriod * enTank['speed'] * 1.1 distance = mathHelper.distanceBetween(tankA['position'], enTank['position']) if (distance < dangerousRange): ## Check if obstacles in the way if not self.isShotClear(tankA['position'], enTank['position']): threats.append({'tank': enTank, 'distance': distance}) return sorted(threats, key=lambda threat:threat['distance'])
def getThreatsToA(self, tankA, enemyTanks): threats = [] for enTank in enemyTanks: ## Check if in dangerous range dangerousRange = PROJECTILE_RANGE + self.avgPeriod * enTank["speed"] * 1.1 distance = mathHelper.distanceBetween(tankA["position"], enTank["position"]) if distance < dangerousRange: ## Check if obstacles in the way if not self.isShotClear(tankA["position"], enTank["position"]): threats.append({"tank": enTank, "distance": distance}) return sorted(threats, key=lambda threat: threat["distance"])
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"]
def correlationAtoB(self, tankA, tankB): result = {"tankA": tankA, "tankB": tankB} result["distance"] = mathHelper.distanceBetween(tankA["position"], tankB["position"]) result["angle"] = mathHelper.angleFromAToB(tankA["position"], tankB["position"]) return result