📄 behave.c
字号:
return scan_field_with_body();}/*****************************************************************************************/ActionQueueRes face_neck_and_body_to_ball(){ Mem->LogAction2(30,"facing neck and body to ball"); if ( Mem->BallPositionValid() ) { return face_neck_and_body_to_point(Mem->BallPredictedPositionWithQueuedActions()); } else return scan_field_with_body();}/*****************************************************************************************//* if the arg is DT_all, we always dodge, otherwise we only dodge if they don't have ball */void get_ball(){ if ( !Mem->MyConf() || !Mem->BallPositionValid() ) my_error("not enough info to get ball"); DodgeType dodge = DT_only_with_ball; if ( !Mem->BallMoving() ){ Mem->LogAction2(30, "get_ball: ball not moving, going to it's pos"); if ( go_to_point(Mem->BallAbsolutePosition(),0,100,dodge) == AQ_ActionNotQueued ){ my_error("already there???"); face_neck_and_body_to_ball(); } face_only_neck_to_ball(); } else { if ( !Mem->MyInterceptionAble() ){ Mem->LogAction2(30, "get_ball: going to the moving ball, but can't?"); my_error("Can't get to the ball"); face_neck_and_body_to_ball(); } else if (Mem->MyInterceptionNumberCycles() == 1) { /* we're just one dash away, so just do it */ Mem->LogAction2(30, "get_ball: going to the moving ball, just dashing 1 cycle"); dash(Mem->CorrectDashPowerForStamina(Mem->MyInterceptionDashPower())); face_only_neck_to_ball(); } else if ( go_to_point(Mem->MyInterceptionPoint(),0, Mem->MyInterceptionDashPower(),dodge) == AQ_ActionNotQueued ) { Mem->LogAction2(30, "get_ball: going to the moving ball, but already there?"); my_error("already there (moving) ???"); face_neck_and_body_to_ball(); } else { Mem->LogAction4(30, "get_ball: going to the moving ball (%d) pow %.2f", Mem->MyInterceptionNumberCycles(), Mem->MyInterceptionDashPower()); face_only_neck_to_ball(); } }}/*****************************************************************************************/void stop_ball(){ if (!Mem->BallPositionValid()) my_error("Need to know where ball is to stop it"); if (Mem->BallVelocityValid()) { Mem->LogAction2(30, "stop_ball: velocity valid"); DoTurnKickCommand(dokick(0,0)); } else { Mem->LogAction2(30, "stop_ball: velocity not valid"); //DebugDrib(printf("Stop kick; don't know velocity, so goign to kick to us")); kick(Mem->CP_stop_ball_power, GetNormalizeAngleDeg(Mem->BallAngleFromBody() + 180)); }}/*****************************************************************************************/void hold_ball(){ if (!Mem->BallPositionValid()) my_error("Need to know where ball is to hold it"); Unum opponent = Mem->ClosestOpponent(); Mem->LogAction3(30, "hold_ball: closest opponent == %d",opponent); /* make sure that we keep control of the ball we need to make sure that ball's velocity is valid, and then scan_field only if we will keep control of ball */ if ( opponent == Unum_Unknown) { if (!Mem->BallVelocityValid()){ Mem->LogAction2(40, "hold_ball: velocity not valid"); face_neck_to_ball(); } else if (Mem->TimeToTurnForScan() && (!Mem->BallMoving() || Mem->BallWillBeKickable(1,0,Mem->CP_holdball_kickable_buffer)) ){ Mem->LogAction2(40, "hold_ball: ball not moving or will be kickable"); scan_field_with_body(); } else if (Mem->BallMoving() || !Mem->BallWillBeKickable(1,0,Mem->CP_holdball_kickable_buffer) ){ Mem->LogAction2(40, "hold_ball: ball moving or won't be kickable"); stop_ball(); } else{ Mem->LogAction2(40, "hold_ball: doing nothing"); /* do nothing */ } } else { /* closest opponent known */ AngleDeg ang = GetNormalizeAngleDeg(Mem->OpponentAngleFromBody(opponent) + 180); Vector targ_pos = Mem->RelativeToMyBody2Global(Polar2Vector(Mem->CP_opt_ctrl_dist, ang)); if (!Mem->FieldRectangle.IsWithin(targ_pos)) { /* Adjust the targ_pos and ang to be in bounds- ignore the corners! */ Line lSide = Mem->FieldRectangle.nearestEdgeLine(Mem->MyPos()); Vector sol1, sol2; int num_sol = LineCircleIntersect(lSide, Mem->CP_opt_ctrl_dist, Mem->MyPos(), &sol1, &sol2); if (num_sol == 0) { my_error("hold_ball: why didn't LineCircleIntersect work?"); } else if (num_sol == 1) { Mem->LogAction6(40, "hold_ball: avoiding the sideline 1; old: (%.1f, %.1f) new: (%.1f, %.1f)", targ_pos.x, targ_pos.y, sol1.x, sol1.y); ang = Mem->AngleToFromBody(sol1); } else if (num_sol == 2) { if (targ_pos.dist2(sol1) < targ_pos.dist2(sol2)) { Mem->LogAction6(40, "hold_ball: avoiding the sideline 2; old: (%.1f, %.1f) new: (%.1f, %.1f)", targ_pos.x, targ_pos.y, sol1.x, sol1.y); ang = Mem->AngleToFromBody(sol1); } else { Mem->LogAction6(40, "hold_ball: avoiding the sideline 3; old: (%.1f, %.1f) new: (%.1f, %.1f)", targ_pos.x, targ_pos.y, sol2.x, sol2.y); ang = Mem->AngleToFromBody(sol2); } } } if (!Mem->BallWillBeKickable(1,0,Mem->CP_holdball_kickable_buffer)) { Mem->LogAction2(40, "hold_ball: turning ball from opponent -- won't be kickable"); if (TurnballTo(ang) == KT_DidNothing) my_error("hold_ball: why didn't turnball do something"); } else if (Mem->OpponentPositionValid(opponent) < .9 && !Mem->InViewAngle(Mem->OpponentAngleFromNeck(opponent))){ Mem->LogAction2(40, "hold_ball: looking at opponent"); face_neck_to_opponent(opponent); } else if (Mem->TimeToTurnForScan() && Mem->EstimatedCyclesToSteal(opponent) > Mem->CP_time_for_full_rotation/3){ /* do we want to scan when the ball may be near the opp? */ /* yes, but only if the opponent isn't about to get the ball */ Mem->LogAction2(40, "hold_ball: looking around"); scan_field_with_body(); } else{ Mem->LogAction2(40, "hold_ball: turning ball from opponent"); TurnballTo(ang); } }}/*****************************************************************************************/void pass_ball(Unum teammate, float target_vel_at_dest){ Mem->LogAction3(30, "passing to %d",teammate); if ( teammate == Unum_Unknown ) my_error("Need to pass to a teammate"); if ( !Mem->TeammatePositionValid(teammate) ) my_error("can't pass to invalid teammmate"); if ( Mem->TeammatePositionValid(teammate) < .9 ){ Mem->LogAction2(40, "pass_ball: looking for teammate"); if ( face_neck_to_teammate(teammate) == AQ_ActionNotQueued ) hold_ball(); return; } Vector target = Mem->TeammateAbsolutePosition(teammate); AngleDeg target_angle = Mem->AngleToFromBody(target); TurnDir rotation = KickRotationDirection(target_angle); float target_vel = Mem->VelAtPt2VelAtFoot(target,target_vel_at_dest); KickMode mode = Mem->BestKickMode(target_angle); if (mode == KM_HardestKick) mode = KM_Hard; Mem->team_passer = Mem->MyNumber; Mem->team_receiver = teammate; Mem->team_pass_time = Mem->CurrentTime; Mem->LogAction2(40, "pass_ball: starting pass"); kick_ball(target,mode,target_vel,rotation); }/*****************************************************************************************//* extend this angle to the sideline and call the other kick_ball variant *//* target_angle is relative to body */void kick_ball(AngleDeg target_angle, KickMode mode, float target_vel, TurnDir rotation){ Vector target_pt = Mem->FieldRectangle.RayIntersection(Ray(Mem->MyPos(), target_angle + Mem->MyBodyAng())); Mem->LogAction5(40, "starting kick to angle %.1f, translated to point (%.1f, %.1f)", target_angle, target_pt.x, target_pt.y); kick_ball(target_pt, mode, target_vel, rotation); return;}void kick_ball(Vector point, KickMode mode, float target_vel, TurnDir rotation){ if (rotation == TURN_NONE) rotation = KickRotationDirection(Mem->AngleToFromBody(point)); /* look to see if a dash will help */ if (mode == KM_Hard && Mem->WillDashHelpKick(point, Mem->SP_max_power)) { mode = KM_Moderate; float target_angle = (point - Mem->MyPredictedPosition(1, Mem->SP_max_power)).dir() - Mem->MyBodyAng(); Mem->LogAction3(40, "kick_ball: dashing will help kick to angle: %1.f", target_angle); dash(Mem->SP_max_power); Mem->StartKick(target_angle, mode, target_vel, rotation); } else { if (mode == KM_Hard) mode = KM_Moderate; float target_angle = Mem->AngleToFromBody(point); Mem->LogAction3(40, "kick_ball: starting kick to angle %.1f",target_angle); Mem->StartKick(target_angle, mode, target_vel, rotation); smart_kick_hard(target_angle, mode, target_vel, rotation); } return;}void kick_ball(AngleDeg target_angle, KickMode mode, TurnDir rotation){ kick_ball(target_angle,mode,2*Mem->SP_ball_speed_max,rotation);}void kick_ball(Vector point, KickMode mode, TurnDir rotation){ kick_ball(point,mode,2*Mem->SP_ball_speed_max,rotation);}/*****************************************************************************************/ActionQueueRes go_to_point( Vector p, float buffer, float dash_power, DodgeType dodge ){ Mem->LogAction5(30, "go_to_point %d (%.1f %.1f)",dodge, p.x,p.y); if ( !Mem->MyConf() ) my_error("Can't go to a point if not localized"); if ( Mem->DistanceTo(p) < buffer ){ if ( Mem->SP_use_offside && fabs(Mem->MyX() - Mem->my_offside_line) < 5 ){ /* hack */ Unum opp = Mem->FurthestForwardOpponent(); if ( opp != Unum_Unknown && Mem->OpponentPositionValid(opp) < .9 ){ /* hack */ Mem->LogAction2(40, "go_to_point: looking for offsides line"); return face_neck_to_opponent(opp); } } Mem->LogAction2(40, "go_to_point: already at the point"); return AQ_ActionNotQueued; } if ( Mem->PlayMode == PM_Their_Goal_Kick && Mem->MyPos() != p ){ /* if ( Mem->TheirPenaltyArea.IsWithin(p) ){ my_error("Can't go into their penalty area on a goal kick!"); */ Line l = LineFromTwoPoints(Mem->MyPos(),p); Vector intersection = AdjustPtToRectOnLine(Mem->MyPos(),Mem->TheirPenaltyArea,l); if ( intersection != Mem->MyPos() && l.InBetween(intersection,Mem->MyPos(),p) ){ /* Need to go around the rectangle */ Mem->LogAction2(40, "go_to_point: moving around penalty area"); Vector target; if ( Mem->MyX() < Mem->TheirPenaltyArea.LeftX() ) target = Vector(Mem->TheirPenaltyArea.LeftX()-3,p.y); else if ( Mem->MyY() > 0 ) target = Vector(Mem->TheirPenaltyArea.LeftX()-3,Mem->TheirPenaltyArea.BottomY()+3 ); else target = Vector(Mem->TheirPenaltyArea.LeftX()-3,Mem->TheirPenaltyArea.TopY()-3 ); go_to_point( target, 0, dash_power, dodge ); return AQ_ActionQueued; } } if ( Mem->PlayMode != PM_Play_On && Mem->TeamInPossession() == Mem->TheirSide && !Mem->OffsidePosition(p,Mem->MySide) && //p.dist(Mem->BallAbsolutePosition()) > Mem->SP_free_kick_buffer && Mem->InOffsidePosition() && Mem->BallDistance() < Mem->SP_free_kick_buffer+1 ){ Mem->LogAction2(40, "go_to_point: moving around free_kick area"); if ( Mem->BallY() > Mem->MyY() ) go_to_point(Vector(Mem->MyX(),Mem->BallY()-(Mem->SP_free_kick_buffer+1))); else go_to_point(Vector(Mem->MyX(),Mem->BallY()+(Mem->SP_free_kick_buffer+1))); return AQ_ActionQueued; } float target_ang = GetNormalizeAngleDeg((p - Mem->MyPredictedPosition()).dir() - Mem->MyBodyAng()); float target_dist = Mem->DistanceTo(p); if ( dodge != DT_none ){ /* dodge players */ PlayerObject *player; float dodge_dist = Min(Mem->CP_dodge_distance_buffer,target_dist); AngleDeg dodge_ang = Mem->CP_dodge_angle_buffer; if ( (player = Mem->GetPlayerWithin( dodge_dist, dodge_ang, 0, target_ang - dodge_ang)) != NULL && (dodge!=DT_unless_with_ball || (Mem->BallPositionValid() && player->get_abs_pos().dist(Mem->BallAbsolutePosition()) > Mem->SP_kickable_area)) && (dodge!=DT_only_with_ball || (Mem->BallPositionValid() && player->get_abs_pos().dist(Mem->BallAbsolutePosition()) <= Mem->SP_kickable_area)) ){ Mem->LogAction2(40, "go_to_point: dodging right"); /*if ( Mem->NumPlayersWithin( dodge_dist, 2*dodge_ang) ){*/ /* Target at dist player_size, so no players will be within in the next iteration ==> dash */ Vector new_target = Mem->BodyPolar2Gpos(Mem->SP_player_size,player->get_ang_from_body() + Mem->CP_dodge_angle); if ( new_target == p ) my_error("Dodging isn't changing the point!"); go_to_point(new_target,0,Mem->CP_dodge_power,DT_none); /*} else{ dash(Mem->CorrectDashPowerForStamina(Min(dash_power,Mem->CP_dodge_power))); }*/ return AQ_ActionQueued; } if ( (player = Mem->GetPlayerWithin( dodge_dist, dodge_ang, 0, target_ang + dodge_ang)) != NULL && (dodge!=DT_unless_with_ball || (Mem->BallPositionValid() && player->get_abs_pos().dist(Mem->BallAbsolutePosition()) > Mem->SP_kickable_area)) && (dodge!=DT_only_with_ball || (Mem->BallPositionValid() && player->get_abs_pos().dist(Mem->BallAbsolutePosition()) <= Mem->SP_kickable_area)) ){ Mem->LogAction2(40, "go_to_point: dodging left"); /*if ( Mem->NumPlayersWithin( dodge_dist, 2*dodge_ang) ){*/ /* Target at dist player_size, so no players will be within in the next iteration ==> dash */ Vector new_target = Mem->BodyPolar2Gpos(Mem->SP_player_size,player->get_ang_from_body() - Mem->CP_dodge_angle); if ( new_target == p ) my_error("Dodging isn't changing the point!"); go_to_point(new_target,0,Mem->CP_dodge_power,DT_none); /*} else{ dash(Mem->CorrectDashPowerForStamina(Min(dash_power,Mem->CP_dodge_power))); }*/ return AQ_ActionQueued; } } if ( fabs(target_ang) > Mem->CP_max_go_to_point_angle_err || (Mem->PlayMode == PM_Their_Goal_Kick && Mem->TheirPenaltyArea.IsWithin(Mem->MyPredictedPosition(1,dash_power))) ){ Mem->LogAction3(50, "go_to_point: turning %f", target_ang); turn(target_ang); return AQ_ActionQueued; } dash_power = Mem->CorrectDashPowerForStamina(dash_power); if ( dash_power > 0 ){ Mem->LogAction3(50, "go_to_point: dashing %f", dash_power); dash( dash_power ); return AQ_ActionQueued; } else {my_stamp; printf("recovering\n");} Mem->LogAction2(50, "go_to_point: doing nothing?"); return AQ_ActionNotQueued;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -