📄 kechze.java
字号:
/* ClosestToCenter
* Return true if I'm the closest on my team to the center of the field
*/
boolean ClosestToCenter(Vec2 robot)
{
return ClosestTo(robot, new Vec2(0.0,0.0));
}
/* ClosestToBall
* Return true if I'm the closest on my team to the ball
*/
boolean ClosestToBall(Vec2 robot)
{
//System.out.println("Closest to ball");
return ClosestTo(robot, ball);
}
/* ClosestToMyGoal
* Return true if I'm the closest on my team to my goal
*/
boolean ClosestToMyGoal(Vec2 robot)
{
//System.out.println("Closest to goal");
Vec2 temp = new Vec2(ourgoal.x, ourgoal.y);
temp.add(robot);
return ClosestTo(robot, temp);
}
/* ClosestTo
* Return true if I'm the closest robot on my team to an item
* Item's position is absolute, not relative (I think)
*/
boolean ClosestTo(Vec2 robot, Vec2 item)
{
Vec2 temp = new Vec2( robot.x, robot.y);
temp.sub(item);
double MyDist = temp.r;
for (int i=0; i< Teammates.length; i++)
{
temp = new Vec2( Teammates[i].x, Teammates[i].y);
temp.add(robot);
temp.sub(item);
double TheirDist = temp.r;
if (TheirDist < MyDist)
return false;
}
return true;
}
/* HaveBall
* Return true if we have the ball
*/
boolean HaveBall(Vec2 robot)
{
return (CloseToBall(robot) && BehindBall(robot));
}
/* BehindBall
* Return true if the ball is between us and the goal-area
*/
boolean BehindBall(Vec2 robot)
{
if (EastTeam(robot))
{
if(ball.x >= robot.x) return false;
}
else
{
if(ball.x <= robot.x) return false;
}
Vec2 top = TopGoalPost();
Vec2 bottom = BottomGoalPost();
return between(0, NormalizeZero(top.t - ball.t),
NormalizeZero(bottom.t - ball.t));
}
/* ClearShot
* Return true if we are in line to kick the ball into their goal,
* angle-wise
*/
boolean ClearShot(Vec2 robot)
{
if(!HaveBall(robot))
return false;
double BallDir, TopGoalDir, BottomGoalDir;
if(EastTeam(robot))
{
BallDir = NormalizePI(EgoBall.t);
TopGoalDir = NormalizePI(toward(me, TopGoalPost()).t);
BottomGoalDir = NormalizePI(toward(me, BottomGoalPost()).t);
}
else
{
BallDir = NormalizeZero(EgoBall.t);
TopGoalDir = NormalizeZero(toward(me, TopGoalPost()).t);
BottomGoalDir = NormalizeZero(toward(me, BottomGoalPost()).t);
}
return between(BallDir, TopGoalDir, BottomGoalDir);
}
/* MyBottomGoalPost
* Return the egocentric position of the bottom of our goal
*/
Vec2 MyBottomGoalPost()
{
return new Vec2(ourgoal.x, ourgoal.y - GOAL_WIDTH/2);
}
/* MyTopGoalPost
* Return the egocentric position of the top of our goal
*/
Vec2 MyTopGoalPost()
{
return new Vec2(ourgoal.x, ourgoal.y + GOAL_WIDTH/2);
}
/* BottomGoalPost
* Return the position of the bottom of their goal
*/
Vec2 BottomGoalPost()
{
return new Vec2(theirgoal.x, theirgoal.y - GOAL_WIDTH/2);
}
/* TopGoalPost
* Return the position of the top of their goal
*/
Vec2 TopGoalPost()
{
return new Vec2(theirgoal.x, theirgoal.y + GOAL_WIDTH/2);
}
/* double NormalizePi
* Normalize an angle into the range [0,2*PI]
*/
static double NormalizePI(double t)
{
while(t>PI2) t -= PI2;
while(t<0) t += PI2;
return t;
}
/* double NormalizeZero
* Normalize an angle into the range [-PI,PI]
*/
static double NormalizeZero(double t)
{
while(t>PI) t -= PI2;
while(t<-PI) t += PI2;
return t;
}
/* int Quadrant
* Return the quadrant (I,II,III,IV) of a vector
*/
static int Quadrant(double theta)
{
double t = NormalizePI(theta);
if ((t > 0) && (t < PI * .5))
return 1;
else if ((t >= PI * .5) && (t < PI))
return 2;
else if ((t >= PI) && (t < PI * 1.5))
return 3;
else //if ((t >= PI * 1.5) && (t < PI2))
return 4;
}
/* TopOfField
* Return true if the given vector is in the top half of the field
*/
boolean TopOfField(Vec2 item)
{
return item.y > 0;
}
/* EastTeam
* Return true if the robot is on the Eastern team
*/
boolean EastTeam(Vec2 robot)
{
return ourgoal.x > 0;
}
/* boolean between
* Return true if a between b and c
*/
static boolean between(double a, double b, double c)
{
return (a<=Math.max(b,c)) && (a>=Math.min(b,c));
}
/* faceOurGoal
* Return the heading required to face our goal
*/
double faceOurGoal()
{
return (EastTeam(me) ? 0.0 : PI);
}
/* faceTheirGoal
* Return the heading required to face their goal
*/
double faceTheirGoal()
{
return (EastTeam(me) ? PI : 0.0);
}
/* goalieFunc
* The function that controls the goalie
* Stay beside the goal, in line with the ball, but not past the ends
* of the goal, when the ball is far away.
* When it gets close, run to a spot near the ball, horizontally in
* line with it, but still between it and the goal
*/
Vec2 goalieFunc()
{
// predict ball position in near future, and always use that value
Vec2 newEgoBall = predictEgoBall(GOALIE_LOOK_AHEAD+curr_time); //zjh
// calculate distance from goal to ball - scale in y so that there's
// an ellipse that covers the whole goal area
Vec2 balldist = new Vec2(ourgoal.x,ourgoal.y);
balldist.sub(newEgoBall);
balldist.sety(balldist.y/0.8);
Vec2 temp = new Vec2(ourgoal.x, ourgoal.y);
if (balldist.r < CLOSE_TO_GOAL) {
// the ball is close. Run to the spot right in front of it, between
// it
// and the goal
temp.setx(newEgoBall.x +
(EastTeam(me)?1.0:-1.0) * (ROBOT_RADIUS+BALL_RADIUS));
temp.sety(newEgoBall.y);
} else {
// the ball is far away. Keep inbetween it and the goal center,
// but stay in goal
temp.setx(temp.x + (EastTeam(me) ? -0.9 : 0.9) * (ROBOT_RADIUS));
temp.sety((temp.y+newEgoBall.y)/2); //zjh
if (temp.y>MyTopGoalPost().y+ROBOT_RADIUS) // too high
temp.sety(MyTopGoalPost().y+ROBOT_RADIUS);
else if (temp.y<MyBottomGoalPost().y-ROBOT_RADIUS) // too low
temp.sety(MyBottomGoalPost().y-ROBOT_RADIUS);
}
// If something went wrong and we got a NaN, then return the center
// of the goal
if (invalid(temp)) temp = new Vec2(ourgoal.x, ourgoal.y);
// Ease to the target spot, so we don't run in circles - since running
// in circles often results in running around a moving ball
return easeToRelativeSpot(temp, faceTheirGoal()); //zjh
}
/* easeToRelativeSpot
* Run to a point, and then face the given direction
* We slow down as we get close, so as not to run in circles
* We also run slow when facing the wrong direction, so as not to
* run too far in the wrong direction when starting out
*/
Vec2 easeToRelativeSpot(Vec2 Spot, double Heading)
{
Vec2 run = new Vec2(Spot.x, Spot.y);
// calculate factor for speed based on desired-current angle difference
Vec2 diff = new Vec2(0.0,1.0);
diff.sett(abstract_robot.getSteerHeading(curr_time)-run.t);
if (diff.t>PI) diff.sett(PI2-diff.t);
double factor = (PI-diff.t)/PI;
if (factor<0.0) factor = 0.0;
// factor for speed based on closeness to goal spot
double r = run.r;
run.setr(factor*r*10+0.2); // can't run slower than 0.2
if (run.r>1.0) run.setr(1.0); // can't run faster than 1.0
// We're there! Stop, and face the given heading
if (r<CLOSE_TO_SPOT)
{
run.sett(Heading);
run.setr(0.0);
}
return run;
}
/* easeToAbsoluteSpot
* Same as easeToRelativeSpot, except you can put in absolute
* coordinates, which is useful for things like:
* easeToRelativeSpot(new Vec2(0.0,0.0), faceTheirGoal());
* to go to the center of the field
*/
Vec2 easeToAbsoluteSpot(Vec2 Spot, double Heading)
{
return easeToRelativeSpot(new Vec2(Spot.x-me.x, Spot.y-me.y), Heading);
}
/* invalid
* Check whether any part of a Vector is NaN
* Use the fact that: (q != q if q is NaN)
*/
boolean invalid(Vec2 vector)
{
return ((vector.x!=vector.x)||(vector.y!=vector.y));
}
/* predictBall
* Predict the ball position at a certain time.
* Simply extrapolate from last and current position and time
*/
Vec2 predictBall(long time)
{
Vec2 temp = new Vec2(ball.x, ball.y);
temp.sub(last_ball);
long diff_time = curr_time - last_time;
if (diff_time==0.0) diff_time = (long) 0.0001; // don't divide by zero
temp.setr(temp.r/(diff_time)*(time-curr_time));
// if it's sitting still, it's going back to the middle
if(temp.r==0) temp = new Vec2(0.0,0.0);
else temp.add(ball);
return temp;
}
/* predictEgoBall
* Same as predictBall, except ego-centric
*/
Vec2 predictEgoBall(long time)
{
Vec2 temp = predictBall(time);
temp.sub(me);
return temp;
}
/* blockFunc
* The function that steers robot #4 when it is trying
* to do our cute little goalie-blocking trick
*
* Run to just below goal, then sweep upwards
*/
Vec2 blockFunc()
{
Vec2 temp = new Vec2(theirgoal.x,
BottomGoalPost().y - 3 * ROBOT_RADIUS);
if (Math.abs(theirgoal.x)<ROBOT_RADIUS+BALL_RADIUS)
temp.sety(TopGoalPost().y);
temp.setr(1.0);
return temp;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -