📄 worldmodelhighlevel.c
字号:
//考虑到守门员一般不会冲出禁区之外截球。 if ((oppGoalie != OBJECT_ILLEGAL) && (oppGoalie == o) && (!isInTheirPenaltyArea (posBallPre))) continue; VecPosition posOpp = getGlobalPosition (o); int slowTime = 0; double dOppToMe = posAgent.getDistanceTo (posOpp); if (dOppToMe < 15) slowTime = 1; else slowTime = 2; double distOppMove = SS->getPlayerSpeedMax () * (t - slowTime); //对手在t个周期内运动的距离。 double distOppKickable = distOppMove + SS->getMaximalKickDist (); //对手的可踢范围。 double ballToOpp = posBallPre.getDistanceTo (posOpp); if (ballToOpp - distOppKickable < minDistToOpp) minDistToOpp = ballToOpp - distOppKickable; } iterateObjectDone (iIndex); if (minDistToOpp <= 0) return true; else return false;}/*! 判断球点pos是否出界。 * 如果出界返回true,否则返回false。 * */boolWorldModel::isPosOutOfCourt (VecPosition pos){ double x = pos.getX (); double y = pos.getY (); if (fabs (x) > 52.5 || fabs (y) > 34) return true; else return false;}/* find the best shooting point and the probability of goal when shot to the point. According to the method of UvA. \param posShoot : the best shooting point at the situation now. \return : the probability of goal when shot to posShoot. */doubleWorldModel::getAgentShootProbability (VecPosition & posShoot){ //it is too far. double distToGoal = getRelDistanceOpponentGoal (); if (distToGoal > 30) return -1; VecPosition posAgent = getAgentGlobalPosition (); if (fabs (posAgent.getY ()) > 20) return -2; //get the position of ball. VecPosition posBall = getBallPos (); //get the position ot goalie. ObjectT oppGoalie = getOppGoalieType (); VecPosition posGoalie = getGlobalPosition (oppGoalie); /* if (oppGoalie == OBJECT_ILLEGAL) { if (distToGoal < 16) { return 0.95; } else { return -1.1; } } else { posGoalie = getGlobalPosition(oppGoalie); } */ //get the value of 'd' : the distance between the ball and the goalie. double d = posBall.getDistanceTo (posGoalie); //get the value of 'a1' : the direction of line from ball to goalie. AngDeg a1 = (posGoalie - posBall).getDirection (); double maxp = 0, maxi = 0; //the max probability and its position. double l = -7.01, r = 7.01; //the edge of the shootable area. //there may be two shootable area on the goal line when the goalie stands at the middle of goal line. double la = 0, li = 0; bool lfind = false, rfind = false; // indicate whether the eade of shootable area is found. VecPosition posL (52.5, -7); VecPosition posR (52.5, 7); double yu = 0.90; // YU ZHI 阈值. //calculate the probability of all the points on the goal line. for (double i = -7; i <= 7; i = i + 0.1) { VecPosition posShoot (52.5, i); double p1 = 0; if (oppGoalie == OBJECT_ILLEGAL) p1 = 1; else { //get the value of 'a'. AngDeg a2 = (posShoot - posBall).getDirection (); AngDeg a = fabs (VecPosition::normalizeAngle (a1 - a2)); //calculate the value of 'u' : use 'a' and 'd'. double u = (a - 26.1) * 0.043 + (d - 9.0) * 0.09 - 0.2; //calculate the probability of ball pass the goalie. p1 = 1.0 / (1.0 + exp (-9.5 * u)); } //calculate the probability of out of goal, two items are considered: // the one is the distance between the ball and the posShoot // the other is the distance between and the edge of the goal. //double d2SP = posBall.getDistanceTo(posShoot); //double d2OutL = fabs(posShoot.getY()+7); //double d2OutR = fabs(7-posShoot.getY()); //double d2Out = (d2OutL>d2OutR) ? d2OutR : d2OutL; //calculate the probability of out of goal 'p2'. //double p2 = 1-(0.1 * fabs(i) / 7); //只考虑了射门点到球门中心的程度,且概率分布不合理。 //double p2 = 1; //不考虑球射偏的概率。 Line lineBallSP = Line::makeLineFromTwoPoints (posBall, posShoot); double sL = lineBallSP.getDistanceWithPoint (posL); double sR = lineBallSP.getDistanceWithPoint (posR); VecPosition blockPointL = lineBallSP.getPointOnLineClosestTo (posL); VecPosition blockPointR = lineBallSP.getPointOnLineClosestTo (posR); double dL = posBall.getDistanceTo (blockPointL); double dR = posBall.getDistanceTo (blockPointR); //calculate the standard deviation of Gaussian 'gdL' & 'gdR'. double gdL = -1.88 * log (1.0 - dL / 45.0); double gdR = -1.88 * log (1.0 - dR / 45.0); //calculate the probability of 'p2'. double p2 = Fi (sR / gdR) - Fi (-1 * sL / gdL); //calculate the probability of goal when shoot to posShoot double p = p1 * p2; if ((p >= yu) && rfind) //又发现一个新的可射门区间。 { if (la >= (r - l)) { lfind = false; rfind = false; continue; //当前区间较原来的小,故不保留当前区间。 } else { la = r - l; } if (la == 1) //the area is too small { la = 0; lfind = false; rfind = false; } else { lfind = false; rfind = false; li = (l + r) / 2; cout << endl << " find two areas!"; } } if (not lfind) { if (p >= yu) { l = i; lfind = true; } } else { if (p < yu) { r = i; rfind = true; } } if (p > maxp) { maxp = p; maxi = i; } } if (maxp >= yu) { if (la == 0) { posShoot = VecPosition (52.5, (l + r) / 2); } else { if (la < r - l) { posShoot = VecPosition (52.5, (l + r) / 2); } else { posShoot = VecPosition (52.5, li); cout << endl << "-----------the first shoot area is used---------------------"; } } } else { posShoot = VecPosition (52.5, maxi); } return maxp;}/* 计算标准正态分布函数的概率分布。 * \param x : 积分上限。 * return : 积分值。 * */doubleWorldModel::Fi (double x){ if (x >= 3) { return 1; } if (x <= -3) { return 0; } double fx = fabs (x); // -3 < fx < 3 double T[31] = { 0.5000, 0.5398, 0.5793, 0.6179, 0.6554, 0.6915, 0.7257, 0.7580, 0.7881, 0.8159, 0.8413, 0.8643, 0.8849, 0.9032, 0.9192, 0.9332, 0.9452, 0.9554, 0.9641, 0.9713, 0.9772, 0.9821, 0.9861, 0.9893, 0.9918, 0.9938, 0.9953, 0.9965, 0.9974, 0.9981, 0.9987 }; int pos = (int) (fx * 10); double p = (T[pos] + T[pos + 1]) / 2; if (x > 0) { return p; } else { return 1 - p; }}/*! 判断自己是否可以以 dribbleT 的方式带球。 * 今后可以改写成判断自己的某一名队友是否可以带球。 * */boolWorldModel::canDribble (AngDeg & angDribble, DribbleT dribbleT){ if (isFreeKickUs () || isCornerKickUs () || isOffsideThem ()) return false; double myStamina = getAgentStamina ().getStamina (); if (myStamina < 1400) return false; VecPosition posBall = getBallPos (); double ballx = posBall.getX (); double bally = posBall.getY (); VecPosition posLeft, posRight; if (ballx < 30) { posLeft.setVecPosition (52.5, -20); posRight.setVecPosition (52.5, 20); } else { if (bally > 20) { posLeft.setVecPosition (36, 0); posRight.setVecPosition (52.5, 0); } else if (bally < -20) { posLeft.setVecPosition (52.5, 0); posRight.setVecPosition (36, 0); } else { posLeft.setVecPosition (52.5, -7); posRight.setVecPosition (52.5, 7); } } AngDeg angLeft = (posLeft - posBall).getDirection (); AngDeg angRight = (posRight - posBall).getDirection (); AngDeg angL2R = fabs (VecPosition::normalizeAngle (angLeft - angRight)); double dDist = 10; if (dribbleT == DRIBBLE_FAST) { dDist = 20; } else if (dribbleT == DRIBBLE_SLOW) { dDist = 10; } else if (dribbleT == DRIBBLE_WITHBALL) { dDist = 8; } else cout << endl << "erro!............dribble type"; if (ballx > 34) { angDribble = (VecPosition (52.5, sign (bally) * 3) - posBall).getDirection (); } else { AngDeg angMax = 0; angDribble = getDirectionOfWidestAngle (posBall, angLeft, angRight, &angMax, dDist); } // 身边有人,不可以dribble。 if (isOpponentAtAngle (angDribble, dDist)) return false; else return true; /* if ( getNrInSetInCircle (OBJECT_SET_OPPONENTS, Circle (posBall, dDist)) > 1) return false; else if ( getNrInSetInCircle (OBJECT_SET_OPPONENTS, Circle (posBall, dDist/2)) > 0) return false; else return true; */}////////////////////////////////////////////////////////////// new pass/////////////////////////////////////////////////////////////*! 判断是否可以将球传给队友。 * param \tmt : 记录可以接球的队友; * param \angPass : 记录传球给队友tmt时应该偏的角度; * param \speedPass : 记录传球的速度; * param \posT : 接球者相对于自己的位置。 * */bool WorldModel::canSmartPassBallToTmt(ObjectT &tmt, AngDeg &angPass, double &speedPass){ tmt = OBJECT_ILLEGAL; VecPosition posAgent = getAgentGlobalPo
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -