⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 behave.c

📁 1999年卡耐基梅陇大学的2D仿真源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -