bool EnemyBlocked( Tank * pEnemy, Tank & self, vector<Tank> & t ) { double my_angle = self.GetAngleTo( *pEnemy ); double my_dist = self.GetDistanceTo( *pEnemy ); for (int i = 0; i < t.size(); ++i) { if (t[i].id() == pEnemy->id() || t[i].id() == self.id()) { continue; } double max_wh = std::max( t[i].width(), t[i].height() ); double alpha = fabs( self.GetAngleTo(t[i]) - my_angle ); double his_dist = self.GetDistanceTo( t[i] ); if (alpha > M_PI / 4) { continue; } double d_size = sin(alpha) * my_dist; if ( d_size <= max_wh/2 && his_dist < my_dist ) { return true; } } return false; }
void GoToUnit( Unit * pBonus, Tank & self, model::Move & move ) { double orig_angle = self.GetAngleTo(*pBonus); double angle = orig_angle; double fangle = fabs(orig_angle); double dist = self.GetDistanceTo( *pBonus ); double MIN_ANGLE_B = dist*0.0005; double direction = 1.0; if (orig_angle > PI_D_2) { angle = M_PI - fangle; direction = -1.0; } if (orig_angle < -PI_D_2) { angle = fangle - M_PI; direction = -1.0; } if (fangle > PI_D_2) { if ( angle > MIN_ANGLE_B ) { move.set_left_track_power(-self.engine_power()); move.set_right_track_power( self.engine_power() - self.engine_rear_power_factor() ); //(.75); } else if ( angle < -MIN_ANGLE_B ) { move.set_left_track_power(self.engine_power() - self.engine_rear_power_factor() );//(.75); move.set_right_track_power(-self.engine_power()); } else { move.set_left_track_power(direction*1); move.set_right_track_power(direction*1); } } else { if ( angle > MIN_ANGLE_B ) { move.set_left_track_power(self.engine_power() - self.engine_rear_power_factor() );//(.75); move.set_right_track_power(-self.engine_power()); } else if ( angle < -MIN_ANGLE_B ) { move.set_left_track_power(-self.engine_power()); move.set_right_track_power( self.engine_power() - self.engine_rear_power_factor() ); //(.75); } else { move.set_left_track_power(direction*1); move.set_right_track_power(direction*1); } } }
void ForceModify(Tank & self, Unit & u, double & xForce, double & yForce, double neg_c) { //double absBearing = fabs( u.angle() ); double absBearing = self.GetAngleTo( u ); /* from 0 to 2*PI */ double distance = self.GetDistanceTo( u ); xForce += neg_c * ( sin(absBearing) / (distance * distance) ); yForce += neg_c * ( cos(absBearing) / (distance * distance) ); }
void Shoot(Tank & self, World & world, model::Move& move) { vector<Tank> t = world.tanks(); /* always keep tower to some enemy */ Tank * pEnemy = get_need_id(g_lock_id, t); if ( EnemyDead(pEnemy) ) { pEnemy = 0; } /* not locked to anyone, select some, or change target every 300 tick */ if (!pEnemy || world.tick() % 300 == 0) { Tank * pOldEnemy = pEnemy; pEnemy = get_best_enemy(self, t); if (pEnemy != pOldEnemy) { waves.clear(); stats.clear(); stats.resize(30); } } /* still bad luck ? */ if (!pEnemy) { /* MoveAlgo */ return; } double absBearing = self.GetAngleTo(*pEnemy); for (int i=0; i < waves.size(); i++) { if (waves[i].checkHit(self, pEnemy, world.tick())) { waves.erase(waves.begin() + i ); i--; } } double power = 16.7; double e_velocity = sqrt( pEnemy->speed_x()*pEnemy->speed_x() + pEnemy->speed_y()*pEnemy->speed_y() ); WaveBullet newWave( self.x(), self.y(), self.angle(), absBearing, power, direction, world.tick(), &stats ); int bestindex = 15; for (int i=0; i<30; ++i) { if (stats[bestindex] < stats[i]) { bestindex = i; } } double guessfactor = ( bestindex - ( (double)stats.size() - 1 )/2 ) / ( ( (double)stats.size() - 1) / 2) ; if (e_velocity > 0.01) { if ( sin( pEnemy->angle() - self.angle() ) < 0 ) { direction = -1; } else { direction = 1; } } double angleOffset = direction * guessfactor * newWave.maxEscapeAngle(); /* got lock? move turret! */ MoveTurretOrShoot( pEnemy, self, world, move, 0.0 ); waves.push_back(newWave); }