Exemplo n.º 1
0
void ZRUser(float myState[12], float otherState[12], float time) {
    if (time < 150) {
        //TODO: move to center of panel initialization circle, instead of
        //assuming that position from the start
        float attitude[3] = {0, 1, 0};
        ZRSetAttitudeTarget(attitude);
        //TODO: rotate around the circle to find the panel; in this case,
        //panel angle is 0 so we automatically see it after the attitude change
        if (isPanelFound() && time > 20) {
            float velocity[3] = {0, 0.01, 0};
            ZRSetVelocityTarget(velocity);
        }
        if (iHavePanel() && time > 70 && time < 75) {
            float stop[3] = {0, 0, 0};
            ZRSetVelocityTarget(stop);
        }
        if (iHavePanel() && time > 75 && time < 150) {
            float station[3] = {-.7, 0, 0};
            ZRSetPositionTarget(station);
        }
    }
    if (iHavePanel() && time == 150) {
        float searchStation[3] = {0, 0.1, 0};
        ZRSetTorques(searchStation);
    }
    if (isStationInSync() && time > 150) {
        float stop[3] = {0, 0, 0};
        float velocity[3] = {0, 0, .01};
        ZRSetTorques(stop);
        ZRSetVelocityTarget(velocity);
    }
}
//User01: stuynaught Team: Stuy-Naught Project: SQUARE
void ZRUser01(float *myState, float *otherState, float time)
{
float P[3];  // The point to move towards in (x, y, z) coordinates
float dist;  // The distance we are from said point
 
P[0] = 0.5;
P[1] = 0.5;
P[2] = 0.0; // point (0.5, 0.5, 0), first corner of our square
 
if (state == 0) {
    // Don't need to do anything extra.
    // The other states give the three other corners of the square.
}
else if (state == 1) {
    P[1] = P[1] * -1;  // negate x
}
else if (state == 2) {
    P[1] = P[1] * -1;  //negate x and y
    P[0] = P[0] * -1;
}
else if (state == 3) {
    P[0] = P[0] * -1;   // negate y
}
 
ZRSetPositionTarget(P);  // move towards point P
 
dist = sqrt((myState[0]-P[0])*(myState[0]-P[0]) +
            (myState[1]-P[1])*(myState[1]-P[1]) +
            (myState[2]-P[2])*(myState[2]-P[2]));  // find our distance from the corner we're traveling to
 
if (dist < 0.05) {
    state = state + 1;  // move to the next corner if we're within 5 cm of the current target
}
}
//User01: stuynaught Team: Stuy-Naught Project: testZachary
void ZRUser01(float *myState, float *otherState, float time)
{
if ( state == 0 ) {
 
Point[0] = 0.45;
Point[1] = 0.45;
Point[2] = 0;
 
}
 
if (( state == 1) || ( state == 3 )) {
 
Point[0] = -Point[0];
 
}
 
else if (( state == 2 ) || ( state == 4 )) {
 
Point[1] = -Point[1];
 
}
 
ZRSetPositionTarget(Point);
 
if (sqrt
((myState[0]-Point[0])*(myState[0]-Point[0])
+(myState[1]-Point[1])*(myState[1]-Point[1])
+(myState[2]-Point[2])*(myState[2]-Point[2])) < 0.05) {
 
state = state+1;
 
}
}
void ZRUser(float * myState, float * otherState, float time) {
	float home[3] = {0,0.3,0};

	if (otherRepelling() == 1) {
		ZRSetPositionTarget(home);
		}

	printf("%i)\n", otherRepelling()); //prints repelling info
	}
