def smallestAngleBetween(): tester = Tester('smallestAngleBetween') twoPi = np.pi * 2 def truncate(num): return '%.4f' % (num) tester.compare( truncate(-twoPi * 2 / 6), truncate(mathHelper.smallestAngleBetween(twoPi * 1 / 6, twoPi * 5 / 6))) tester.compare( truncate(twoPi * 2 / 6), truncate(mathHelper.smallestAngleBetween(twoPi * 5 / 6, twoPi * 1 / 6))) tester.compare( truncate(twoPi * 1 / 6), truncate(mathHelper.smallestAngleBetween(twoPi * 1 / 6, twoPi * 2 / 6))) tester.compare( truncate(-twoPi * 1 / 6), truncate(mathHelper.smallestAngleBetween(twoPi * 2 / 6, twoPi * 1 / 6))) tester.compare( truncate(-twoPi * 3 / 6), truncate(mathHelper.smallestAngleBetween(twoPi * 2 / 6, twoPi * 5 / 6))) tester.compare( truncate(twoPi * 3 / 6), truncate(mathHelper.smallestAngleBetween(twoPi * 5 / 6, twoPi * 2 / 6)))
def smallestAngleBetween(): tester = Tester('smallestAngleBetween') twoPi = np.pi * 2 def truncate(num): return '%.4f'%(num) tester.compare(truncate(-twoPi*2/6), truncate(mathHelper.smallestAngleBetween(twoPi*1/6, twoPi*5/6))) tester.compare(truncate(twoPi*2/6), truncate(mathHelper.smallestAngleBetween(twoPi*5/6, twoPi*1/6))) tester.compare(truncate(twoPi*1/6), truncate(mathHelper.smallestAngleBetween(twoPi*1/6, twoPi*2/6))) tester.compare(truncate(-twoPi*1/6), truncate(mathHelper.smallestAngleBetween(twoPi*2/6, twoPi*1/6))) tester.compare(truncate(-twoPi*3/6), truncate(mathHelper.smallestAngleBetween(twoPi*2/6, twoPi*5/6))) tester.compare(truncate(twoPi*3/6), truncate(mathHelper.smallestAngleBetween(twoPi*5/6, twoPi*2/6)))
def offensivePositioning(self): correlationArr = [] myPredictedTanks = copy.deepcopy(self.myTanks) for myTank in myPredictedTanks: # Account for the predicted position myTank['actualPosition'] = myTank['position'] if 'predictedPosition' in myTank: myTank['position'] = myTank['predictedPosition'] for enTank in self.enemyTanks: tempCor = self.intp.correlationAtoB(myTank, enTank) if tempCor['distance'] > PROJECTILE_RANGE + self.intp.avgPeriod * enTank['speed'] * 3: tempCor['shootable'] = False else: tempCor['shootable'] = self.intp.isShotClear(myTank['position'], enTank['position']) tempCor['turretChange'] = mathHelper.smallestAngleBetween(myTank['turret'], tempCor['angle']) correlationArr.append(tempCor) # Sort the array, smallest abs angle chang first correlationArr = sorted(correlationArr, key=lambda entry:np.absolute(entry['turretChange'])) remainingAttackers = copy.deepcopy(self.myTankIds) usedAttackers = {} enemyAttacked = {} for entry in correlationArr: # Check that the enemy is shootable if entry['shootable']: # Check if attacking tank is available if entry['tankA']['id'] not in usedAttackers: # Check that enemy doesn't have too many attackers (max attackers = roundUp(remainingHeath/ProjDmg) + 1) if entry['tankB']['id'] not in enemyAttacked or enemyAttacked[entry['tankB']['id']] <= np.ceil(entry['tankB']['health'] / PROJECTILE_DAMAGE) + 1: # Check that attacker is actually close enough if entry['distance'] < PROJECTILE_RANGE + self.intp.avgPeriod * entry['tankB']['speed']: # assign the attaker to the enemy tank remainingAttackers.remove(entry['tankA']['id']) entry['targetId'] = entry['tankB']['id'] usedAttackers[entry['tankA']['id']] = entry if entry['tankB']['id'] in enemyAttacked: enemyAttacked[entry['tankB']['id']] += 1 else: enemyAttacked[entry['tankB']['id']] = 0 # assign any remaining attackers to enemies for attacker in remainingAttackers: # nobody to fire at so stop firinging self.comm.stop(myTank['id'], 'FIRE') # Find closest enemy via path finding and assign that enemy myCorrelations = [cor for cor in correlationArr if cor['tankA']['id'] == attacker] myCorrelations = sorted(myCorrelations, key=lambda entry:entry['distance']) for cor in myCorrelations: if cor['distance'] < PROJECTILE_RANGE + self.intp.avgPeriod * cor['tankB']['speed'] * 2: cor['targetId'] = cor['tankB']['id' ] usedAttackers[attacker] = cor else: break # find closest shootable friend and move somewhat close to them (like 30 away?) # Rotate turret appropriately for attacker in usedAttackers: # add predicitve factor to rotation angleToRotate = usedAttackers[attacker]['turretChange'] * self.predictionFactor self.comm.rotateTurret(attacker, angleToRotate) return
def offensivePositioning(self): correlationArr = [] myPredictedTanks = copy.deepcopy(self.myTanks) for myTank in myPredictedTanks: # Account for the predicted position myTank["actualPosition"] = myTank["position"] if "predictedPosition" in myTank: myTank["position"] = myTank["predictedPosition"] for enTank in self.enemyTanks: tempCor = self.intp.correlationAtoB(myTank, enTank) if tempCor["distance"] > PROJECTILE_RANGE + self.intp.avgPeriod * enTank["speed"] * 3: tempCor["shootable"] = False else: tempCor["shootable"] = self.intp.isShotClear(myTank["position"], enTank["position"]) tempCor["turretChange"] = mathHelper.smallestAngleBetween(myTank["turret"], tempCor["angle"]) correlationArr.append(tempCor) # Sort the array, smallest abs angle chang first correlationArr = sorted(correlationArr, key=lambda entry: np.absolute(entry["turretChange"])) remainingAttackers = copy.deepcopy(self.myTankIds) usedAttackers = {} enemyAttacked = {} for entry in correlationArr: # Check that the enemy is shootable if entry["shootable"]: # Check if attacking tank is available if entry["tankA"]["id"] not in usedAttackers: # Check that enemy doesn't have too many attackers (max attackers = roundUp(remainingHeath/ProjDmg) + 1) if ( entry["tankB"]["id"] not in enemyAttacked or enemyAttacked[entry["tankB"]["id"]] <= np.ceil(entry["tankB"]["health"] / PROJECTILE_DAMAGE) + 1 ): # Check that attacker is actually close enough if entry["distance"] < PROJECTILE_RANGE + self.intp.avgPeriod * entry["tankB"]["speed"]: # assign the attaker to the enemy tank remainingAttackers.remove(entry["tankA"]["id"]) entry["targetId"] = entry["tankB"]["id"] usedAttackers[entry["tankA"]["id"]] = entry if entry["tankB"]["id"] in enemyAttacked: enemyAttacked[entry["tankB"]["id"]] += 1 else: enemyAttacked[entry["tankB"]["id"]] = 0 # assign any remaining attackers to enemies for attacker in remainingAttackers: # nobody to fire at so stop firinging self.comm.stop(myTank["id"], "FIRE") # Find closest enemy via path finding and assign that enemy myCorrelations = [cor for cor in correlationArr if cor["tankA"]["id"] == attacker] myCorrelations = sorted(myCorrelations, key=lambda entry: entry["distance"]) for cor in myCorrelations: if cor["distance"] < PROJECTILE_RANGE + self.intp.avgPeriod * cor["tankB"]["speed"] * 2: cor["targetId"] = cor["tankB"]["id"] usedAttackers[attacker] = cor else: break # find closest shootable friend and move somewhat close to them (like 30 away?) # Rotate turret appropriately for attacker in usedAttackers: # add predicitve factor to rotation angleToRotate = usedAttackers[attacker]["turretChange"] * self.predictionFactor self.comm.rotateTurret(attacker, angleToRotate) return