📄 knockorpass.c
字号:
/* knockorpass.c * CMUnited-97 (soccer client for Robocup-97) * Peter Stone <pstone@cs.cmu.edu> * Computer Science Department * Carnegie Mellon University * Copyright (C) 1997 Peter Stone * * CMUnited-97 was created by Peter Stone and Manuela Veloso * * You may copy and distribute this program freely as long as you retain this notice. * If you make any changes or have any comments we would appreciate a message. */#include "global.h"/* In this file, the choice of what to do with the ball (pass,dribble,or shoot) is made */#define WHATEVER 0#define SHOOT_DIST 30#define PASS_DEBUG 0#define PASSER_DEBUG 0/*****************************************************************************/int NoChange(char *KnockOrPass, int *BallTo){ /* only if they're assigned coming in */ return WHATEVER;}/*****************************************************************************/int AlwaysShoot(char *KnockOrPass, int *BallTo){ *KnockOrPass = 'k'; *BallTo = THEIR_GOAL; return WHATEVER;}/*****************************************************************************/int RandomOccupied(char *KnockOrPass, int *BallTo){ int MyPositionType = Mem->GetMyPositionType(); int MyPositionSide = Mem->GetMyPositionSide(); if ( Mem->GetMyPositionType() == FORWARD ){ /* If I'm forward, shoot */ *KnockOrPass = 'k'; *BallTo = THEIR_GOAL; return WHATEVER; } *KnockOrPass = 'p'; /* otherwise pass */ int OccupiedPositions[TEAM_SIZE]; int NumOccupied=0; for(int position=0; position<TEAM_SIZE; position++){ if ( position != Mem->GetMyPosition() && Mem->PositionOccupied(position) ){ OccupiedPositions[NumOccupied] = position; NumOccupied++; } } if (!NumOccupied){ /* No positions occupied, so shoot */ *KnockOrPass = 'k'; *BallTo = THEIR_GOAL; } else /* Pick a random position */ *BallTo = Mem->GetPositionPlayer(OccupiedPositions[int_random(NumOccupied)]); return WHATEVER;}/*****************************************************************************/int UnderPressure(){ if ( Mem->NumOpponentsWithin(10) || Mem->FacingBackInOwnPA() ) return TRUE; else return FALSE;}/*****************************************************************************/int ResolveConfidencesAndPreferences(int NumPrefs, int PreferenceList[], int NumMates, int teammates[], float Confidences[]){ /* Start by finding the ones with the highest confs. Then choose most preferable of those. If none on the list, see if there is another candidate from prefs with a reasonable conf */ int NumWithHighConf = 0; float HighConf = 0; int HighConfMates[NumMates]; int hurry = UnderPressure(); /*FALSE*/ if (hurry) printf("Gotta Hurry (%d)\n",Mem->MyNumber); /* Get all the highest confidences into an array */ for (int i=0; i<NumMates; i++){ /* If under pressure, only consider the facing ones */ while (hurry && NEEDTOCIRCLETOPASSTO(teammates[i])) i++; if ( i>=NumMates ) break; if (Confidences[i] > HighConf){ HighConf = Confidences[i]; NumWithHighConf = 1; HighConfMates[0] = teammates[i]; } else if (Confidences[i] == HighConf){ HighConfMates[NumWithHighConf++] = teammates[i]; } } /* If all options are bad, forget it */ if ( !NumWithHighConf ) return 0; /* If only one is best, go with it */ if ( NumWithHighConf == 1 ) return HighConfMates[0]; /* Find the most preferable of the ones with the top confidence */ for (int i=0; i<NumWithHighConf; i++) for (int j=0; j<NumPrefs; j++) if ( Mem->GetPlayerPosition(HighConfMates[i]) == PreferenceList[j] ){ return HighConfMates[i]; } /* If none were good, all options are bad*/ return 0; }/*****************************************************************/int ConsiderDTOutput(char *KnockOrPass, int *BallTo){#if 0 if ( Mem->GetPositionTypeOfMyLocation() == FORWARD ){ /* If I'm forward, shoot */ *KnockOrPass = 'k'; *BallTo = THEIR_GOAL; return WHATEVER; }#endif if ( !Mem->BallValid() || Mem->GetBallDistance() > KICK_DISTANCE ){ /* Doesn't matter -- won't get used anyway, just collecting the ball */ *KnockOrPass = 'd'; *BallTo = THEIR_GOAL; return WHATEVER; } if ( Mem->FacingBackNearOwnGoal() ||/*FacingBackInOwnPA()*/ Mem->InOwnPenaltyArea() ){ /* Similar condition in Cleartowards --- change there too */ *KnockOrPass = 'c'; if ( Mem->GetMyLocationSide() == RIGHT ) *BallTo = RC_FLAG; else *BallTo = LC_FLAG; return WHATEVER; } *KnockOrPass = 'p'; /* otherwise pass */#if PASSER_DEBUG printf("*** player %d passing *** %d *** %d *** %d ***\n", Mem->MyNumber,Mem->MyNumber,Mem->MyNumber,Mem->MyNumber);#endif int PreferenceList[TEAM_SIZE]; int NumOptions = Mem->GetMyReceiverList(PreferenceList); int hurry = UnderPressure(); #if PASSER_DEBUG if (hurry) printf("Gotta Hurry (%d)\n",Mem->MyNumber);#endif /* choose the eligible receivers */ int teammates[TEAM_SIZE]; int NumOpen = 0, teammateIndex = 0; for (int i=0; i<NumOptions; i++){ if ( Mem->PositionOccupied(PreferenceList[i]) && Mem->GetPositionPlayer(PreferenceList[i]) != Mem->MyNumber ){ int PossibleReceiver = Mem->GetPositionPlayer(PreferenceList[i]); if ( Mem-> PlayerValid(Mem->MySide,PossibleReceiver) && Mem->GetPlayerDistance(Mem->MySide,PossibleReceiver) > 10 && Mem->GetPlayerDistance(Mem->MySide,PossibleReceiver) < 50 && (!hurry || !NEEDTOCIRCLETOPASSTO(PossibleReceiver)) ) teammates[NumOpen++] = PossibleReceiver; } }#if PASSER_DEBUG printf("NumOpen: %d\n",NumOpen);#endif#if 0 int WaitForData = FALSE; for (int j=0; j<NumOpen; j++){ if ( !strcmp(Mem->GetData(teammates[j]),BLANK_DAT) ){ SAYTO(teammates[j],GIVE_DATA_MSG); /* Ping the individual for data */ WaitForData = TRUE; } }#endif/* Ask for the data, but don't wait for it */#if 0 if ( WaitForData ){ /* waiting for data: don't bother evaluating yet */ *KnockOrPass = 'd'; *BallTo = THEIR_GOAL; printf("ChooseReceiverTree returned FALSE\n"); return WHATEVER; }#endif#if 1 if ( !NumOpen ){ /* printf(" None open\n");*/ if ( hurry || (Mem->MarkerValid(THEIR_GOAL) && Mem->GetMarkerDistance(THEIR_GOAL) < SHOOT_DIST) ) *KnockOrPass = 'k'; else *KnockOrPass = 'd'; *BallTo = THEIR_GOAL; int myType = Mem->GetMyLocationsPositionType(); int mySide = Mem->GetMyLocationsPositionSide(); if ( myType <= DEFENDER && mySide == CENTER ){ if (Mem->GetMyLocationSide() == RIGHT) /* Actual side */ *BallTo = RF_FLAG; /* center backs shouldn't clear it up the middle */ else *BallTo = LF_FLAG; } if ( myType != FORWARD ) *KnockOrPass = 'c'; /* avoid players */ return WHATEVER; }#endif#if PASSER_DEBUG printf("Running the DT stuff\n");#endif /* Find the best teammate */ float Confidences[NumOpen]; /* Array to keep confidence that pass will succeed */ /* Limit the options that are considered */ /* if (NumOpen > 3) NumOpen = 3; */#if PASS_DEBUG /* Random choice among DT options */ /* int receiverIndex = int_random(NumOpen);*/ /* First choice among DT options (like WTW)*/ printf("random pass\n"); int receiverIndex = 0; int receiver = teammates[receiverIndex]; float PassSuccessConf = 1;#else int receiverIndex = FindTreeConfidences(NumOpen,teammates,Confidences); int receiver = teammates[receiverIndex]; float PassSuccessConf = Confidences[receiverIndex];#endif if ( PassSuccessConf < 0 ){ /* printf(" None will succeed\n"); */ if ( hurry || (Mem->MarkerValid(THEIR_GOAL) && Mem->GetMarkerDistance(THEIR_GOAL) < SHOOT_DIST) ) *KnockOrPass = 'k'; else *KnockOrPass = 'd'; *BallTo = THEIR_GOAL; int myType = Mem->GetMyLocationsPositionType(); int mySide = Mem->GetMyLocationsPositionSide(); if ( myType <= DEFENDER && mySide == CENTER ){ if (Mem->GetMyLocationSide() == RIGHT) /* Actual side */ *BallTo = RF_FLAG; /* center backs shouldn't clear it up the middle */ else *BallTo = LF_FLAG; } if ( myType != FORWARD ) *KnockOrPass = 'c'; /* avoid players */#if PASSER_DEBUG printf("Don't pass with confidence of %.1f\n",PassSuccessConf);#endif return WHATEVER; } else{ /* printf("ChooseReceiverTree returned %d\n",receiver); */ *BallTo = receiver; } if ( *KnockOrPass == 'p' && ( !*BallTo || *BallTo>TEAM_SIZE ) ){ printf("*BallTo = %d\n",*BallTo); my_error("Need to pass to a teammate with a valid number"); } return WHATEVER;}/*****************************************************************//* What's in a state? Want this to be as small as possible, yet meaningful--My position on the field--Teammate/opponent locations--distances + position (i.e. where on field) angle is irrelevant (sort all by distance?)--DT outputs to all teammates (do it with only passer data?)--did I pass, shoot, or dribble?--to whom?When there's a goal, record it in the file as well.Intermediate occurences? -- retain possession on next decision?*///int OldUseRL(char *KnockOrPass, int *BallTo){//// if ( !Mem->BallValid() || Mem->GetBallDistance() > KICK_DISTANCE ){// /* Doesn't matter -- won't get used anyway, just collecting the ball */// *KnockOrPass = 'd';// *BallTo = THEIR_GOAL;// return WHATEVER;// }//// *KnockOrPass = 'p'; /* otherwise pass */////#if PASSER_DEBUG// printf("*** player %d passing *** %d *** %d *** %d ***\n",// Mem->MyNumber,Mem->MyNumber,Mem->MyNumber,Mem->MyNumber);//#endif//// int PreferenceList[TEAM_SIZE];////#if 0// /* Only consider from list */// int NumOptions = Mem->GetMyReceiverList(PreferenceList); //#else// /* Consider all positions*/// int NumOptions=TEAM_SIZE;// for (int i=0; i<TEAM_SIZE; i++)// PreferenceList[i]=i;//#endif//// int hurry = UnderPressure(); //#if PASSER_DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -