00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "gamestateaspect.h"
00023 #include <zeitgeist/logserver/logserver.h>
00024 #include <soccer/soccerbase/soccerbase.h>
00025 #include <soccer/agentstate/agentstate.h>
00026 #include <salt/random.h>
00027
00028 using namespace oxygen;
00029 using namespace boost;
00030 using namespace std;
00031 using namespace salt;
00032
00033 GameStateAspect::GameStateAspect() : SoccerControlAspect()
00034 {
00035 mPlayMode = PM_BeforeKickOff;
00036 mTime = 0;
00037 mLeadTime = 0;
00038 mFupTime = 0;
00039 mLastModeChange = 0;
00040 mGameHalf = GH_FIRST;
00041 mScore[0] = 0;
00042 mScore[1] = 0;
00043 mMaxUnum[0] = 0;
00044 mMaxUnum[1] = 0;
00045 mLastKickOff = TI_NONE;
00046
00047 mLeftInit = Vector3f(0,0,0);
00048 mRightInit = Vector3f(0,0,0);
00049 mFinished = false;
00050 }
00051
00052 GameStateAspect::~GameStateAspect()
00053 {
00054 }
00055
00056 void
00057 GameStateAspect::UpdateTime(float deltaTime)
00058 {
00059 switch (mPlayMode)
00060 {
00061 case PM_BeforeKickOff:
00062 mLeadTime += deltaTime;
00063 break;
00064 case PM_GameOver:
00065 mFupTime += deltaTime;
00066 break;
00067 default:
00068 mTime += deltaTime;
00069 }
00070 }
00071
00072 void
00073 GameStateAspect::Update(float deltaTime)
00074 {
00075 UpdateTime(deltaTime);
00076 }
00077
00078 TPlayMode
00079 GameStateAspect::GetPlayMode() const
00080 {
00081 return mPlayMode;
00082 }
00083
00084 void
00085 GameStateAspect::SetPlayMode(TPlayMode mode)
00086 {
00087 if (mode == mPlayMode)
00088 {
00089 return;
00090 }
00091
00092 GetLog()->Normal() << "(GameStateAspect) playmode changed to "
00093 << SoccerBase::PlayMode2Str(mode) << " at t="
00094 << mTime << "\n";
00095 mPlayMode = mode;
00096 mLastModeChange = mTime;
00097 mLeadTime = 0.0;
00098 mFupTime = 0.0;
00099 }
00100
00101
00102 void
00103 GameStateAspect::KickOff(TTeamIndex ti)
00104 {
00105 if (mGameHalf == GH_FIRST)
00106 {
00107
00108 if (ti == TI_NONE)
00109 {
00110 ti = (salt::UniformRNG<>(0,1)() <= 0.5) ? TI_LEFT : TI_RIGHT;
00111 }
00112
00113 SetPlayMode((ti == TI_LEFT) ? PM_KickOff_Left : PM_KickOff_Right);
00114
00115 if (mLastKickOff == TI_NONE)
00116 mLastKickOff = ti;
00117 }
00118 else
00119 {
00120
00121 SetPlayMode((mLastKickOff == TI_LEFT) ? PM_KickOff_Right : PM_KickOff_Left);
00122 }
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155 TTime
00156 GameStateAspect::GetTime() const
00157 {
00158 return mTime;
00159 }
00160
00161 TTime
00162 GameStateAspect::GetModeTime() const
00163 {
00164 switch (mPlayMode)
00165 {
00166 case PM_BeforeKickOff:
00167 return mLeadTime;
00168 case PM_GameOver:
00169 return mFupTime;
00170 default:
00171 return mTime - mLastModeChange;
00172 }
00173 }
00174
00175 TTime
00176 GameStateAspect::GetLastModeChange() const
00177 {
00178 return mLastModeChange;
00179 }
00180
00181 void
00182 GameStateAspect::SetTeamName(TTeamIndex idx, const std::string& name)
00183 {
00184 switch (idx)
00185 {
00186 case TI_LEFT:
00187 mTeamName[0] = name;
00188 break;
00189 case TI_RIGHT:
00190 mTeamName[1] = name;
00191 break;
00192 }
00193 return;
00194 }
00195
00196 std::string
00197 GameStateAspect::GetTeamName(TTeamIndex idx) const
00198 {
00199 switch (idx)
00200 {
00201 case TI_LEFT:
00202 return mTeamName[0];
00203 case TI_RIGHT:
00204 return mTeamName[1];
00205 default:
00206 return "";
00207 }
00208 }
00209
00210 TTeamIndex
00211 GameStateAspect::GetTeamIndex(const std::string& teamName)
00212 {
00213 for (int i=0; i<=1; ++i)
00214 {
00215 if (mTeamName[i].empty())
00216 {
00217 mTeamName[i] = teamName;
00218 return static_cast<TTeamIndex>(i + TI_LEFT);
00219 }
00220
00221 if (mTeamName[i] == teamName)
00222 {
00223 return static_cast<TTeamIndex>(i + TI_LEFT);
00224 }
00225 }
00226
00227 return TI_NONE;
00228 }
00229
00230 bool
00231 GameStateAspect::InsertUnum(TTeamIndex idx, int unum)
00232 {
00233 int i;
00234
00235 switch (idx)
00236 {
00237 case TI_LEFT:
00238 i = 0;
00239 break;
00240 case TI_RIGHT:
00241 i = 1;
00242 break;
00243 default:
00244 return false;
00245 }
00246
00247 TUnumSet& set = mUnumSet[i];
00248
00249 if (
00250 (set.size() >= 11) ||
00251 (set.find(unum) != set.end())
00252 )
00253 {
00254 return false;
00255 }
00256
00257 set.insert(unum);
00258 mMaxUnum[i] = std::max<int>(unum, mMaxUnum[i]);
00259
00260 return true;
00261 }
00262
00263 bool
00264 GameStateAspect::RequestUniform(shared_ptr<AgentState> agentState,
00265 std::string teamName, unsigned int unum)
00266 {
00267 if (agentState.get() == 0)
00268 {
00269 return false;
00270 }
00271
00272 TTeamIndex idx = GetTeamIndex(teamName);
00273
00274 if (idx == TI_NONE)
00275 {
00276 GetLog()->Error()
00277 << "ERROR: (GameStateAspect::RequestUniform) invalid teamname "
00278 << teamName << "\n";
00279 return false;
00280 }
00281
00282 if (unum == 0)
00283 {
00284 unum = RequestUniformNumber(idx);
00285 }
00286
00287 if (! InsertUnum(idx,unum))
00288 {
00289 GetLog()->Error()
00290 << "ERROR: (GameStateAspect::RequestUniform) cannot insert uniform"
00291 " number " << unum << " to team " << teamName << "\n";
00292 return false;
00293 }
00294
00295 agentState->SetUniformNumber(unum);
00296 agentState->SetTeamIndex(idx);
00297
00298 agentState->SetPerceptName(teamName, ObjectState::PT_Default, ObjectState::PT_Player );
00299
00300 agentState->SetPerceptName("player", ObjectState::PT_TooFar);
00301
00302 GetLog()->Normal() << "(GameStateAspect) handed out uniform number "
00303 << unum << " for team " << teamName << "\n";
00304
00305 return true;
00306 }
00307
00308 void
00309 GameStateAspect::SetGameHalf(TGameHalf half)
00310 {
00311 if (
00312 (half != GH_FIRST) &&
00313 (half != GH_SECOND)
00314 )
00315 {
00316 return;
00317 }
00318
00319 mGameHalf = half;
00320 }
00321
00322 TGameHalf
00323 GameStateAspect::GetGameHalf() const
00324 {
00325 return mGameHalf;
00326 }
00327
00328 void
00329 GameStateAspect::ScoreTeam(TTeamIndex idx)
00330 {
00331 switch (idx)
00332 {
00333 case TI_LEFT:
00334 ++mScore[0];
00335 break;
00336 case TI_RIGHT:
00337 ++mScore[1];
00338 break;
00339 }
00340 return;
00341 }
00342
00343 int
00344 GameStateAspect::GetScore(TTeamIndex idx) const
00345 {
00346 switch (idx)
00347 {
00348 case TI_LEFT:
00349 return mScore[0];
00350 case TI_RIGHT:
00351 return mScore[1];
00352 default:
00353 return 0;
00354 }
00355 }
00356
00357 Vector3f
00358 GameStateAspect::RequestInitPosition(const TTeamIndex ti)
00359 {
00360 if (ti == TI_NONE)
00361 {
00362 GetLog()->Debug()
00363 << "(GameStateAspect) RequestInitPosition called with "
00364 << "ti=TI_NONE\n";
00365 return Vector3f(0,0,10);
00366 }
00367
00368 salt::Vector3f& init = (ti ==TI_LEFT) ? mLeftInit : mRightInit;
00369
00370 Vector3f pos = init;
00371 init[1] -= mAgentRadius * 3;
00372
00373 return pos;
00374 }
00375
00376 void
00377 GameStateAspect::OnLink()
00378 {
00379
00380 float fieldWidth = 64.0;
00381 SoccerBase::GetSoccerVar(*this,"FieldWidth",fieldWidth);
00382
00383 float fieldLength = 100.0;
00384 SoccerBase::GetSoccerVar(*this,"FieldLength",fieldLength);
00385
00386 mAgentRadius = 0.22;
00387 SoccerBase::GetSoccerVar(*this,"AgentRadius",mAgentRadius);
00388
00389 mLeftInit = Vector3f
00390 (
00391 -fieldLength/2.0 + mAgentRadius*2,
00392 fieldWidth/2 - mAgentRadius*2,
00393 mAgentRadius
00394 );
00395
00396 mRightInit = Vector3f
00397 (
00398 +fieldLength/2.0 - mAgentRadius*2,
00399 fieldWidth/2 - mAgentRadius*2,
00400 mAgentRadius
00401 );
00402 }
00403
00404 int
00405 GameStateAspect::RequestUniformNumber(TTeamIndex ti) const
00406 {
00407 switch (ti)
00408 {
00409 case TI_LEFT:
00410 return mMaxUnum[0] + 1;
00411 case TI_RIGHT:
00412 return mMaxUnum[1] + 1;
00413 default:
00414 return 0;
00415 }
00416 }
00417
00418
00419
00420
00421
00422