📄 opptypes.cpp
字号:
/* * Copyright 2002-2005, Mersad Team, Allameh Helli High School (NODET). * * This program is free software, you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Library General Public License for more details. * * This file is created by: Mohammad Salehe * * Released on Monday 1 August 2005, 10 Mordad 1384 by Mersad RoboCup Team. * For more information please read README file.*/#include <cassert>#include <cmath>#include <iostream>#include <OppTypes.h>#include <Logger.h>#include <Degree.h>#include <Basics.h>using namespace std;#define OPPTYPES_LOG1//#define OPPTYPES_LOG3//#define OPPTYPES_LOG3#define PLAYER_EXTRA_RAND_TURN 0.02#define PLAYER_EXTRA_RAND_DASH 0.21#define PLAYER_EXTRA_RAND_KICK 0.0145// Class TypeInfovoid TypeInfo::setByPlayerType(const Param &playerParam){ playerSpeedMax = playerParam["player_speed_max"].asFloat(); staminaIncMax = playerParam["stamina_inc_max"].asFloat(); playerDecay = playerParam["player_decay"].asFloat(); inertiaMoment = playerParam["inertia_moment"].asFloat(); dashPowerRate = playerParam["dash_power_rate"].asFloat(); playerSize = playerParam["player_size"].asFloat(); kickableMargin = playerParam["kickable_margin"].asFloat(); kickRand = playerParam["kick_rand"].asFloat(); extraStamina = playerParam["extra_stamina"].asFloat(); effortMax = playerParam["effort_max"].asFloat(); effortMin = playerParam["effort_min"].asFloat();}// playerPos,ballPos,playerBodyDir are for the kick cycle.int TypeInfo::isAbleToKick(Vector playerPos, Vector ballPos, float playerBodyDir, Vector accleration, Side ourSide, const Param &serverParam){ float rate; float needPower; float randFactor; float actualKickRand; Vector bodyVector;#ifdef OPPTYPES_LOG3 LOG << " is able to kick acc=" << accleration << " bd=" << playerBodyDir << endl;#endif bodyVector = ballPos - playerPos; #ifdef OPPTYPES_LOG3 LOG << " bodyVector=" << bodyVector << endl;#endif bodyVector.rotate(-playerBodyDir); rate = (1 - 0.25 * (bodyVector.getMagnitude() - playerSize - serverParam["ball_size"].asFloat()) / kickableMargin - 0.25 * (fabs(bodyVector.getDirection()) / 180)); if (rate < 0.5) return 0;#ifdef OPPTYPES_LOG3 LOG << " rate=" << rate << endl;#endif needPower = (accleration.getMagnitude() / rate) / serverParam["kick_power_rate"].asFloat();#ifdef OPPTYPES_LOG3 LOG << " needPower=" << needPower << endl;#endif if (needPower <= serverParam["maxpower"].asFloat() && needPower >= serverParam["minpower"].asFloat()) return 2; if (ourSide == SI_LEFT) actualKickRand = serverParam["kick_rand_factor_r"].asFloat() * kickRand; else actualKickRand = serverParam["kick_rand_factor_l"].asFloat() * kickRand;#ifdef OPPTYPES_LOG3 LOG << " actualKickRand=" << actualKickRand << endl;#endif randFactor = (accleration.getMagnitude() - M_SQRT2 * actualKickRand) / accleration.getMagnitude();#ifdef OPPTYPES_LOG3 LOG << " randFactor=" << randFactor << endl;#endif if (randFactor < 0) randFactor = 1; accleration *= randFactor;#ifdef OPPTYPES_LOG3 LOG << " newacc=" << accleration << endl;#endif needPower = (accleration.getMagnitude() / rate) / serverParam["kick_power_rate"].asFloat();#ifdef OPPTYPES_LOG3 LOG << " newneedPower=" << needPower << endl;#endif if (needPower <= serverParam["maxpower"].asFloat() * (1 + PLAYER_EXTRA_RAND_KICK) && needPower >= serverParam["minpower"].asFloat() * (1 + PLAYER_EXTRA_RAND_KICK)) return 1; return 0;} // playerBodyDir is for the dash cycle.int TypeInfo::isAbleToDash(Vector playerVel, Vector playerPrevVel, float playerBodyDir, const Param &serverParam){ Vector accleration; float needPower;#ifdef OPPTYPES_LOG3 LOG << " is able to dash prevV=" << playerPrevVel << " nextV=" << playerVel << " bd=" << playerBodyDir << endl;#endif if (playerVel.getMagnitude() > playerSpeedMax) return 0; if (playerPrevVel.getMagnitude() > playerSpeedMax) return 0; accleration = (playerVel * (1 / playerDecay)) - playerPrevVel; accleration.rotate(-playerBodyDir);#ifdef OPPTYPES_LOG3 LOG << "accleration = " << accleration << endl;#endif if (accleration.getY() > 0.2) return 2; needPower = accleration.getX() / dashPowerRate; #ifdef OPPTYPES_LOG3 LOG << "power = " << needPower << endl;#endif if (needPower <= serverParam["maxpower"].asFloat() && needPower >= serverParam["minpower"].asFloat()) return 2; if (needPower <= serverParam["maxpower"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_DASH) && needPower >= serverParam["minpower"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_DASH)) return 1; return 0;}// playerBodyDir is for the dash cycle.bool TypeInfo::isMaxDash(Vector playerVel, Vector playerPrevVel, float playerBodyDir, const Param &serverParam){ Vector accleration; float needPower;#ifdef OPPTYPES_LOG3 LOG << " is max dash prevV=" << playerPrevVel << " nextV=" << playerVel << " bd=" << playerBodyDir << endl;#endif if (playerVel.getMagnitude() > playerSpeedMax) return true; accleration = (playerVel * (1 / playerDecay)) - playerPrevVel; accleration.rotate(-playerBodyDir);#ifdef OPPTYPES_LOG3 LOG << "accleration = " << accleration << endl;#endif if (accleration.getY() > 0.2) return false; needPower = accleration.getX() / dashPowerRate;#ifdef OPPTYPES_LOG3 LOG << "power = " << needPower << endl;#endif if (needPower <= serverParam["maxpower"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_DASH) && needPower >= serverParam["maxpower"].asFloat() / (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_DASH)) return true; if (needPower >= serverParam["minpower"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_DASH) && needPower <= serverParam["minpower"].asFloat() / (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_DASH)) return true; return false;}// playerVel is for the turn cycle.int TypeInfo::isAbleToTurn(Vector playerVel, float angle, const Param &serverParam){ float needMoment; needMoment = angle * (1 + playerVel.getMagnitude() * inertiaMoment);#ifdef OPPTYPES_LOG3 LOG << " is able to turn angle=" << angle << " needMoment=" << needMoment << endl;#endif if (needMoment <= serverParam["maxmoment"].asFloat() && needMoment >= serverParam["minmoment"].asFloat()) return 2; if (needMoment <= serverParam["maxmoment"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_TURN) && needMoment >= serverParam["minmoment"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_TURN)) return 1; return 0;}// playerVel is for the turn cycle.bool TypeInfo::isMaxTurn(Vector playerVel, float angle, const Param &serverParam){ float needMoment; needMoment = angle * (1 + playerVel.getMagnitude() * inertiaMoment);#ifdef OPPTYPES_LOG3 LOG << " is max turn angle=" << angle << " needMoment=" << needMoment << endl;#endif if (needMoment <= serverParam["maxmoment"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_TURN) && needMoment >= serverParam["maxmoment"].asFloat() / (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_TURN)) return true; if (needMoment >= serverParam["minmoment"].asFloat() * (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_TURN) && needMoment <= serverParam["minmoment"].asFloat() / (1 + serverParam["player_rand"].asFloat() + PLAYER_EXTRA_RAND_TURN)) return true; return false;}// Class OppTypesOppTypes::OppTypes(const CoachWorldModel *worldModel, const CoachWorldModelHistory &worldModelHistory): Task(worldModel, worldModelHistory){ int i; typesSet = false; for (i = 0; i < 11; i++) resetPlayerForFirstTime(i);}void OppTypes::resetPlayer(int uniNum){ int i; #ifdef OPPTYPES_LOG1 LOG << "OppTypes: resetPlayer " << uniNum << endl;#endif for (i = 0; i < 7; i++) { sureNot[uniNum][i] = false; sureIs[uniNum][i] = 0; } sureIs[uniNum][0] = 0.01; foundSure[uniNum] = false; foundType[uniNum] = 0;}void OppTypes::resetPlayerForFirstTime(int uniNum){ int i; #ifdef OPPTYPES_LOG1 LOG << "OppTypes: resetPlayerForFirstTime " << uniNum << endl;#endif for (i = 0; i < 7; i++) { sureNot[uniNum][i] = true; sureIs[uniNum][i] = 0; } sureNot[uniNum][0] = false; sureIs[uniNum][0] = 0.01; foundSure[uniNum] = true; foundType[uniNum] = 0;}void OppTypes::informOppChangePlayerType(unsigned playerNum){ resetPlayer(playerNum - 1);}void OppTypes::checkForTurns(){ int uniNum;#ifdef OPPTYPES_LOG1 LOG << "OppTypes: checkForTurns " << endl;#endif if (worldModelHistory.getSize() <= 2) return; if (worldModelHistory[-1]->getPlayMode() != worldModel->getPlayMode() || worldModelHistory[-1]->getVirtualPlayMode() != worldModel->getVirtualPlayMode()) return;#ifdef OPPTYPES_LOG1 LOG << "OppTypes: checking " << endl;#endif for (uniNum = 0;uniNum < 11; uniNum++) { if (foundSure[uniNum]) continue; if (worldModelHistory[-1]->getFullPlayer(TID_OPPONENT, uniNum).isAlive() && worldModel->getFullPlayer(TID_OPPONENT, uniNum).isAlive()) {// LOG << "Turn OppAlive " << uniNum + 1 << endl;// LOG << "prev ba" << worldModelHistory[-1]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() << endl;// LOG << "prev time" << worldModelHistory[-1]->getCurTime() << endl;// LOG << "curr ba" << worldModel->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() << endl;// LOG << "curr time" << worldModel->getCurTime() << endl; if (worldModelHistory[-1]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() != worldModel->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir()) informTurn(uniNum, worldModelHistory[-1]->getCurTime()); } } if (worldModelHistory.getSize() <= 3) return; for (uniNum = 0;uniNum < 11; uniNum++) { if (foundSure[uniNum]) continue; if (worldModelHistory[-1]->getFullPlayer(TID_OPPONENT, uniNum).isAlive() && worldModelHistory[-2]->getFullPlayer(TID_OPPONENT, uniNum).isAlive() && worldModel->getFullPlayer(TID_OPPONENT, uniNum).isAlive()) { if (worldModelHistory[-1]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() != worldModel->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() && worldModelHistory[-2]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() != worldModelHistory[-1]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir()) informMaxTurn(uniNum, worldModelHistory[-2]->getCurTime()); } }}void OppTypes::informTurn(int uniNum, unsigned time){ float angle; int i;#ifdef OPPTYPES_LOG2 char logString[8];#endif angle = worldModelHistory[time]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() - worldModelHistory[time + 1]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir(); angle = fabs(Degree::normalizeAngle(angle)); for (i = 0; i < 7; i++) { if (sureNot[uniNum][i]) {#ifdef OPPTYPES_LOG2 logString[i] = 'X';#endif continue; } if (!types[i].isAbleToTurn(worldModelHistory[time]->getFullPlayer(TID_OPPONENT, uniNum). getVel(), angle, worldModel->getServerParam())) {#ifdef OPPTYPES_LOG2 logString[i] = 'N';#endif sureNot[uniNum][i] = true; } else {#ifdef OPPTYPES_LOG2 logString[i] = '0';#endif } }#ifdef OPPTYPES_LOG2 logString[7] = 0; LOG << "OppTypes:informTurn p=" << uniNum + 1 << " t=" << time << " " << " angle=" << angle << " info:" << logString << endl;#endif}void OppTypes::informMaxTurn(int uniNum, unsigned time){ float angle; int i;#ifdef OPPTYPES_LOG2 char logString[8];#endif angle = worldModelHistory[time]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir() - worldModelHistory[time + 1]->getFullPlayer(TID_OPPONENT, uniNum).getBodyDir(); angle = fabs(Degree::normalizeAngle(angle)); for (i = 0; i < 7; i++) { if (sureNot[uniNum][i]) {#ifdef OPPTYPES_LOG2 logString[i] = 'X';#endif continue; } if (types[i].isMaxTurn(worldModelHistory[time]->getFullPlayer(TID_OPPONENT, uniNum). getVel(), angle, worldModel->getServerParam())) {#ifdef OPPTYPES_LOG2 logString[i] = 'Y';#endif sureIs[uniNum][i] += (100 - sureIs[uniNum][i]) * 0.20; } else {#ifdef OPPTYPES_LOG2 logString[i] = '0';#endif } }#ifdef OPPTYPES_LOG2 logString[7] = 0; LOG << "OppTypes:informMaxTurn p=" << uniNum + 1 << " t=" << time << " " << " angle=" << angle << " info:" << logString << endl;#endif}void OppTypes::checkForDashes(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -