Skip to content

Instantly share code, notes, and snippets.

@kkabdol
Created March 29, 2017 08:25
Show Gist options
  • Save kkabdol/ac3e24b2160b5e940527afadf35b9e6b to your computer and use it in GitHub Desktop.
Save kkabdol/ac3e24b2160b5e940527afadf35b9e6b to your computer and use it in GitHub Desktop.
Codingame Coders Strike Back - Bronze to Silver
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
#define PI 3.14159265
struct vec2 {
float x;
float y;
vec2( float s = float(0.0) ) :
x(s), y(s) {}
vec2( float x, float y ) :
x(x), y(y) {}
vec2( const vec2& v )
{ x = v.x; y = v.y; }
float& operator [] ( int i ) { return *(&x + i); }
const float operator [] ( int i ) const { return *(&x + i); }
//
// --- (non-modifying) Arithematic Operators ---
//
vec2 operator - () const // unary minus operator
{ return vec2( -x, -y ); }
vec2 operator + ( const vec2& v ) const
{ return vec2( x + v.x, y + v.y ); }
vec2 operator - ( const vec2& v ) const
{ return vec2( x - v.x, y - v.y ); }
vec2 operator * ( const float s ) const
{ return vec2( s*x, s*y ); }
vec2 operator * ( const vec2& v ) const
{ return vec2( x*v.x, y*v.y ); }
friend vec2 operator * ( const float s, const vec2& v )
{ return v * s; }
vec2 operator / ( const float s ) const {
float r = float(1.0) / s;
return *this * r;
}
bool operator == ( const vec2& v ) const
{ return ( x == v.x ) && ( y == v.y ); }
bool operator != ( const vec2& v ) const
{ return ( x != v.x ) || ( y != v.y ); }
//
// --- (modifying) Arithematic Operators ---
//
vec2& operator += ( const vec2& v )
{ x += v.x; y += v.y; return *this; }
vec2& operator -= ( const vec2& v )
{ x -= v.x; y -= v.y; return *this; }
vec2& operator *= ( const float s )
{ x *= s; y *= s; return *this; }
vec2& operator *= ( const vec2& v )
{ x *= v.x; y *= v.y; return *this; }
vec2& operator /= ( const float s ) {
float r = float(1.0) / s;
*this *= r;
return *this;
}
};
//----------------------------------------------------------------------------
//
// Non-class vec2 Methods
//
inline
float dot( const vec2& u, const vec2& v ) {
return u.x * v.x + u.y * v.y;
}
inline
float length( const vec2& v ) {
return std::sqrt( dot(v,v) );
}
inline
vec2 normalize( const vec2& v ) {
return v / length(v);
}
inline
vec2 rotate( const vec2& v, float angle ) {
float radian = angle * PI / 180;
double sinAngle = sin(radian);
double cosAngle = cos(radian);
return vec2( v.x * cosAngle - v.y * sinAngle, v.y * cosAngle + v.x * sinAngle );
}
class BoostHelper {
public:
BoostHelper() : boostAvailable_( true ), allCheckpointFound_( false ), fartestDist_( 0.0 ) {}
bool UseBoost( float dist ) {
cerr << "BOOST left:" << boostAvailable_;
cerr << " is 2nd Lap:" << allCheckpointFound_;
cerr << " best boost dist:" << fartestDist_;
cerr << " current dist:" << dist << endl;
if( boostAvailable_ &&
allCheckpointFound_ &&
dist + distError > fartestDist_ )
{
boostAvailable_ = false;
return true;
}
else
{
return false;
}
}
void SetNextCheckpoint( int x, int y, int dist ) {
if( allCheckpointFound_ )
{
return;
}
const vec2 newCheckpoint( x, y );
if( checkpoints_.empty() )
{
checkpoints_.push_back( newCheckpoint );
}
else if( checkpoints_.back() != newCheckpoint )
{
checkpoints_.push_back( newCheckpoint );
if( checkpoints_.front() == newCheckpoint )
{
allCheckpointFound_ = true;
}
}
if( fartestDist_ < dist )
{
fartestDist_ = dist;
}
}
bool BoostAvailable()
{
return boostAvailable_;
}
private:
const float distError = 2000;
bool boostAvailable_;
bool allCheckpointFound_;
float fartestDist_;
vector< vec2 > checkpoints_;
};
/**
* Auto-generated code below aims at helping you parse
* the standard input according to the problem statement.
**/
int main()
{
// Steering Behaviors
// https://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732
// 1. Seek
// 2. Boost
// 3. Slowing Down ( straight only )
int oldX = 0;
int oldY = 0;
int oldOpponentX = 0;
int oldOpponentY = 0;
BoostHelper boostHelper;
const int kAngleToSteer = 1;
const int kSlowingAngle = 90;
const float kSlowingRadius = 600 * 4; // check point radius = 600
// game loop
while (1) {
int x;
int y;
int nextCheckpointX; // x position of the next check point
int nextCheckpointY; // y position of the next check point
int nextCheckpointDist; // distance to the next checkpoint
int nextCheckpointAngle; // angle between your pod orientation and the direction of the next checkpoint
cin >> x >> y >> nextCheckpointX >> nextCheckpointY >> nextCheckpointDist >> nextCheckpointAngle; cin.ignore();
int opponentX;
int opponentY;
cin >> opponentX >> opponentY; cin.ignore();
boostHelper.SetNextCheckpoint( nextCheckpointX, nextCheckpointY, nextCheckpointDist );
cerr << "x:" << x << ", y:" << y << endl;
cerr << "nextCheckpoint x:" << nextCheckpointX << ", y:" << nextCheckpointY << endl;
cerr << "nextCheckpoint angle:" << nextCheckpointAngle << endl;
cerr << "nextCheckpointDist:" << nextCheckpointDist << endl;
int thrust = 100;
bool useBoost = false;
if( nextCheckpointAngle <= -kAngleToSteer || nextCheckpointAngle >= kAngleToSteer )
{
// 1. Seek
vec2 desiredDirection( nextCheckpointX - x, nextCheckpointY - y );
desiredDirection = normalize( desiredDirection );
vec2 currentDirection = rotate( desiredDirection, -nextCheckpointAngle );
//vec2 currentDirection( x - oldX, y - oldY );
currentDirection = normalize( currentDirection );
vec2 steeringDirection = ( desiredDirection - currentDirection );
steeringDirection = normalize( steeringDirection ) * 100;
nextCheckpointX += steeringDirection.x;
nextCheckpointY += steeringDirection.y;
// 2. Slowing Down ( angle )
if( nextCheckpointAngle <= -kSlowingAngle || nextCheckpointAngle >= kSlowingAngle )
{
thrust = 0;
}
else if( nextCheckpointDist < kSlowingRadius )
{
thrust *= ( kSlowingAngle - abs(nextCheckpointAngle) ) / ( float )kSlowingAngle;
}
cerr << "steering to x:" << nextCheckpointX << ", y:" << nextCheckpointY;
cerr << " by: " << thrust << endl;
}
else
{
if( boostHelper.UseBoost( nextCheckpointDist ) )
{
useBoost = true;
cerr << "BOOST" << endl;
}
else if( nextCheckpointDist < kSlowingRadius )
{
// 2. Slowing Down ( radius )
thrust *= nextCheckpointDist / kSlowingRadius;
}
cerr << "not steering" << endl;
}
if( boostHelper.BoostAvailable() )
{
cerr << "BOOST available" << endl;
}
else
{
cerr << "BOOST used" << endl;
}
// output
cout << nextCheckpointX << " " << nextCheckpointY << " ";
if( useBoost )
{
cout << "BOOST" << endl;
}
else
{
cout << thrust << endl;
}
cerr << "thrust :" << thrust << endl;
oldX = x;
oldY = y;
oldOpponentX = opponentX;
oldOpponentY = opponentY;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment