📄 memaction.c
字号:
DebugInt(printf("At BallIntercept_active max_pow: %f, max_look: %d\n", max_pow_to_use, max_lookahead)); if (PlayerSide == MySide && PlayerNum == MyNumber) *pInfo = CloseBallInterception(max_pow_to_use, max_lookahead, BallAbsolutePosition(), BallVel); if (pInfo->res == BI_None) *pInfo = ActiveCanGetThere(max_pow_to_use, max_lookahead, BallAbsolutePosition(), BallVel, PlayerSide, PlayerNum, PlayerPos, PlayerVel, PlayerAng, AngValid, (PlayerSide == MySide && PlayerNum == MyNumber)); else ;//{ printf("%d:%d Used Close Ball intercept\n",MyNumber,CurrentTime.t);}} /*****************************************************************************************/PlayerInterceptInfo* ActionInfo::GetPlayerIntInfo(char side, Unum num){ if (side == MySide) return TeamIntInfo[num]; else if (side == TheirSide) return OppIntInfo[num]; else my_error("bad side passed to GetPlayerIntInfo"); return NULL;}/*****************************************************************************************/PlayerInterceptInfo* ActionInfo::VerifyIntInfo(char side, Unum num, float dash_pow){ PlayerInterceptInfo* pInfo = GetPlayerIntInfo(side, num); if (pInfo == NULL) { my_error("Bad side or number passed to VerifyIntInfo"); return NULL; } int lookahead; switch (InterceptLookahead) { case LA_Default: lookahead = CP_max_int_lookahead; break; case LA_BestSoFar: lookahead = (IntMinCycTime == CurrentTime) ? (IntMinCyc) : CP_max_int_lookahead; break; default: lookahead = InterceptLookahead; break; break; } if ( pInfo->time != CurrentTime || fabs((pInfo->dash_pow-dash_pow))>FLOAT_EPS || (pInfo->lookahead < lookahead && !IsSuccessRes(pInfo->res)) ) { /* set the info struct */ DebugInt(printf("%d %d Data not current. Calling interception code\n", MyNumber, num)); if (pInfo->time == CurrentTime && (pInfo->dash_pow-dash_pow)<=FLOAT_EPS && (side != MySide || num != MyNumber)) my_error("Recomputing %c %d because lookahead got bigger; old: %d\tnew: %d", side,num,pInfo->lookahead, lookahead); /* let's do a real quick estimate to see if the player can make it there if player dist to ball > max ball dist will travel + max_dist we'll travel, then there's no way to get there */ if (!PlayerPositionValid(side, num)) { my_error("VerifyIntInfo: Can't give an answer if I don't know where player is"); pInfo->res = BI_Invalid; return pInfo; } DebugInt(printf("Lookahead: %d\n", lookahead)); float ball_travel = SumGeomSeries((BallVelocityValid() ? BallSpeed() : 0), SP_ball_decay, lookahead); float player_travel = SP_player_speed_max * lookahead; float play_ball_dist = (PlayerAbsolutePosition(side, num) - BallAbsolutePosition()).mod() ; if (play_ball_dist > player_travel + ball_travel) { pInfo->time = CurrentTime; pInfo->dash_pow = dash_pow; pInfo->dash_pow_to_use = dash_pow; pInfo->lookahead = lookahead; pInfo->res = BI_Failure; DebugInt(printf("Interception: %d, %d Took shortcut to decide failure\n", MyNumber, num)); } else { DebugInt(printf("Interception: %d, %d About to do actual calculation\n", MyNumber, num)); BallIntercept_active( dash_pow, lookahead, side, num, pInfo); if (IsSuccessRes(pInfo->res)) SetIntMinCyc(pInfo->numCyc); pInfo->time = CurrentTime; pInfo->dash_pow = dash_pow; pInfo->lookahead = lookahead; } } else if ( IsSuccessRes(pInfo->res) ) SetIntMinCyc(pInfo->numCyc); return pInfo;}/*****************************************************************************************/InterceptRes ActionInfo::PlayerInterceptionResult(char side, Unum num, float dash_pow){ return (VerifyIntInfo(side, num, dash_pow))->res;}/*****************************************************************************************/Bool ActionInfo::PlayerInterceptionAble(char side, Unum num, float dash_pow){ return IsSuccessRes((VerifyIntInfo(side, num, dash_pow))->res) ? TRUE : FALSE;}/*****************************************************************************************/int ActionInfo::PlayerInterceptionNumberCycles(char side, Unum num, float dash_pow){ PlayerInterceptInfo* pInfo = VerifyIntInfo(side, num, dash_pow); if (!IsSuccessRes(pInfo->res)) my_error("Trying to get number of cycles on invalid result: %c%d %d", side, num, pInfo->res); return pInfo->numCyc;}/*****************************************************************************************/Vector ActionInfo::PlayerInterceptionPoint(char side, Unum num, float dash_pow){ PlayerInterceptInfo* pInfo = VerifyIntInfo(side, num, dash_pow); if (!IsSuccessRes(pInfo->res)) my_error("Trying to get interception point on invalid result: %c%d %d", side, num, pInfo->res); return pInfo->pos; }/*****************************************************************************************/float ActionInfo::PlayerInterceptionDashPower(char side, Unum num, float dash_pow){ PlayerInterceptInfo* pInfo = VerifyIntInfo(side, num, dash_pow); if (!IsSuccessRes(pInfo->res)) my_error("Trying to get interception dash power on invalid result: %c%d %d", side, num, pInfo->res); return pInfo->dash_pow_to_use; }/*****************************************************************************************/int ActionInfo::GetInterceptionMinCyc(){ if (IntMinCycTime != CurrentTime) return -1; else return IntMinCyc;}/*****************************************************************************************/void ActionInfo::SetIntMinCyc(int newval){ if (IntMinCycTime != CurrentTime) { IntMinCycTime = CurrentTime; IntMinCyc = newval; } else if (IntMinCyc > newval) IntMinCyc = newval;}/*****************************************************************************************/void ActionInfo::SetInterceptionLookahead(int newval){ if (newval > 0 || newval == LA_Default || newval == LA_BestSoFar) { if (IntMinCycTime == CurrentTime) DebugInt(cout << "Changing lookahead mid way through computations. Could be bad" <<endl); InterceptLookahead = newval; } else { my_error("Trying to set InterceptLookahead to an invlaid value"); } }/*****************************************************************************************//*****************************************************************************************//*****************************************************************************************//* Passive interception stuff */int ActionInfo::GetClosestPointToBallPath(Vector* pPt, float* pNumCycles, Vector PlayerPos, Vector BallPos, Vector BallVel){ if (fabs(BallVel.x) < FLOAT_EPS && fabs(BallVel.y) < FLOAT_EPS) { *pPt = BallPos; *pNumCycles = 0; return 1; } Ray rBallPath(BallPos, BallVel);; *pPt = rBallPath.GetClosestPoint(PlayerPos); /* adjust point for sidelines */ Rectangle field(Vector(0,0), Vector(SP_pitch_length, SP_pitch_width)); *pPt = AdjustPtToRectOnLine(*pPt, field, LineFromRay(rBallPath)); /* Now let's reason about how far off we will be if we favor not turning */ Vector no_turn_pt; if (rBallPath.intersection(Ray(MyPos(), MyBodyAng()), &no_turn_pt)) { if (no_turn_pt.dist(*pPt) < CP_no_turn_max_dist_diff) { LogAction6(110, "BPI: using no turn interception, old: (%.1f, %.1f) new: (%.1f, %.1f)", pPt->x, pPt->y, no_turn_pt.x, no_turn_pt.y); *pPt = no_turn_pt; } } /* compute the number of cycles to get here */ *pNumCycles = 0; /* now get the number of cycles */ Vector traj = *pPt - BallPos; DebugInt(cout << "Pt: " << *pPt << "\tBallVel: " << BallVel << "\tBallPos: " << BallPos << "\ttraj: " << traj << endl); /* first decide if the ball is actually coming towards us */ if (signf(traj.x) != signf(BallVel.x) || signf(traj.y) != signf(BallVel.y)) { DebugInt(printf(" GCPTBP: Ball is goign wrong way for closest intercept!\n")); return 0; } float trajDist = traj.mod(); float velMod = BallVel.mod(); float temp = trajDist / velMod * (SP_ball_decay - 1) + 1; if (temp < 0.0) { /* ball will never make it to closest point */ /* SMURF - shoudl adjust for actual closest!!!! */ DebugInt(printf("GCPTBP: Ball will never make it to closest point, adjusting\n")); *pPt = BallPos + traj * SumInfGeomSeries(velMod, SP_ball_decay) / traj.mod(); *pNumCycles = SP_half_time; //just a big number return 1; } else *pNumCycles = log(temp) / log(SP_ball_decay); return 1;}/*****************************************************************************************/void ActionInfo::VerifyBPIInfo(){ if (BPItime == CurrentTime) return; BPItime = CurrentTime; Vector BallVel; if (!MyConf()) { my_error("Can't intercept if I don't know where I am"); BPIvalid = FALSE; return; } if (!BallPositionValid()) { my_error("Can't get to ball path if I don't know where it is"); BPIvalid = FALSE; return; } if (BallKickable()) { BPIvalid = TRUE; BPIable = TRUE; BPIdist = 0; BPIpoint = MyPos(); BPIballcyc = 0; return; } if (BallVelocityValid()) BallVel = BallAbsoluteVelocity(); else { BPIvalid = TRUE; BPIable = TRUE; BPIdist = BallDistance(); BPIpoint = BallAbsolutePosition(); BPIballcyc = 0; return; } DebugInt(printf("\nTime: %d\n", CurrentTime.t)); DebugInt(printf("At BallIntercept_passive\n")); int passRet; passRet = GetClosestPointToBallPath(&BPIpoint, &BPIballcyc, MyPos(), BallAbsolutePosition(), BallVel); DebugInt(printf("Passive Method: ret: %d\tx: %f\ty:%f\tcyc: %f\n", passRet, BPIpoint.x, BPIpoint.y, BPIballcyc)); if (passRet) { BPIvalid = TRUE; BPIable = TRUE; BPIdist = (BPIpoint - MyPos()).mod(); } else { BPIvalid = TRUE; BPIable = FALSE; } return; }/*****************************************************************************************/Vector ActionInfo::BallPathInterceptPoint(){ VerifyBPIInfo(); if (!BPIvalid) my_error("Calling BallPathInterceptionPoint when info not valid?"); return BPIpoint;}/*****************************************************************************************/Bool ActionInfo::BallPathInterceptAmIThere(float buffer){ VerifyBPIInfo(); if (!BPIvalid) my_error("Calling BallPathInterceptionAmIThere when info not valid"); return (BPIable && (MyPos() - BPIpoint).mod() <= buffer) ? TRUE : FALSE;}/*****************************************************************************************/float ActionInfo::BallPathInterceptDistance(){ VerifyBPIInfo(); if (!BPIable)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -