📄 dribble_around.c
字号:
} bool ballDirOK = fabs((WSinfo::ball->vel.ARG() - WSinfo::me->ang).get_value_mPI_pPI())<PI/5; ballDirOK = ballDirOK && fabs(Tools::my_angle_to(WSinfo::ball->pos).get_value_mPI_pPI())<DEG2RAD(90); ballDirOK = ballDirOK && WSinfo::me->vel.norm() >= 0.5*WSinfo::ball->vel.norm(); if(ballDirOK && !keepBallSafe){ POL("getNextAction: Dash needed, ball seems to be going in right dir"); return DA_DASH; } /* if(bodyAngleOffALot && WSinfo::me->pos.distance(dribbleTo)>2){ // I'm running in the totally wrong direction // --> provoke collision to make dir change easier POL("getNextAction: Collision kick needed"); if(!dontKick) return DA_COLKICK; } */ // Can we get the ball in the next cycle? bool iGetBallByDoingNothing = nextMeNA.pos.distance(nextBall.pos)<maxDistToBall; bool iGetBallByDashing=false; bool iGetBallLater = fabs((WSinfo::me->ang - WSinfo::ball->vel.ARG()).get_value_mPI_pPI())<DEG2RAD(5) && WSinfo::ball->vel.norm()<1.2*WSinfo::me->speed_max; if(!iGetBallByDoingNothing){ Cmd tmpCmd; Vector new_my_pos,new_my_vel,new_ball_pos,new_ball_vel; ANGLE new_my_ang; basic_cmd->set_dash(maxSpeed); basic_cmd->get_cmd(tmpCmd); Tools::model_cmd_main(WSinfo::me->pos,WSinfo::me->vel,WSinfo::me->ang,WSinfo::ball->pos,WSinfo::ball->vel,tmpCmd.cmd_main,new_my_pos,new_my_vel,new_my_ang,new_ball_pos,new_ball_vel,false); iGetBallByDashing = new_my_pos.distance(new_ball_pos)<maxDistToBall; } if(!iGetBallByDashing && !iGetBallByDoingNothing && !iGetBallLater){ POL("getNextAction: Kick needed, can't catch Ball next cycle"); if(!dontKick) return DA_KICK; } if(ballWillLeaveField){ POL("getNextAction: Kick needed, ball will be outside field next cycle"); if(!dontKick) return DA_KICK; } POL("getNextAction: Dash needed"); return DA_DASH;}// getNextAction() {{{1DribbleAround::Action DribbleAround::getNextAction(){ ANGLE toGoal = Tools::my_angle_to(dribbleTo); bool bodyAngleOK = fabs(toGoal.get_value_mPI_pPI())<MAX_ANGLE_TO_DEST; bool bodyAngleOffALot = !bodyAngleOK && fabs(toGoal.get_value_mPI_pPI())>DEG2RAD(100); static const float maxDistToBall = 0.80*WSinfo::me->kick_radius; // check for other teammates in possession of ball WSpset team = WSinfo::valid_teammates_without_me; team.keep_and_sort_closest_players_to_point(1,WSinfo::ball->pos); bool dontKick = team.num>0 && (team[0]->pos.distance(WSinfo::ball->pos)<0.9*team[0]->kick_radius) && (team[0]->number > WSinfo::me->number); if(dontKick) POL("getNextAction: I have a lower number than teammate who also controls ball -- not kicking"); Vector inMyDir; inMyDir.init_polar(0.1,WSinfo::me->ang); switch(request){ case DAREQ_NONE: break; case DAREQ_KICK: POL("getNextAction: Kick needed: Was requested"); if(!dontKick) return DA_KICK; break; case DAREQ_DASH: if(WSinfo::me->pos.distance(nextBall.pos) > (WSinfo::me->pos+inMyDir).distance(nextBall.pos)){ POL("getNextAction: Dash needed: Was requested"); return DA_DASH; }else{ POL("getNextAction: Ignoring requested dash!"); } break; case DAREQ_TURN: if(!bodyAngleOK){ bool looseBall = nextBall.pos.distance(nextMeNA.pos)>0.9*WSinfo::me->kick_radius; bool looseBallBehind = looseBall && fabs((dribbleTo-WSinfo::me->pos).ANGLE_to(nextBall.pos-nextMeNA.pos).get_value_mPI_pPI())>DEG2RAD(100); if(!looseBallBehind){ POL("getNextAction: Turn needed: Was requested"); return DA_TURN; }else{ POL("getNextAction: Ignoring requested turn!"); } } } bool ballWillLeaveField= fabs(nextBall.pos.x)>FIELD_BORDER_X-0.5 ||fabs(nextBall.pos.y)>FIELD_BORDER_Y; if(nextMeNA.pos.distance(nextBall.pos)<maxDistToBall) // I get ball w/o moving if(!bodyAngleOK && !ballWillLeaveField){ POL("getNextAction: Turn needed, kicking first"); return DA_KICK; // TODO: Does this work? } bool ballDirOK = fabs((WSinfo::ball->vel.ARG() - WSinfo::me->ang).get_value_mPI_pPI())<PI/5; ballDirOK = ballDirOK && fabs(Tools::my_angle_to(WSinfo::ball->pos).get_value_mPI_pPI())<DEG2RAD(90); ballDirOK = ballDirOK && WSinfo::me->vel.norm() >= 0.9*WSinfo::ball->vel.norm(); if(ballDirOK){ POL("getNextAction: Dash needed, ball seems to be going in right dir"); return DA_DASH; } if(bodyAngleOffALot && WSinfo::me->pos.distance(dribbleTo)>2){ // I'm running in the totally wrong direction // --> provoke collision to make dir change easier POL("getNextAction: Collision kick needed"); if(!dontKick) return DA_COLKICK; } // Can we get the ball in the next cycle? bool iGetBallByDoingNothing = nextMeNA.pos.distance(nextBall.pos)<maxDistToBall; bool iGetBallByDashing = false; bool iGetBallLater = fabs((WSinfo::me->ang - WSinfo::ball->vel.ARG()).get_value_mPI_pPI())<DEG2RAD(5) && WSinfo::ball->vel.norm()<1.2*WSinfo::me->speed_max; if(!iGetBallByDoingNothing){ Cmd tmpCmd; Vector new_my_pos,new_my_vel,new_ball_pos,new_ball_vel; ANGLE new_my_ang; basic_cmd->set_dash(maxSpeed); basic_cmd->get_cmd(tmpCmd); Tools::model_cmd_main(WSinfo::me->pos,WSinfo::me->vel,WSinfo::me->ang,WSinfo::ball->pos,WSinfo::ball->vel,tmpCmd.cmd_main,new_my_pos,new_my_vel,new_my_ang,new_ball_pos,new_ball_vel,false); iGetBallByDashing = new_my_pos.distance(new_ball_pos)<maxDistToBall; } if(!iGetBallByDashing && !iGetBallByDoingNothing && !iGetBallLater){ POL("getNextAction: Kick needed, can't catch Ball next cycle"); if(!dontKick) return DA_KICK; } if(ballWillLeaveField){ POL("getNextAction: Kick needed, ball will be outside field next cycle"); if(!dontKick) return DA_KICK; } POL("getNextAction: Dash needed"); return DA_DASH;}// get_cmd() {{{1bool DribbleAround::get_cmd(Cmd& cmd){ // avoid acting upon aged kickRequests if(WSinfo::ws->time != requestTime+1){ setRequest(DAREQ_NONE); } if(!didDribble){ setRequest(DAREQ_NONE); } neckReqSet=false; dribbleInsecure=false; // trivial cases 1st: if(!WSinfo::is_ball_kickable()){ POL("Ball not kickable -> intercept"); return intercept->get_cmd(cmd); } /* if(getGoalieKickCmd(cmd)){ POL("Trying to shoot goal"); return true; } */ if((WSinfo::me->pos - WSinfo::ball->pos).norm()<0.385) POL("Collision with ball. Danger. Doing nothing against it!"); static PPlayer lastOpp = NULL; static int lastOppInMeCount = 0; opp = getRelevantOpponent(); if(opp && opp==lastOpp && opp->pos.distance(WSinfo::me->pos)<.8*WSinfo::me->kick_radius) lastOppInMeCount++; else lastOppInMeCount=0; lastOpp = opp; if(lastOppInMeCount>3){ POL("get_cmd: Last Opp has been close to me for too long!"); dribbleInsecure = true; }else{ //POL("lastOppInMeCount = "<<lastOppInMeCount); } if(opp && WSinfo::ws->time - opp->time > 1 && Tools::could_see_in_direction((opp->pos-WSinfo::me->pos).ARG())){ POL("get_cmd: Haven't seen opp in 1 cycle: Setting neck request"); neckReqSet=true; neckReq = (opp->pos-WSinfo::me->pos).ARG(); // Tools::set_neck_request(NECK_REQ_LOOKINDIRECTION, (opp->pos-WSinfo::me->pos).ARG()); } nextBall.setAssumeNoAction(WSinfo::ball); nextMeNA.setAssumeNoAction(WSinfo::me,nextBall.pos); Vector __ang; MARK_PPLAYER(WSinfo::me,#00FFFF); Action nextAction; if(opp){ nextOppNA.setAssumeNoAction(opp,nextBall); nextOppToBall.setAssumeToPos(opp,nextBall); nextOppToMe.setAssumeToPos(opp,nextMeNA); MARK_PPLAYER(opp,red); MARK_STATE(nextOppNA, #AAAAAA); MARK_STATE(nextOppToMe,#666666); MARK_BALL(nextBall,#AAAAAA); nextAction = getNextAction(opp); } else{ MARK_BALL(nextBall,#AAAAAA); nextAction = getNextAction(); } bool res = false; switch(nextAction){ case DA_TACKLE: res= getTackleCmd(cmd); break; case DA_KICK: res= getKickCmd(cmd); break; case DA_TURN: res= getTurnCmd(cmd); break; case DA_DASH: res= (getDashCmd(cmd)||getKickCmd(cmd)); break; case DA_COLKICK: res= getColKickCmd(cmd); break; case DA_GOALK: res= getGoalieKickCmd(cmd)||getKickCmd(cmd); break; } if(opp&& opp->number == WSinfo::ws->his_goalie_number){ POL("get_cmd: Goalie direct opponent, dribbling is unsafe!"); dribbleInsecure=true; } if(opp&&nextOppToMe.movedToAvoidCollision){ POL("get_cmd: nextOppToMe movedToAvoidCollision, dribbling is unsafe!"); dribbleInsecure=true; } // never reached!? return res;}// getCmd: Dash, Turn, Tackle {{{1// getTurnCmd {{{2bool DribbleAround::getTurnCmd(Cmd& cmd){ lastActionTaken=DA_TURNING; POL("getTurnCmd: Turning to dribbleTo."); basic_cmd->set_turn_inertia(Tools::my_angle_to(dribbleTo).get_value()); Vector new_my_pos,new_my_vel,new_ball_pos,new_ball_vel; ANGLE new_my_ang; Tools::model_cmd_main(WSinfo::me->pos,WSinfo::me->vel,WSinfo::me->ang,WSinfo::ball->pos,WSinfo::ball->vel,cmd.cmd_main,new_my_pos,new_my_vel,new_my_ang,new_ball_pos,new_ball_vel,false); basic_cmd->get_cmd(cmd); // TODO: set again request if criteria match. Work out criteria bool isMyAngleAfterTurnOK = fabs((dribbleTo - new_my_pos).ARG().get_value_mPI_pPI())<MAX_ANGLE_TO_DEST; bool isBallDirOK = fabs((WSinfo::ball->vel.ARG()-(dribbleTo-WSinfo::ball->pos).ARG()).get_value_mPI_pPI())<MAX_ANGLE_TO_DEST; bool isBallSpeedCatchUpable = WSinfo::ball->vel.norm()<1.; if(isBallDirOK && !isMyAngleAfterTurnOK && isBallSpeedCatchUpable) setRequest(DAREQ_TURN); else if(isBallDirOK) setRequest(DAREQ_DASH); return true;}// getDashCmd {{{2bool DribbleAround::getDashCmd(Cmd& cmd){ float distToBall; static const float minDistToBall = 0.15+(ServerOptions::player_size + ServerOptions::ball_size); static const float maxDistToBall = .8*WSinfo::me->kick_radius; Vector inMyDir; inMyDir.init_polar(0.3,WSinfo::me->ang); bool isBallDirOK = fabs((WSinfo::ball->vel.ARG()-(dribbleTo-WSinfo::ball->pos).ARG()).get_value_mPI_pPI())<MAX_ANGLE_TO_DEST; bool isBallSpeedCatchUpable = WSinfo::ball->vel.norm()<2.; bool isBallPosOK = WSinfo::me->pos.distance(nextBall.pos) > (WSinfo::me->pos+inMyDir).distance(nextBall.pos); bool ballBehind = fabs(Tools::my_angle_to(WSinfo::ball->pos).get_value_mPI_pPI())>DEG2RAD(100); bool amIOutsideField = fabs(WSinfo::me->pos.x)>FIELD_BORDER_X ||fabs(WSinfo::me->pos.y)>FIELD_BORDER_Y; bool dontCareAboutMaxDist = isBallDirOK && isBallSpeedCatchUpable && !ballBehind; if(maxSpeed==0){ POL("getDashCmd: Cannot dash: maxSpeed=0"); return false; } if(request == DAREQ_DASH){ POL("getDashCmd: Returning requested dash maxSpeed="<<maxSpeed); basic_cmd->set_dash(maxSpeed); return basic_cmd->get_cmd(cmd); } int canDash = 0; Cmd tmpCmd; Vector new_my_pos,new_my_vel,new_ball_pos,new_ball_vel; ANGLE new_my_ang; bool isOutsideField; for(int i = 70; i<=maxSpeed; i+=10){ tmpCmd.cmd_main.unset_lock(); basic_cmd->set_dash(i); basic_cmd->get_cmd(tmpCmd); Tools::model_cmd_main(WSinfo::me->pos,WSinfo::me->vel,WSinfo::me->ang,WSinfo::ball->pos,WSinfo::ball->vel,tmpCmd.cmd_main,new_my_pos,new_my_vel,new_my_ang,new_ball_pos,new_ball_vel,false); isOutsideField = fabs(new_my_pos.x)>FIELD_BORDER_X ||fabs(new_my_pos.y)>FIELD_BORDER_Y; if(!amIOutsideField && isOutsideField) continue; // dont dash outside field distToBall = (new_my_pos-new_ball_pos).norm(); if( ((distToBall <= maxDistToBall)// play it safe ||dontCareAboutMaxDist) // vorgelegt && distToBall > minDistToBall) // avoid collision canDash = i; } if(canDash==0) { POL("getDashCmd: Cannot dash."); lastActionTaken=DA_NO_ACTION; return false; } bool ballDirOK = fabs((WSinfo::ball->vel.ARG() - WSinfo::me->ang).get_value_mPI_pPI())<PI/5; if(ballDirOK && ballBehind && canDash<60){ POL("getDashCmd: BallDir OK and I can dash only little --> rather kick"); lastActionTaken=DA_NO_ACTION; return false; } POL("getDashCmd: Dashing with power "<<canDash); lastActionTaken=DA_DASHING; basic_cmd->set_dash(canDash); return basic_cmd->get_cmd(cmd);}// getColKickCmd {{{2/* * Return a kick that is prone to collide with me in the next cycle * thus giving me the possibility to turn afterwards * (ball aint movin and me neither) */bool DribbleAround::getColKickCmd(Cmd& cmd){ Vector toGoal = dribbleTo - nextMeNA.pos; toGoal.normalize(0.5 * ServerOptions::player_size); Vector dest = toGoal + nextMeNA.pos; lastActionTaken=DA_COLLISION_KICK; setRequest(DAREQ_TURN); return getCmdKickToDest(cmd,dest,true,true);}// getTackleCmd {{{2bool DribbleAround::getTackleCmd(Cmd& cmd){ Vector tackleTo; tackleTo.init_polar(4,WSinfo::me->ang.get_value()); tackleTo+=WSinfo::ball->pos; if(tackleTo.distance(MY_GOAL_CENTER)> WSinfo::ball->pos.distance(MY_GOAL_CENTER)) basic_cmd->set_tackle(100); else basic_cmd->set_tackle(-100); lastActionTaken=DA_TACKLING; return basic_cmd->get_cmd(cmd);}// getCmd: Kicks {{{1// getKickCmd {{{2bool DribbleAround::getKickCmd(Cmd& cmd){ POL2("In getKickCmd()"); ANGLE toGoal = Tools::my_angle_to(dribbleTo); bool bodyAngleOK = fabs(toGoal.get_value_mPI_pPI())<MAX_ANGLE_TO_DEST; if(bodyAngleOK) return getKickAhead(cmd); else return getKickForTurn(cmd) || getKickAhead(cmd);}// getKickAhead {{{2bool DribbleAround::getKickAhead(Cmd& cmd){ POL2("In getKickAhead()"); ANGLE toBall = Tools::my_angle_to(WSinfo::ball->pos); ANGLE toOpp = opp?Tools::my_angle_to(opp->pos):ANGLE(0); double toBallFl = toBall.get_value_mPI_pPI(); double toBallFlAbs = fabs(toBallFl); double toOppFl = toOpp.get_value_mPI_pPI(); double distToOpp = opp?WSinfo::me->pos.distance(opp->pos):1000; bool isBallOnLeftSide = (toBallFl>0); bool ballChangeSidePossible = true || (WSinfo::ball->pos.distance(WSinfo::me->pos)>.4) && ( (toBallFlAbs<DEG2RAD(50)) ||(toBallFlAbs>DEG2RAD(130))); bool oppOnLeftSide = opp && Tools::my_angle_to(opp->pos).get_value_mPI_pPI()>0; bool oppStraightAhead = opp && fabs(Tools::my_angle_to(opp->pos).get_value_mPI_pPI())<DEG2RAD(4); bool oppStraightBehind = opp && fabs(Tools::my_angle_to(opp->pos).get_value_mPI_pPI())>DEG2RAD(170); bool oppOnMyLine = opp && (oppStraightAhead || oppStraightBehind); bool amICloseToFieldXBorder = FIELD_BORDER_X-fabs(WSinfo::me->pos.x)<WSinfo::me->kick_radius; bool amICloseToFieldYBorder = FIELD_BORDER_Y-fabs(WSinfo::me->pos.x)<WSinfo::me->kick_radius; bool isFieldBorderOnLeftSide = (amICloseToFieldXBorder && ((WSinfo::me->ang.get_value_mPI_pPI()<0 && WSinfo::me->pos.x>0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -