?? skill.cpp
字號:
num = selectPass(num); clearDist = (WM->getBallGlobalPos()-WM->getTeammateGlobalPos(num)).Length(); clearForce = calGroundKickForce(clearDist); } //in dangerous area,clear using full force! Rectangle danagerArea(WM->getOurBaseLine(),half_penalty_width,WM->getOurBaseLine()+20.0f,-half_penalty_width); if ( danagerArea[posBall] ) clearForce = max_kick_force; Action kickAction; kickAction.setTime(kickTime); kickAction.setKick(calClearAngle(),clearForce); for ( Step i=0; i<step_num_per_cycle; i+=step_num_per_kick ) { kickAction.setTime( kickTime + i ); clearAction += kickAction; } } Action driveAction = interceptClearBall(); clearAction += driveAction; return clearAction;}/*! calculate which angle should clear, suitations consider: 1. if clear back, angle should large 2. if opponent hold in the clear way, angle should enough large to over him 3. else choose a small angle to clear far away*/AngDeg Skill::calClearAngle() const{ AngDeg clearAng = 0; Vector3f posOpp = WM->getOpponentGlobalPos(WM->getClosestOppNum2Ball()); if ( isThreePointOneLine(WM->getMyGlobalPos(), WM->getBallGlobalPos(), posOpp, 5.0f ) ) { clearAng += 30.0f; } const AngDeg angK = 10.0f;//0.21f;//gene1[0];//10.0f; float posOppDist = (posOpp-WM->getBallGlobalPos()).Length(); if ( posOppDist < 5 && isThreePointOneLine(WM->getMyGlobalPos(), WM->getBallGlobalPos(), posOpp, 60.0f ) ) { clearAng += (5-posOppDist)*angK; } float dist2OurGoal = ( WM->getBallGlobalPos() - WM->getOurGoalCenter() ).Length(); if ( dist2OurGoal < max_kick_distance && isKickDirectionDanagerous() ) { clearAng = max_kick_angle; } float dist2OppGoal = ( WM->getBallGlobalPos()-WM->getOppGoalCenter()).Length(); if ( dist2OppGoal > 20 && dist2OppGoal < 30 ) { clearAng = max_kick_angle; } //AngDeg clearAng = -WM->getBallGlobalPos().x()/WM->getFieldLength()*100; AngDeg minClearAng = 20.0f;//min_kick_angle;//20.0f; if ( (WM->getBallGlobalPos()-WM->getOppGoalCenter()).Length()<20 ) minClearAng = 10;//0 clearAng = setMaxNMin(clearAng,max_kick_angle,minClearAng); return clearAng;}/*! this function return whether the ball will be kick to our own goal \return the current kick direction is in our own goal?*/bool Skill::isKickDirectionDanagerous() const{ Vector3f posBias(0.0, 1.0, 0.0); return shoudIKick(WM->getOurGoalRight()-posBias,WM->getOurGoalLeft()+posBias);}/*! this function return false in some suitation: (the ball will be cleared to our own goal!) 1. too near the our goal 2. not too close, but the lofted ball will fall on ground just near the goal 3. if I am free, I have enough time to turn and kick to opp's goal \return can clear the ball in current suitation*/bool Skill::canIClear() const{ Vector3f posBall = WM->getBallGlobalPos(); //-* I am free :) const Rectangle rectCenter(WM->getOurBaseLine(),15,WM->getOurBaseLine()+20,-15); AngDeg attackDir = getVector3fHorizontalAng(WM->getOppGoalCenter()-posBall ); const float freeBias = 3;//gene1[2];//0.3f if ( ( WM->getMyFreedom() > cosDeg(WM->getMyKickHorizontalAng()-attackDir)*10.0f+freeBias) || ( WM->getMyFreedom()>4 && abs(WM->getMyKickHorizontalAng()) > 45 ) //|| ( (WM->getMyGlobalPos().x()+0.1)>WM->getBallGlobalPos().x() && FM->getMyType() > PT_MIDFIELDER_SWEEPER ) || ( WM->getBallGlobalPos().x()<(WM->getOurBaseLine()+20) && abs(WM->getMyGlobalPos().y())>(abs(WM->getBallGlobalPos().y())+0.2) && !rectCenter[posBall]) ) { return false; } //-* the kick direction is danagerous? if ( !isKickDirectionDanagerous() ) return true; //-* is the ball just in front of the goal? const Rectangle rectGoalFront(WM->getOurBaseLine(),half_goal_width,WM->getOurBaseLine()+0.5f,-half_goal_width); if ( rectGoalFront[posBall] && FM->getMyType() != PT_GOALKEEPER ) return false; //-* will the lofted ball fall into our goal? const float bigRange = 20.0f;//11.0f; const float smallRange = 9.0f;//3.0f; const Rectangle rectGoalBig(WM->getOurBaseLine(),half_goal_width+bigRange,WM->getOurBaseLine()+bigRange,-half_goal_width-bigRange); const Rectangle rectGoalSmall(WM->getOurBaseLine(),half_goal_width+smallRange,WM->getOurBaseLine()+bigRange,-half_goal_width-smallRange); if ( rectGoalBig[posBall] && !rectGoalSmall[posBall] ) return false; return true;}/*! this is function define how the goalie defend the goal 1. if the ball is not in shootBox, run strategic pos 2. if opp is near the ball and ready to shoot, run to the def-shoot point 3. if the ball is fast and heading to goal, run to the def-shoot point 4. default is run to the biesection's position \return defend goal's actions*/Actions Skill::defendGoal() const{ const float closeShootBoxL = 5;//gene1[3];//5 const float closeShootBoxW = half_goal_width+1.5f; Rectangle closeShootBox(WM->getOurBaseLine(),closeShootBoxW,WM->getOurBaseLine()+closeShootBoxL,-closeShootBoxW); if ( ( closeShootBox[WM->getInterceptBallPos()] || closeShootBox[WM->getBallGlobalPos()] ) && ( !WM->isInDefencePos(2) && !WM->isInDefencePos(3) && !WM->isInDefencePos(4) ) ) { LOG( 19,"too near the goal, trying clear it"); return clearBall(); } Actions defendGoalActions; Vector3f posMe = WM->getMyGlobalPos(); Vector3f ourGoal = WM->getOurGoalCenter(); Vector3f ourGoalLeft = WM->getOurGoalLeft(); Vector3f ourGoalRight = WM->getOurGoalRight(); Vector3f posBall = WM->getBallGlobalPos(); Vector3f velBall = WM->getBallGlobalVel(); //float speedBall = velBall.Length(); //AngDeg angBall = getVector3fHorizontalAng(velBall); AngDeg angBall = getVector3fHorizontalAng(WM->getInterceptBallPos()-posBall); unsigned int oppNum = WM->getClosestOppNum2Ball(); Vector3f posOpp = WM->getOpponentGlobalPos(oppNum); float opp2Ball = ( posOpp - posBall ).Length(); AngDeg angBias = 5; AngDeg angLeft = getVector3fHorizontalAng( ourGoalLeft - posBall )-angBias; AngDeg angRight = getVector3fHorizontalAng( ourGoalRight - posBall )+angBias; Vector3f shoot = posBall - posOpp; AngDeg angShoot = getVector3fHorizontalAng(shoot); float distShoot = min((ourGoalLeft - posBall).Length(),(ourGoalRight - posBall).Length()); //distShoot -= 0.5; Vector3f posDef; //-* kick action if ( canIClear()) { Action kickAction; Time kickTime = WM->getRealTime(); kickAction.setKick(max_kick_angle,max_kick_force); for ( Step i=0; i<step_num_per_cycle; i+=step_num_per_kick ) { kickAction.setTime( kickTime+i ); defendGoalActions += kickAction; } } //-* drive action Action driveAction; Rectangle shootBox(WM->getOurBaseLine(),penalty_width,WM->getOurBaseLine()+penalty_length+10,-penalty_width); if ( shootBox[posBall]) { const float shootDistOpp = 0.5;//gene1[4];//1 if ( opp2Ball < shootDistOpp && WM->isBallStop()//speedBall < 1 && isAngInInterval(angShoot,angLeft,angRight) ) { LOG( 19,"opp is ready for shooting"); posDef = pol2xyz(Polar(distShoot,angShoot,0.0f)) + posBall; } else if ( isAngInInterval(angBall,angLeft,angRight) ) { LOG( 19,"opp has shooted"); LOG( 19,"ball's direction angle: %f",angBall); LOG( 19,"posMe: %f, %f, %f",posMe.x(),posMe.y(),posMe.z()); posDef = pol2xyz(Polar(distShoot,angBall,0.0f)) + posBall; } else { LOG( 19,"prepare for defneding goal"); AngDeg angHalf = getBisectorTwoAngles(angLeft,angRight); posDef = pol2xyz(Polar(distShoot,angHalf,0.0f)) + posBall; } posDef.z() = WM->getMyRadius(); posDef = setInterceptPosBeforeGoal(posDef); LOG( 19,"posBall:(%f, %f, %f)",posBall.x(),posBall.y(),posBall.z()); LOG( 19,"posDef:(%f, %f, %f)",posDef.x(),posDef.y(),posDef.z()); driveAction = runTo(posDef,Vector3f(0,0,0)); //driveAction = dashTo(posDef); } else { driveAction = runStrategicPos(); } defendGoalActions += driveAction; return defendGoalActions;}/*! pass skill using calGroundPassForce\param teammateNum the teammate's num\return pass actions (include drive and skill)*/Actions Skill::pass( Num teammateNum ) const{ Vector3f posTeammate = WM->getTeammateGlobalPos(teammateNum); Vector3f posBall = WM->getBallGlobalPos(); Vector3f posBias = WM->getOppGoalCenter() - posTeammate; posBias.Normalize(); posBias*=(0.3*(posBall-posTeammate).Length()); Vector3f posAttack = posTeammate+posBias; //float kickForce = calGroundKickForce((attack-posBall).Length()); float passDist = (posAttack-posBall).Length(); float kickForce = calGroundKickForce(passDist); AngDeg kickAng = calPassAng(passDist); AngDeg dir = abs(WM->getMyKickHorizontalAng()); if ( dir > 100 ) {//back pass kickForce *= (1+0.3*cosDeg(dir))*0.8; } else { kickForce /=cosDeg(kickAng); } Vector3f posOppGoal = WM->getOppGoalCenter(); AngDeg angCanKick = abs(getClipAng(posBall,posOppGoal,posTeammate)); if ( angCanKick > 15 && angCanKick < 30 ) { return kickBetween(posOppGoal,posTeammate,kickForce,kickAng); } else { return kickTo(posAttack,kickForce,kickAng,15); } //return kickTo(posAttack,kickForce,kickAng,30); //return kickBetween(posAttack+posBias,posTeammate,kickForce);}/*! the idea is want the player can pass as fast as possible 1.find the fastPass teammate, who do not need long adjusting time 2.pass to fastPass teammate\return the pass actions*/Actions Skill::fastPass(Num num)const{ float myFreedom = WM->getMyFreedom(); if ( ( myFreedom<3)//0 )//|| (myFreedom<2&&WM->getMyFreedomChange()<0) ) //&& ( !WM->isSpaceAhead(1,1) ) ) { return oneTouch( num ); } if ( myFreedom<5 ) { num = selectPass( num ); } return pass(num);}Actions Skill::oneTouch(Num num)const{ num = selectPass(num); return safePass(num); Vector3f aim = WM->getTeammateGlobalPos(num); Vector3f posBall = WM->getBallGlobalPos(); float kickDist = (aim-posBall).Length(); float force = calGroundKickForce(kickDist); AngDeg kickAng = calPassAng(kickDist); AngDeg dir = abs(WM->getMyKickHorizontalAng()); if ( dir > 100 ) {//back pass force *= (1+0.5*cosDeg(dir))*0.8; } else { force /=cosDeg(kickAng); } return kickTo(aim,force,kickAng,500);}Num Skill::selectPass( Num num)const{ float kickDir = WM->getMyKickHorizontalAng(); float minErr = 60; float minDist = 25; Vector3f posBall = WM->getBallGlobalPos(); for ( Num i=6; i<=teammates_num; i++) { Vector3f posTeammate = WM->getTeammateGlobalPos(i); Polar pol = xyz2pol(posTeammate - posBall); if ( FM->getPlayerType(i) >= PT_MIDFIELDER_SWEEPER //&& WM->calOurFreedom(i) > 0 //&& posTeammate.x() > posBall.x() - 9 && pol.distance < minDist && pol.distance > 1 && abs(normalizeAngle(pol.theta-kickDir)) < minErr ) { num = i; minErr = setMaxNMin(abs(normalizeAngle(pol.theta-kickDir)),minErr,30.0f); minDist = pol.distance; } } return num;}Actions Skill::fastDribble(const Vector3f &goal) const{ Actions act; Action drive; Action kick; Time actTime = WM->getRealTime(); Vector3f posBall = WM->getBallGlobalPos(); Vector3f posMe = WM->getMyGlobalPos(); Vector3f velBall = WM->getBallGlobalVel(); Vector3f velMe = WM->getMyGlobalVel(); Vector3f posIntercept = WM->getInterceptPos(goal); kick.setKick(0,3.5f); for ( int i = 0; i < 20; i ++ ) { kick.setTime( actTime + i ); act += kick; } Vector3f direction = posIntercept - posMe; direction = direction.Normalized() * max_drive_force; drive.setDriveForce(direction); drive.setTime( actTime ); act += drive; return act;}AngDeg Skill::calPassAng(const float passDist)const{ AngDeg passAng = 0; float kickDir = WM->getMyKickHorizontalAng(); float minErr = 45; float maxDist = min(10.0f,passDist); Vector3f posBall = WM->getBallGlobalPos(); Num num = 0; float oppDist=maxDist; for ( Num i=1; i<=opponents_num; i++) { Vector3f posOpp = WM->getOpponentGlobalPos(i); Polar pol = xyz2pol(posOpp - posBall); if ( pol.distance < maxDist && abs(normalizeAngle(pol.theta-kickDir)) < minErr ) { num = i; oppDist = pol.distance; minErr = abs(normalizeAngle(pol.theta-kickDir)); } } if ( 0==num ) { passAng = 0; } else { passAng = 30*cosDeg(minErr); if ( oppDist < 5 ) passAng+=5; if ( oppDist < 3 ) passAng+=5; if ( oppDist < 1 ) passAng+=10; } passAng = setMaxNMin(passAng,max_kick_angle,min_kick_angle); return passAng;}/*! this action gurarantee our teammate will snatch the ball first. that means, the ball should NOT pass to opponent But, it may cost time\param teammateNum inspirer teammate's num, may not pass to him*/Actions Skill::safePass( Num teammateNum ) const{ Vector3f pos3Teammate = WM->getTeammateGlobalPos(teammateNum); if ( WM->getBallRelativePos().Length() > 2 ) { return kickTo(pos3Teammate,1.0,0,60); } Vector2f posTeammate = projection(pos3Teammate); Vector2f posOpp = projection(WM->getOpponentGlobalPos(WM->getClosestOppNum2Pos(pos3Teammate))); Vector2f posBall = projection(WM->getBallGlobalPos()); AngDeg kickDir = WM->getMyKickHorizontalAng(); Line2f kickLine = Line2f::makeLineFromPositionAndAngle(posBall,kickDir); Vector2f maxKickEnd = posBall + projection(pol2xyz(Polar(max_kick_distance,kickDir,0.0f))); Vector2f pos2Aim = maxKickEnd; Vector2f posProjection = kickLine.getPointOnLineClosestTo(posTeammate); Vector2f delta = projection(pol2xyz(Polar(1.0f,kickDir,0.0f))); Vector2f posBias1 = posProjection; Vector2f posBias2 = posProjection; while( kickLine.isInBetween(posBias1,posBall,maxKickEnd) || kickLine.isInBetween(posBias2,posBall,maxKickEnd) ) { if ( (posBias1-posTeammate).Length() < (posBias1-posOpp).Length() ) { pos2Aim = posBias1; break; } else if ( (posBias2-posTeammate).Length() < (posBias2-posOpp).Length() ) { pos2Aim = posBias2; break; } else { posBias1 += delta; posBias2 -= delta; } } float kickDist = (pos2Aim-posBall).Length(); float force = calGroundKickForce(kickDist); AngDeg kickAng = calPassAng(kickDist); return kickTo(pos3Teammate,force,kickAng,500);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -