def tick(self): self.parseCombatEvents() if(self.timeToRespawn < self.game.match.timeToNextRespawn ): self.numEnemies = len(self.game.bots_alive) self.timeToRespawn = self.game.match.timeToNextRespawn for bot in self.game.team.members: if bot.health <= 0: self.myAttackers.discard(bot) self.myDefenders.discard(bot) self.facingAttackers.pop(bot, None) for bot in self.game.bots_available: if bot in self.myDefenders or ((len(self.myDefenders)<self.maxDefenders) and len(self.myDefenders) <= self.numEnemies): distanceToHomeFlag = Vector2.distance(bot.position,self.game.team.flagSpawnLocation) distanceToEnemyFlag = Vector2.distance(bot.position, self.game.enemyTeam.flagSpawnLocation) if distanceToEnemyFlag > distanceToHomeFlag or len(self.myAttackers) >= 3: self.goDefend(bot) else: self.goAttack(bot) else: self.goAttack(bot) for bot in self.game.bots_alive: if bot.state == bot.STATE_SHOOTING: continue if bot.state == bot.STATE_TAKINGORDERS: continue if bot.state == bot.STATE_DEFENDING and bot.flag : self.goAttack(bot) continue if (bot in self.myDefenders): self.defenseTick(bot) if (bot in self.myAttackers): self.attackTick(bot)
def attackCloseEnemy(self, bot): closestEnemy = self.closestEnemy(bot) if closestEnemy is not None and not self.isInsideSpawn(closestEnemy): if bot.flag: enemyDistanceFromHome = Vector2.distance(closestEnemy.position,self.game.team.flagScoreLocation) botDistanceFromHome = Vector2.distance(bot.position,self.game.team.flagScoreLocation) if closestEnemy in bot.seenBy or enemyDistanceFromHome > botDistanceFromHome: return False enemyDistance = Vector2.distance(closestEnemy.position,bot.position) if closestEnemy.state == closestEnemy.STATE_DEFENDING and closestEnemy in bot.seenBy: if enemyDistance < self.level.firingDistance*1.4 and enemyDistance > self.level.firingDistance: enemyDir = (closestEnemy.position - bot.position).normalized() perpendicular = enemyDir.perpendicular().normalized() flank = bot.position + enemyDir*2 + perpendicular*6*self.isLeftOf(bot,closestEnemy) flank = self.level.findNearestFreePosition(flank) if flank is not None: if self.lastCommand[bot] != 'attack defender' or Vector2.distance(bot.position,self.lastTarget[bot])<self.level.characterRadius: self.issueAndStore(commands.Attack, bot, flank,closestEnemy.position, description = 'attack defender') return True if enemyDistance < self.level.firingDistance*1.7 and bot.state in [bot.STATE_MOVING,bot.STATE_IDLE,bot.STATE_CHARGING]: if bot.state is bot.STATE_CHARGING and enemyDistance <= self.level.firingDistance: return False if closestEnemy.state in [closestEnemy.STATE_DEFENDING,closestEnemy.STATE_IDLE,closestEnemy.STATE_TAKINGORDERS]: self.issueAndStore(commands.Attack, bot, closestEnemy.position,closestEnemy.position, description = 'attack close enemy') else: self.issueAndStore(commands.Attack, bot, self.getPositionInFrontOf(closestEnemy),self.getPositionInFrontOf(closestEnemy), description = 'attack close enemy') return True return False return False
def goAttack(self, bot): self.myAttackers.add(bot) self.myDefenders.discard(bot) self.resetDefenders() distanceToHomeFlag = Vector2.distance(bot.position,self.game.team.flagSpawnLocation) distanceToEnemyFlag = Vector2.distance(bot.position, self.game.enemyTeam.flagSpawnLocation) enemyFlagSpawn = self.game.enemyTeam.flagSpawnLocation enemyFlag = self.game.enemyTeam.flag.position if not self.attackCloseEnemy(bot): if bot.flag: # Tell the flag carrier to run home! target = self.game.team.flagScoreLocation self.issueAndStore(commands.Move, bot, target, description = 'running home') else: if self.game.enemyTeam.flag.carrier == None: if distanceToEnemyFlag > self.level.firingDistance*1.6: pos1 = self.attackPositions[0] self.attackPositions = self.attackPositions[1:] + [self.attackPositions[0]] pos2 = self.attackPositions[0] self.attackPositions = self.attackPositions[1:] + [self.attackPositions[0]] position = min([pos1,pos2], key=lambda x:Vector2.distance(bot.position,x)) position = self.level.findNearestFreePosition(position) self.issueAndStore(commands.Charge, bot, position, description = 'charge to attack position') else: self.issueAndStore(commands.Charge, bot, enemyFlag,enemyFlag, description = 'Charge enemy flag') else: if distanceToEnemyFlag <= self.level.characterRadius: faceSpawn1 = self.game.enemyTeam.botSpawnArea[0]-bot.position faceSpawn2 = self.game.enemyTeam.botSpawnArea[1]-bot.position faceMiddle = Vector2(self.level.width/2,self.level.height/2)-bot.position faceDirs = [faceSpawn1,faceMiddle] self.issueAndStore(commands.Defend, bot, faceDirs, description = 'defend enemy flag') else: self.issueAndStore(commands.Charge, bot, enemyFlagSpawn, description = 'charge to enemy flagSpawn')
def isVisibleFrom(self, pos1, pos2): if Vector2.distance(pos1,pos2) > self.level.firingDistance: return False point = pos1 dir = (pos2 - pos1).normalized() if self.level.blockHeights[int(point.x)][int(point.y)] > 1: point = point + dir while Vector2.distance(point, pos2) > 1: point = point + dir if self.level.blockHeights[int(point.x)][int(point.y)] > 1: return False return True
def defenseTick(self, bot): if not (Vector2.distance(bot.position,self.game.team.flagSpawnLocation) > self.level.firingDistance and self.attackCloseEnemy(bot)): if len(self.closeVisibleLivingEnemies(bot)) > 1: for defender in self.myDefenders: if not self.visibleLivingEnemies(defender) and defender.state == defender.STATE_DEFENDING and self.lastCommand[defender] != 'doubling up': dir = [bot.facingDirection,defender.facingDirection] self.issueAndStore(commands.Defend, defender, dir, description = 'doubling up') if len(self.myAttackers) < 2 and len(self.myDefenders) > self.numEnemies and not bot.seenBy: self.goAttack(bot)
def resetDefenders(self): if self.cheating: return False if all(Vector2.distance(self.closestEnemy(x).position,x.position) >self.level.firingDistance*1.6 for x in self.myDefenders if self.closestEnemy(x) is not None): self.resetDefendDirections() for defender in self.myDefenders: if (self.defendPosition - defender.position).length() <= 2: dir = self.defendDirections[0] self.defendDirections.append(self.defendDirections.pop(0)) self.issueAndStore(commands.Defend, defender, dir, description = 'defend flag') return True return False
def enemyJustOutsideRange(self, bot): closestEnemy = self.closestEnemy(bot) if not closestEnemy == None: if Vector2.distance(bot.position, closestEnemy.position) < self.level.firingDistance + self.level.firingDistance/4: return closestEnemy return None
def enemyInRange(self, bot): for enemy in self.visibleLivingEnemies(bot): enemyDistance = Vector2.distance(bot.position, enemy.position) if(enemyDistance <= self.level.firingDistance): return True return False
def closestEnemy(self, bot): closest = None visibleLivingEnemies = self.visibleLivingEnemies(bot) if visibleLivingEnemies: closest = min(visibleLivingEnemies, key=lambda x:Vector2.distance(bot.position,x.position)) return closest
def closestDefender(self, enemy): closest = min(self.myDefenders, key=lambda x:Vector2.distance(x.position,enemy.position)) return closest