/* * FindFriendsInDanger will find friendly vessels that are in danger accordingly to the rules. * It will sort over enemy list and friend list and find the closest enemy vessel that jeopardise a friendly vessel. * Additionally it will return a list of all the friendly vessels that are in danger (for warn them). * * Accepts: * ------- * friends_list - friendly vessels list. * foe_list - enemy vessels list. * vessel_to_fire - reference to an enemy vessel that we need to shoot him. * * Returns: * ------- * Pointer to the friendly list that are in danger. */ Vessel* FindFriendsInDanger(Vessel* friends_list, Vessel* foe_list,Vessel** vessel_to_fire) { double dangerest = 1000; double euclid_distance; Vessel* vessels_in_danger = NULL; Vessel* travers_friends = friends_list; while(foe_list) { while(travers_friends) { euclid_distance = CalculateEuclideanDistance(foe_list,travers_friends); if(euclid_distance < DANGER_DISTANCE) { if(euclid_distance < dangerest||(euclid_distance == dangerest && IsCloserAngleDistance(vessels_in_danger,vessels_in_danger->next))) { dangerest = euclid_distance; Push(&vessels_in_danger,travers_friends); Push(vessel_to_fire,foe_list); } else { Append(&vessels_in_danger,travers_friends); } } travers_friends = travers_friends->next; } travers_friends = friends_list; foe_list= foe_list->next; } return vessels_in_danger; }
bool CMCTSNodeGuard::WantsToSurrender() const { if(this->m_dQ < 0.2 && CalculateEuclideanDistance(this->m_kpkOpponentPosition, this->m_kpkLevel->GetExitPosition()) > 3) { return true; } return false; }
CMCTSNodeGuard::CMCTSNodeGuard(SInfoForNodeInit info, CMCTSNodeGuard *const pkParent) :CGAMCTSNode(info, pkParent) { this->m_bLooseConditionReached = false; this->m_bWinConditionReached = false; if(PrisonerCatched(info.m_kpkActualPosition, info.m_kpkOpponentPosition)) { this->m_bWinConditionReached = true; } if(PrisonerEscaped(info.m_kpkOpponentPosition)) { this->m_bLooseConditionReached = true; } this->m_dDistanceFromPrisoner = CalculateEuclideanDistance(info.m_kpkActualPosition,info.m_kpkOpponentPosition); }
void CMCTSNodeGuard::NewRndPositionCloserToTarget(SGCoordinates2D<unsigned short> *const pkSourcePosition, const SGCoordinates2D<unsigned short> *const kpkTargetPosition) { SGCoordinates2D<unsigned short> newSourcePosition = SGCoordinates2D<unsigned short>(); multimap<double, SGCoordinates2D<unsigned short>> mmDistanceTable; for(int i = 0 ; i < (int)ECMOVES::Count; i++) { newSourcePosition = *pkSourcePosition; ECMOVES eMove = (ECMOVES)(i); switch(eMove) { case ECMOVES::UP: newSourcePosition.y--; break; case ECMOVES::DOWN: newSourcePosition.y++; break; case ECMOVES::LEFT: newSourcePosition.x--; break; case ECMOVES::RIGHT: newSourcePosition.x++; break; default : throw logic_error("value not inside the enum range"); } if(!this->m_kpkLevel->IsPositionFree(&(newSourcePosition))) { continue; } double dNewDistance = CalculateEuclideanDistance(&newSourcePosition, kpkTargetPosition); mmDistanceTable.insert(pair<double, SGCoordinates2D<unsigned short>>(dNewDistance, newSourcePosition)); } std::multimap<double, SGCoordinates2D<unsigned short>>::const_iterator pkIt = mmDistanceTable.begin(); srand((unsigned int)time(0)); int iRange = (rand() % 100); //select randomly if take the first or the second move closer to the target if(iRange > 49) { pkIt++; } *pkSourcePosition = (*pkIt).second; mmDistanceTable.clear(); }
double CMCTSNodeGuard::Simulation(const unsigned short kusNumberOfSimulations) { double dDeltaValue = 0; if(this->m_bWinConditionReached) { return 1 ; } if(this->m_bLooseConditionReached) { return 0; } SGCoordinates2D<unsigned short> guardPositionCpy(this->m_kpkActualPosition); SGCoordinates2D<unsigned short> prisonerPositionCpy(this->m_kpkOpponentPosition); //scale down the delta value calculated at each simulation step, by the distance between //the position of the guard in this node and the position of the prisoner in this node double dScaleDownFactor = (this->m_dDistanceFromPrisoner / 100); for(int i = 0; i < kusNumberOfSimulations ; i++) { NewRndPositionCloserToTarget(&guardPositionCpy, &prisonerPositionCpy); NewPositionCloserToTarget(&prisonerPositionCpy, this->m_kpkLevel->GetExitPosition(), this->m_kpkLevel); double dDistanceGuardTheft = CalculateEuclideanDistance(&guardPositionCpy, &prisonerPositionCpy); if(PrisonerCatched(&guardPositionCpy, &prisonerPositionCpy)) { dDeltaValue += 1 * (kusNumberOfSimulations - i); break; } if(PrisonerEscaped(&prisonerPositionCpy)) { break; } //if the gurd is in a diagonal position compared to the prisoner. Best //position, as it have a chance to catch it if(dDistanceGuardTheft == sqrt(2)) { dDeltaValue += 0.7 - dScaleDownFactor; continue; } dDeltaValue += 0.3 - dScaleDownFactor; } // keep the delta value between 0 and 1 dDeltaValue /= (double)kusNumberOfSimulations; return dDeltaValue; }
StepSide_e Goalkeeper::GetStepSide() { //CombinedData_t* combinedDataIterator = m_listCombinedData->m_head; //int numOfCombinedData = m_listCombinedData->GetNumberOfCombinedDatas(); static int counterSinceRobotMovedStep = 0; m_currentTime.update(); double maxAngleForStepAside; #ifdef GOALKEEPER_STEP__IF_THERE_WAS_GOOD_LOCALIZATION double angleBallPoint,angleEdgeRight,distanceRight,targetX; m_ballLocation = m_localization->GetBallLocation(); Point2DInt_s ballPoint; ballPoint.x = m_ballLocation.x; ballPoint.y = m_ballLocation.y; double edgeRight = CalculateEuclideanDistance(&ballPoint,&(FixedPoles[GOAL_RIGHT_BACK])); double edgeLeft = CalculateEuclideanDistance(&ballPoint,&(FixedPoles[GOAL_LEFT_BACK])); //cos law angleBallPoint = RAD2DEG*acos( (SIZE_OF_GOAL_IN_CM*SIZE_OF_GOAL_IN_CM - edgeRight*edgeRight - edgeLeft*edgeLeft) / (-2*edgeLeft*edgeRight)); angleEdgeRight = RAD2DEG*acos( (edgeLeft*edgeLeft - SIZE_OF_GOAL_IN_CM*SIZE_OF_GOAL_IN_CM - edgeRight*edgeRight) / (-2*SIZE_OF_GOAL_IN_CM*edgeRight)); //sin law distanceRight = (edgeRight*sin(DEG2RAD* angleBallPoint/2.0)) / (sin(DEG2RAD*(180 - angleBallPoint/2.0 - angleEdgeRight))); if (fabs(m_myLocationPtr->angle) > MAX_ANGLE_FOR_GOALKEEPER_POSITION ) { return DONT_MOVE; } if (numOfCombinedData == 0) { return DONT_MOVE; } if (counterSinceRobotMovedStep != 0) { counterSinceRobotMovedStep--; return DONT_MOVE; } if(m_currentTime - combinedDataIterator->ballLocation.time > 500*1000) { return DONT_MOVE; } m_ballLocation = m_localization->GetBallLocation(); #endif m_ballLocation = m_localization->GetBallLocation(); if (m_currentTime - m_ballLocation.time > 300 * 1000) { return DONT_MOVE; } #ifdef STEP_BY_HEAD_ANGLE if (fabs(m_myLocationPtr->angle) > 20) { return DONT_MOVE; } if (m_ballLocation.distanceFromMe > FAR_BALL_DISTANCE) { maxAngleForStepAside = MAX_ANGLE_FOR_STEP_ASIDE_FAR_DISTANCE; } else { maxAngleForStepAside = MAX_ANGLE_FOR_STEP_ASIDE_CLOSE_DISTANCE; } #ifdef DEBUG_GOALKEEPER_STEP cout << "Ball angle from me = " << m_ballLocation.angleFromMe << "\n"; #endif if (m_ballLocation.angleFromMe > maxAngleForStepAside) { #ifdef DEBUG_GOALKEEPER_STEP cout << "****************Step Right\n"; #endif counterSinceRobotMovedStep = NUM_OF_BALLS_TO_DECIDE_STEP; // wait for new balls till next step return MOVE_RIGHT_STEP; } else if (m_ballLocation.angleFromMe < -maxAngleForStepAside) { #ifdef DEBUG_GOALKEEPER_STEP cout << "****************Step Left\n"; #endif counterSinceRobotMovedStep = NUM_OF_BALLS_TO_DECIDE_STEP; // wait for new balls till next step return MOVE_LEFT_STEP; } else { return DONT_MOVE; } #endif #ifdef GOALKEEPER_STEP__IF_THERE_WAS_GOOD_LOCALIZATION /* Decide the step side */ targetX = FixedPoles[GOAL_RIGHT_BACK].x - distanceRight; #ifdef DEBUG_GOALKEEPER_STEP cout << "MyLocationX = " << m_myLocationPtr->x << " ball x = " << m_ballLocation.x << " ball y = " << m_ballLocation.y << " targetX = " << targetX << "\n"; #endif if (fabs(targetX - m_myLocationPtr->x) < 20) { return DONT_MOVE; } else if (targetX < m_myLocationPtr->x) { counterSinceRobotMovedStep = NUM_OF_BALLS_TO_DECIDE_STEP; return MOVE_LEFT_STEP; } else { counterSinceRobotMovedStep = NUM_OF_BALLS_TO_DECIDE_STEP; return MOVE_RIGHT_STEP; } #endif }