Exemplo n.º 5
0
void rotateTau() {
	// Rotates about the x-axis by applying a torque of 0.025 N*m (?)
	// Requires an int tauSet to be set to 1 and a float correctPos to be set to 1.0;
	// Somewhat more unstable... depends on the previous performance of an attitude alignment being within a given bound
	// Sometimes the above mentioned alignment exceeds given time limits..
	// If alignment goes smoothly however, this function seems to work pretty well... but that's a big "if".
	
	float tau[3] = {0.0, 0.025, 0.0};
	if (correctPos < 2) {
		ZRSetPositionTarget(a);
		correctPos += 1.0;
	}
	if (tauSet == 1) {
		ZRSetTorques(tau);
		tauSet = 0;
	}
}
void CollideFromPoint(float * mState, float * oState, float * fromPoint, float velMag) {

if (stage == 0) {
ZRSetPositionTarget(fromPoint);
if (Vfunc(6, mState, fromPoint, NULL, 0) < 0.09) {
stage = 1;
}
}

if (stage == 1) {

Vfunc(9, fromPoint, oState, dir, 0);
Vfunc(4, dir, NULL, dir, velMag);
ZRSetVelocityTarget(dir);
}

}
Exemplo n.º 7
0
static void SetPosFaster (float c[3], float state[12])
{
//BEGIN::PROC::SetPosFaster
/*
 * SetPosFaster, as the name says,
 * is used to reach a point in
 * a shorter amount of seconds
 * than ZRSetPositionTarget ().
 */
float v[3];

mathVecSubtract(v,c,state,3);
mathVecMul (v,v,1.315f);
mathVecAdd (v,v,state,3);
ZRSetPositionTarget(v);
//END::PROC::SetPosFaster
}
Exemplo n.º 8
0
static void CoastToTarget(float* myPos, float* coastTarget, float magnitude)
{
 float temp[3];
 if (magnitude > 0.04) magnitude = 0.04;
 Vfunc(2, (coastTarget), (myPos), (temp), 0);
 if (mathVecMagnitude((temp), 3) < (mathSquare(mathVecMagnitude((&myPos[3]), 3)) * 50.0 + 0.08))
 {
  ZRSetPositionTarget(coastTarget);
 }
 else
 {
  mathVecNormalize((temp), 3);
  Vfunc(4, (temp), NULL, (temp), (magnitude));
  if (Vfunc(6, (temp), (&myPos[3]), NULL, 0) > 0.02)
   ZRSetVelocityTarget(temp);
 }
}
Exemplo n.º 9
0
static void RotateTarget(float * myState, float * pos)
{
#define VLen(a) mathVecMagnitude((a), 3)
#define VAdd(a, b, result) mathVecAdd(result, (a), (b), 3) 
#define VSub(a, b, result) Vfunc(2, (a), (b), (result), 0)
#define VUnit(a, result) Vfunc(3, (a), NULL, (result), 0)
#define VMult(a, b, result) Vfunc(4, (a), NULL, (result), (b))
#define VDot(a, b) Vfunc(5, (a), (b), NULL, 0)
#define VDist(a, b) Vfunc(6, (a), (b), NULL, 0)
#define VCopy(a, result) memcpy((result), (a), sizeof(float)*3)
#define VAngle(a, b) Vfunc(8, (a), (b), NULL, 0)
#define VPoint(a, b, result) Vfunc(9, (a), (b), (result), 0)
#define Deg2Rad(Deg) (Deg*PI/180.0)
#define Rad2Deg(Rad) (Rad*180.0/PI)
  
    // do ZRSetAttitudeTarget(current_att + AngleForward)
#define AngleForward 30
  
    float temp[3], target_att[3], current_att[3];
    float current_theta, target_theta;
  
    ZRSetPositionTarget(pos);
  
    VCopy(myState+6,current_att);
    current_theta = atan2(current_att[2],current_att[1]);
    if (current_theta < 0)
        current_theta = current_theta + 2*PI;
    target_theta = current_theta + Deg2Rad(AngleForward);
  
    temp[0] = -5.0*current_att[0];
    temp[1] = cos(target_theta);
    temp[2] = sin(target_theta);
    VUnit(temp,target_att);
  
    //printf("time: %2.0f, current_att: (%5.2f, %5.2f, %5.2f), target: (%5.2f, %5.2f, %5.2f), to_target: %5.1f",
    //procvar[0],current_att[0],current_att[1],current_att[2],target_att[0],target_att[1],target_att[2],
    //VAngle(current_att,target_att));
    //printf(" rates: (%5.2f, %5.2f, %5.2f)\n", myState[9],myState[10],myState[11]);
    //printf( " out-of-plane: %5.2f\n",asin(current_att[0])*180/3.14159);
  
    ZRSetAttitudeTarget(target_att);
}
static void orbit (float myState[12], float center[3], unsigned char CCW)
{
//BEGIN::PROC::orbit
float difference[3], target[3];
float theta;
float thetastep = .66;

mathVecSubtract(difference, myState, center, 3);
theta = atan2f(difference[1], difference[0]);

if(CCW)
    thetastep *= -1;

theta += thetastep;
difference[0] = .4 * sinf(PI/2 - theta);
difference[1] = .4 * sinf(theta);
mathVecAdd(target, center, difference, 3);
ZRSetPositionTarget(target);
//END::PROC::orbit
}
//User01: stuynaught Team: Stuy-Naught Project: squares
void ZRUser01(float *myState, float *otherState, float time)
{
float mypos[3];
int i = 0;
float dist;
for (i = 0; i < 3; i++) {
    mypos[i] = myState[i];}
dist = mathSquare(mathVecMagnitude(mypos, 3)) + mathSquare(mathVecMagnitude(pos, 3)) - 2 * mathVecInner(mypos, pos, 3);
dist = sqrt(dist);
if (dist < .05) {
if (state % 4 == 0) {
    pos[0] = .5;}
else if (state % 4 == 1) {
    pos[1] = .5;}
else if (state % 4 == 2) {
    pos[0] = -.5;}
else {
    pos[1] = -.5;}
state++;}
ZRSetPositionTarget(pos);
}
//User01: stuynaught Team: Stuy-Naught Project: move2.718
void ZRUser01(float *myState, float *otherState, float time)
{
float P[3] = {0.25, 0.25, 0};
 
if (getPercentFuelRemaining() < 10) {
myState[0] = P[0];
myState[1] = P[1];
myState[2] = P[2];
}
if (state == 0) {
}
else
if (state == 1) {
    P[1] = -0.25;
}
else
if (state == 2) {
    P[0] = -0.25;
    P[1] = -0.25;
}
else
if (state == 3) {
    P[0] = -0.25;
}
 
ZRSetPositionTarget(P);
if ( sqrt((myState[0] - P[0])*(myState[0] - P[0]) +
     (myState[1] - P[1])*(myState[1] - P[1]) +
     (myState[2] - P[2])*(myState[2] - P[2]))  < 0.05 ) {
      
     state = state+1;
      
}
 
if (state == 4) {
state = 0;
}
 
 
}
Exemplo n.º 13
0
static void meltIce (float state[12], float other[12], float time)
{
//BEGIN::PROC::meltIce
/*
 * meltIce melts the
 * ice sheet on Opulens
 * (no shit!)
 */
float x[3]={0,-0.35,-0.2};
if (PiceHits()+PotherIceHits()>18 || time<47) {
	revolve (x,state,other);
}
else {
	ZRSetPositionTarget (state);
	mathVecSubtract(x,x,state,3);
	ZRSetAttitudeTarget(x);
	
}
if (time>59)
	Plaser();
//END::PROC::meltIce
}
Exemplo n.º 14
0
static void spin (float c[3], float mystate[12])
{
//BEGIN::PROC::spin
/*
 * mmh.. Do I really need to
 * exaplain what this function
 * is for?
 */
float v[3];
char i;
float cosalfa=0;

if (ok<3) {
	PgetAsteroidNormal(v);
	
	for(i=0;i<3;i++)
		cosalfa+=v[i]*mystate[i+6];
		
	if(cosalfa<0)
		mathVecMul (v,v,-1);
			
	ZRSetAttitudeTarget(v);
	
	if (fabs(cosalfa)>0.986f)
		ok++;
}
else {
	v[0]=(0.5236f - mystate[9])/50;
	v[1]=0;
	v[2]=0;
	ZRSetTorques(v);
}
 
ZRSetPositionTarget(c); 
//END::PROC::spin
}
void ZRUser01(float *myState, float *otherState, float time)
{
//BEGIN::PROC::ZRUser
float opulens[3] = {0.0, -0.6, 0.0};
float Laser[3] = {0.4, 0.0, 0.0};
float shield[3] = {0.0, 0.4, 0.0};
float zero[3] = {0.0, 0.0, 0.0};
float difference[3];
float Asteroid[3] = {0.0, -0.6, 0.0};
float Station[3] = {0.0, 0.0, 0.0};


switch((int)time)
{
    case 0:
        SphereNumber = !!(myState[0] < 0) + 1;
        break;
    case 30:
        getShield = (otherState[1] <= 0);
        break;
    case 61:
        asteroid = (PinAsteroid(otherState) == 1) ? 1 : 0;
        break;
    case 90:
        asteroid = (PisRevolving(otherState) == 2 && !asteroid) ? 1 : asteroid;
        break;
}


Station[0] = (SphereNumber == 1) ? 0.6 : -0.6; //station closer to where you started
Asteroid[1] = asteroid ? -0.6 : 0.6;
Laser[0] = ((SphereNumber == 1) - (PotherHasLaser() == SphereNumber)) ? 0.4 : -0.4;


switch(state)
{
    case 0:
        ZRSetPositionTarget(Laser);
        shoot(myState, opulens, 0);
        if(PhaveLaser() || PgetPhase() == 2)
            state = 1;
        break;
        
    case 1:
        if(!getShield)
            shield[1] = .3;
        ZRSetPositionTarget(shield);
        shoot(myState, opulens, 0);
        if(PotherHasShield() || PhaveShield() || PgetPhase() == 2)
            state = 2;
        break;
        
    case 2:
        if(PiceHits() < 14 && !asteroid)
            shoot(myState, opulens, (PgetPhase() > 1));
        if(!(PiceMelted()) && asteroid)
        {
            mathVecSubtract(difference, myState, opulens, 3);
            if(mathVecMagnitude(difference, 3) > .8)
                ZRSetPositionTarget(opulens);
            else
                ZRSetVelocityTarget(zero);
            shoot(myState, opulens, (PgetPhase() > 1));
            return;
        }
        orbit(myState, Asteroid, Station[0] == -0.6);
        if(time + timeToMS(myState, Station) >= 165)
            state = 3;
        break;
        
    default:
        ZRSetPositionTarget(Station);
        break;
}
//END::PROC::ZRUser
}
Exemplo n.º 16
0
void ZRUser(float* myState, float* otherState, float time)
{
 float target[3];
 float station[4];

 float baseAngle;
 float angleDiff;
 float baseRadius;

 float to_opponent[3];
 float sun[3] = {0,0,0};

 float tolerance=.02;

 float a1, a2;
 float s1 = 0;
 float s2 = 0; //s1 = score 1 second ago. s2 = current score

 DEBUG(("time: %4.0f, state: %d\n", time, state));
 switch (state)
 {
  case 0:
//Code to initialize the sphere, then search for the panel...

state = 1;
   break;
  case 1:
//Code to move towards panel initialization circle...



if (fabs(myState[0] - (getPanelSide() * 0.7)) < 0.1)
 state = 2;

baseAngle = atan2f(myState[2], myState[1]);

target_pos[0] = (getPanelSide() * 0.7);
target_pos[1] = cosf(baseAngle) * 0.7;
target_pos[2] = sinf(baseAngle) * 0.7;

ZRSetPositionTarget(target_pos);

Vfunc(9, (sun), (myState), (target_att), 0);

ZRSetAttitudeTarget(target_att);


//Code to find tangent lines...

baseAngle = atan2f(-target_pos[2], -target_pos[1]);
angleDiff = asinf(0.5 / sqrtf(mathSquare(target_pos[1]) + mathSquare(target_pos[2])));

tangentPoints[0] = baseAngle - angleDiff;
tangentPoints[1] = baseAngle + angleDiff;



tangentPoints[2] = tangentPoints[0];
   break;
  case 2:
if (getPercentChargeRemaining() >= 95) {
    state = 3;
    break;
} else {
    // calc vector from current position back toward sun
    Vfunc(9, (sun), (myState), (target_att), 0);
    ZRSetPositionTarget(target_pos);
    ZRSetAttitudeTarget(target_att);
}
   break;
  case 3:
//Code to wait for the opponent to get into their panel's plane



Vfunc(9, (myState), (otherState), (to_opponent), 0);



if(fabs(otherState[0] - (getPanelSide() * -0.7) > .10)){
 state = 5;
 break;
}
else {
 ZRSetAttitudeTarget(to_opponent);
 if(fabs(otherState[0] - (getPanelSide() * -0.7)) < .005){
  state = 4;
  break;
 }
}
   break;
 case 4:
ZRSetPositionTarget(target_pos);
Vfunc(9, (myState), (otherState), (to_opponent), 0);
if (Vfunc(8, (to_opponent), (myState+6), NULL, 0) < 5 && getPercentChargeRemaining() > 0 && fabs(otherState[0]) > .68 && fabs(otherState[0]) < .81) {
    DEBUG(("time: %4.0f, (BLUE): ZAPPING ++++++++++++++++++++\n",time));
    ZRRepel();
}
else {
    if (getPercentChargeRemaining() < 1) {
        state = 5;
        break;
    }
    Vfunc(9, (myState), (otherState), (to_opponent), 0);
    DEBUG(("time: %4.0f, (BLUE): angle to opponent: %f\n",time,Vfunc(8, (to_opponent), (myState+3), NULL, 0)));
    ZRSetAttitudeTarget(to_opponent);
}
   break;
  case 5:
//Code to search for panel...

//Check if panel was found.

if (isPanelFound())
{
 getPanelState(panelState);


 panelState[4] = panelState[0];

 baseAngle = atan2f(panelState[2], panelState[1]);
 baseRadius = sqrtf(mathSquare(panelState[1]) + mathSquare(panelState[2])) - 0.03;

 panelState[5] = cosf(baseAngle) * baseRadius;
 panelState[6] = sinf(baseAngle) * baseRadius;

 state = 6;
 break;
}


//Code to find tangent lines...

baseAngle = atan2f(-myState[2], -myState[1]);
angleDiff = asinf(0.5 / sqrtf(mathSquare(myState[1]) + mathSquare(myState[2])));

tangentPoints[0] = baseAngle - angleDiff;
tangentPoints[1] = baseAngle + angleDiff;


//Point in the direction of tangentPoints[2]

target_att[0] = 0;
target_att[1] = cosf(tangentPoints[2]);
target_att[2] = sinf(tangentPoints[2]);

ZRSetAttitudeTarget(target_att);

if(fabs(otherState[0] - (getPanelSide() * -0.7) < .05 && getPercentChargeRemaining() > 0)){
 state = 3;
 break;
}

tangentPoints[2] += scanTarget * 0.1;

if ((scanTarget == 1) && (tangentPoints[2] >= tangentPoints[1]))
 scanTarget = -1;
else if ((scanTarget == -1) && (tangentPoints[2] <= tangentPoints[0]))
 scanTarget = 1;

target_pos[0] = getPanelSide() * 0.7;
target_pos[1] = myState[1];
target_pos[2] = myState[2];

ZRSetPositionTarget(target_pos);
   break;
  case 6:
//Code to move to panel...

if (iHavePanel())
{
 state = 7;
 scanTarget = 0;
 break;
}

ZRSetPositionTarget(&panelState[4]);

Vfunc(7, (panelState), NULL, (target_pos), 0);
target_pos[0] = 0;
Vfunc(3, (target_pos), NULL, (target_pos), 0);

ZRSetAttitudeTarget(target_pos);
   break;
  case 7:
//Code to beeline towards the station...

if (s2 - s1 == 0 && s2 > 0){
state = 8;
break;
}
else {
s1 = s2;
s2 = getOtherCurrentScore();
getStationState(station);

Vfunc(7, (station), NULL, (target_att), 0);

target_att[1] += cosf(station[3]) * 0.03;
target_att[2] += sinf(station[3]) * 0.03;

CoastToTarget(myState, target_att);

target_att[0] = 0;
target_att[1] = cosf(station[3]);
target_att[2] = sinf(station[3]);

ZRSetAttitudeTarget(target_att);
}
   break;
  case 8:
//Code to beeline towards the station...



target[0] = (getPanelSide() * 0.7);
target[1] = 0;
target[2] = 0;

CoastToTarget(myState, target);
   break;
 }
}
void ZRUser01(float *myState, float *otherState, float time)
{
//BEGIN::PROC::ZRUser
float opulens[3] = {0.0, -0.6, 0.0};
float Laser[3] = {0.4, 0.0, 0.0};
float shield[3] = {0.0, 0.4, 0.0};
float disrupt[3] = {0.0,0.2,0.0};
float zero[3] = {0.0, 0.0, 0.0};
float difference[3];
float facing[3];
float Asteroid[3] = {0.0, -0.6, 0.0};
int recieved;


switch((int)time)
{
    case 0:
        SphereNumber = !!(myState[0] < 0) + 1;
        Station[0] = (SphereNumber == 1) ? 0.6 : -0.6; //station closer to where you started
        break;
    case 30:
        getUp = (otherState[1] <= 0);
        break;
    case 61:
    case 66:
        Spin = PisRevolving(otherState) ? 1 : 0;
        break;
    case 75: if(PinAsteroid(otherState) == 1) asteroid = 1;
}


Laser[0] = ((SphereNumber == 1) - (PotherHasLaser() == SphereNumber)) ? 0.4 : -0.4;

recieved = (int)PgetMessage();
switch(recieved)
{
    case 6:
        if(!(Station[0] < 0.0) && switchedStation++ < 3)
            Station[0] = -0.6;
        break;
    case 7:
        if(!(Station[0] > 0.0) && switchedStation++ < 3)
            Station[0] = 0.6;
        break;
    case 2:
    case 3:
        if(time < 45)
        asteroid = 1;
        break;
    case 4:
    case 5:
        if(time < 45)
        asteroid = 0;
        break;
}


if(time <= 120)
PsendMessage(4 - 2*asteroid + (Spin == 0));
else
PsendMessage((Station[0] < 0) + 6);

Asteroid[1] = asteroid ? -0.6 : 0.6;


switch(state)
{
    case 0:
        ZRSetPositionTarget(Laser);
        shoot(myState, opulens, 0);
        if(PhaveLaser() || PgetPhase() == 2)
            state = 1;
        break;
        
    case 1:
        if(!getUp) {
            shield[1] = .3;
            disrupt[1] = .3;
        }
        ZRSetPositionTarget(disrupt);
        shoot(myState, opulens, 0);
        if(PotherDisruptorUpgraded() || PdisruptorUpgraded())
            state = 2;
        if(PgetPhase() == 2)
            state = 3;
        break;
        
    case 2:
        ZRSetPositionTarget(shield);
        shoot(myState, opulens, 0);
        if(PotherHasShield() || PhaveShield() || PgetPhase() == 2)
            state = 3;
        break;
    case 3:
        if(PiceHits() < 15 && !asteroid)
            shoot(myState, opulens, (PgetPhase() > 1));
        if(!(PiceMelted()) && asteroid)
        {
            mathVecSubtract(difference, myState, opulens, 3);
            if(mathVecMagnitude(difference, 3) > .8)
                ZRSetPositionTarget(opulens);
            else if(!Spin)
                ZRSetVelocityTarget(zero);
            shoot(myState, opulens, (PgetPhase() > 1));
            return;
        }
        if(Spin){
            ZRSetPositionTarget(Asteroid);
            spin(myState);
        }
        else
            orbit(myState, Asteroid, Station[0] == -0.6);
        if((!Spin && (time + timeToMS(myState, Station) >= 165)) || (Spin && (time >= 156)))
            state = 4;
        break;
    default:
        leaveOrbit(myState, Asteroid, Station);
        mathVecSubtract(facing, otherState, myState, 3);
        mathVecNormalize(facing, 3);
        ZRSetAttitudeTarget(facing);
        if (acos(mathVecInner(&myState[6], facing, 3) / mathVecMagnitude(&myState[6], 3)) < (0.1))
            Ptractor();
        break;
}
//END::PROC::ZRUser
}
Exemplo n.º 18
0
void ZRUser01(float *myState, float *otherState, float time)
{
//BEGIN::PROC::ZRUser

// These are just some costants, don't pay to much attention to them :)
#define	 WAIT_TIME	   13	// Seconds to wait before starting spinning

#define	 TIME_OPP_STAT   140	// Will only start considering about going
				// to a station after TIME_OPP_STAT seconds.

#define	 ACCURACY_STAT   1.975f // Number between 1 and 2, the higher it is,
				// the more accurate in deciding whether the 
				// opponent is headed towards the station.

#define	 FUEL_STAT	   25	// The minimum amount of fuel required to go
				// to a mining station (below this value, 
				// the sphere's not going anywhere


// msg  : contains the messages received from the opponent
// tt   : contains a condition used a couple of times (space optimization)
// out  : contains the message we're sending our opponent
unsigned short msg,tt,out=0;
// avoid: is true or false whether the collision avoidance system is activated or not
unsigned char avoid;
// Don't worry about x and v ^^
float x[2];
float v[3];
// stat : these are some coordinates of stuff, like stations, asteroids and
//		a couple of corners of the playground
float stat[6][3] =  {   {-0.5f,+0.31f,-0.55f},
			{+0.5f,-0.31f,+0.55f},
			{0,-0.35f,-0.2f},
			{0,+0.35f,+0.2f},
			{-0.5f,+0.65f,-0.55f},
			{+0.5f,-0.65f,+0.55f}};
msg=PgetMessage();
avoid = PisAvoidingCollision();
tt=(tmp && tmp+WAIT_TIME<time);

/*
 * y0b0tics protocol will be used only when 
 * we're controlling the SPH # 1
 */
if (!time) {
	if (myState[0]>0) { // SPH1
		a=0.4; //  a is the X coordinate of the nearest laser
		out=0x0400; // bit 11
		sp=1;
	}
	else
		a=-0.4;
}

/*
 * If the opponent is willing to work
 * on Indigens, we're going to Indigens
 * as well, but we'll try to revolve.
 * Otherwise we keep sending our
 * opponent a "I'll revolve on Opulens"
 * message.
 */
if (time<60 && time) {
	if ((msg>3 && msg<6) || ast==1) {
		out=5;
		act=2; // Revolve
		ast=1; // Indigens
	}
	else {
		out=3;
	}
}
/*
 * If we're headed to a mining station,
 * we're telling our opponents which one
 * it is
 */
else if (act==4 && st<2)
	out=7-st;
PsendMessage(out);
/*
 * First of all, the Laser is taken
 * (btw, there's a "minor" bug in this
 * condition (&& time<60) is needed
 * (will add that as soon as some space
 * is available)
 */
if (!PhaveLaser()) {
	/*
	 * If the opponent is trying to "steal"
	 * our laser, we will get the other one
	 */
	if (avoid && myState[0]*a>0) 
		a*=-1;
	/* v contains the
	 * laser coordinates
	 */
	v[0]=a;
	v[1]=0;
	v[2]=0;
	ZRSetPositionTarget(v);
}
else {
	if (time>TIME_OPP_STAT && st<2) {
		/*
		 * x[0] is given the value of the distance
		 * between us and our opponent
		 */
		mathVecSubtract (v,myState,otherState,3);
		x[0]=mathVecMagnitude (v,3);
		/*
		 * if our opponent is going to a station
		 * we decide to go to the other one, but
		 * only if we're able to arrive first
		 */
		if (checkTarget(otherState,0)>ACCURACY_STAT) {
			/*
			 * Even if we're headed towards a station,
			 * if our opponent is going to
			 * the same station as us, we stop going
			 * there and, instead, we move to the
			 * closest corner of the playground,
			 * so that, even if we don't gain anything,
			 * at least we won't activate the collision
			 * avoidance system
			 */
			if (!st && x[0]<0.65f) {
					st=4;
			}
			else if (st==-1) {
				/*
				 * We go to the other station only if
				 * we can reach it first
				 */
				if (getInTime(stat[0],otherState,stat[1],myState)) {
					st=1;
					act=4;
				}
				else
					st=-2;
			}
		}
		/*
		 * Same stuff as before, but now
		 * the other station is checked.
		 */
		else if (checkTarget(otherState,1)>ACCURACY_STAT) {
			if (st==1 && x[0]<0.65f) {
					st=5;
			}
			else if (st==-1) {
				if (getInTime(stat[1],otherState,stat[0],myState)) {
					st=0;
					act=4;
				}
				else
					st=-2;
			}
		}
		/*
		 * although our opponent is not going to 
		 * a station, we leave the asteroid we're
		 * working on to go to a station.
		 * The time we're leaving the asteroid is
		 * not fixed, but is calculated every time
		 * in order to leave the asteroid as late as
		 * possible
		 */
		else if (PgetPercentFuelRemaining()>FUEL_STAT && st==-1) {
			/*
			 * x[0] contains the value of time
			 * at which we have to leave the asteroid
			 * to reach a station
			 * 180-(time needed to reach a station)
			 */
			x[0]=timeStation(stat[0],myState);
			x[1]=timeStation(stat[1],myState);
				/*
				 * It is then decided which station is
				 * better, keeping in account that, if
				 * we're spinning, our opponent could be
				 * on our way to the station.
				 */
				if ((time>=x[0]) && (x[0]>x[1]) && !(act==3 && otherState[0]<0 && otherState[1]>0 && otherState[2]<0.2)) {
					act=4;
					st=0;
				}
				if ((x[0]<x[1]) && (time>=x[1]) && !(act==3 && otherState[0]>0 && otherState[1]<0 && otherState[2]>-0.2)) {
					act=4;
					st=1;
				}
		}
	}
	/*
	 * act (action) contains a value
	 * related to the action we're
	 * doing.
	 */
	switch (act) {
		/* act = 1 -> melting ice on Opulens */
		case 1:
			meltIce(myState,otherState,time);
			if (PiceMelted()) 
				act=2;  // if the ice is melted, we start revolving
						// on Opulens
			break;
		/* act = 2 -> revolve */
		case 2:
			/*
			 * if the opponent is revolving as
			 * well, we keep revolving as well
			 * for WAIT_TIME seconds. After that
			 * seconds, if the opponent is 
			 * still revolving, we start spinning
			 */
			if (PisRevolving (otherState)==ast-1) {
				if (!tmp)
					tmp=time;
				if (tt && (checkTarget (otherState,ast)<1.9f) && st!=-2) {
					act=3;
					tmp=0;
				}
			}
			revolve(stat[ast],myState,otherState);
			break;
		/* act = 3 -> spinning */
		case 3:
			/*
			 * if the avoiding collision system
			 * is working, it probably means that
			 * our opponent wants to spin and he's
			 * close to us so, after a few seconds,
			 * we let him spin and we start revolving ^^
			 */
			if (avoid) {
				if (!tmp)
					tmp=time;
				if (tt) {
					tmp=0;
					act=2;
				}
			}
			spin(stat[ast],myState);
			break;
		/* act = 4 -> going somewhere */
		case 4:
			SetPosFaster(stat[st],myState);
			break;
		default:
			break;
	}
	if (tt)
		tmp=0;
}
//END::PROC::ZRUser
}