00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 template <typename T>
00018 inline Field<T>::Field()
00019 {
00020 for (int i = 0; i < COLS * ROWS; i++)
00021 tab_[i] = NULL;
00022 }
00023
00024 template <typename T>
00025 inline Field<T>::~Field()
00026 {
00027 }
00028
00029 template <typename T>
00030 inline bool Field<T>::intoField(const Coordinates& coord) const
00031 {
00032 return coord.row >= 0 && coord.row < ROWS
00033 && coord.col >= 0 && coord.col < COLS;
00034 }
00035
00036 template <typename T>
00037 inline Coordinates Field<T>::dirToCoord(enum eDirection d) const
00038 {
00039 switch(d)
00040 {
00041 case DIR_NORTHWEST: return Coordinates(-1, -1); break;
00042 case DIR_NORTH: return Coordinates(-1, 0); break;
00043 case DIR_NORTHEAST: return Coordinates(-1, +1); break;
00044 case DIR_EAST: return Coordinates( 0, +1); break;
00045 case DIR_SOUTHEAST: return Coordinates(+1, +1); break;
00046 case DIR_SOUTH: return Coordinates(+1, 0); break;
00047 case DIR_SOUTHWEST: return Coordinates(+1, -1); break;
00048 case DIR_WEST: return Coordinates( 0, -1); break;
00049 default: return Coordinates( 0, 0); break;
00050 }
00051 }
00052
00053 template <typename T>
00054 inline void Field<T>::setPlayer(const Coordinates& coord, T* p)
00055 {
00056
00057
00058 if (p != NULL && tab_[coord.row * COLS + coord.col] != NULL)
00059 WARN("Desynchronization bewteen field and players!");
00060
00061 tab_[coord.row * COLS + coord.col] = p;
00062 }
00063
00064 template <typename T>
00065 inline T* Field<T>::getPlayer(const Coordinates& coord) const
00066 {
00067 if (!intoField(coord))
00068 return NULL;
00069 return tab_[coord.row * COLS + coord.col];
00070 }
00071
00072 template <typename T>
00073 inline int Field<T>::getNbPlayersInOppositeHalf(int team_id) const
00074 {
00075 Coordinates c;
00076 int nb_players = 0;
00077
00078
00079 for (c.row = (1 - team_id) * (ROWS / 2);
00080 c.row <= (1 - team_id) * (ROWS / 2) + (ROWS / 2) - 1;
00081 c.row++)
00082 for (c.col = 0; c.col <= COLS - 1; c.col++)
00083 if (getPlayer(c) != NULL && getPlayer(c)->getTeamId() == team_id)
00084 nb_players++;
00085
00086 return nb_players;
00087 }
00088
00089 template <typename T>
00090 inline int Field<T>::getNbPlayersInLeftWideZone(int team_id) const
00091 {
00092 Coordinates c;
00093 int nb_players = 0;
00094
00095
00096 for (c.row = team_id * ((ROWS / 2) - 1) + 1;
00097 c.row <= team_id * ((ROWS / 2) - 1) + ((ROWS / 2) - 1);
00098 c.row++)
00099 for (c.col = 0; c.col <= SIDE - 1; c.col++)
00100 if (getPlayer(c) != NULL && getPlayer(c)->getTeamId() == team_id)
00101 nb_players++;
00102
00103 return nb_players;
00104 }
00105
00106 template <typename T>
00107 inline int Field<T>::getNbPlayersInRightWideZone(int team_id) const
00108 {
00109 Coordinates c;
00110 int nb_players = 0;
00111
00112
00113 for (c.row = team_id * ((ROWS / 2) - 1) + 1;
00114 c.row <= team_id * ((ROWS / 2) - 1) + ((ROWS / 2) - 1);
00115 c.row++)
00116 for (c.col = COLS - SIDE; c.col <= COLS - 1; c.col++)
00117 if (getPlayer(c) != NULL && getPlayer(c)->getTeamId() == team_id)
00118 nb_players++;
00119
00120 return nb_players;
00121 }
00122
00123 template <typename T>
00124 inline int Field<T>::getNbPlayersOnLineOfScrimmage(int team_id) const
00125 {
00126 Coordinates c;
00127 int nb_players = 0;
00128
00129
00130 c.row = team_id + (ROWS / 2) - 1;
00131 for (c.col = SIDE; c.col <= (COLS - 1) - SIDE; c.col++)
00132 if (getPlayer(c) != NULL && getPlayer(c)->getTeamId() == team_id)
00133 nb_players++;
00134
00135 return nb_players;
00136 }
00137
00138 template <typename T>
00139 inline int Field<T>::getNbPlayersInEndZone(int team_id) const
00140 {
00141 Coordinates c;
00142 int nb_players = 0;
00143
00144
00145 c.row = team_id * (ROWS - 1);
00146 for (c.col = 0; c.col <= COLS - 1; c.col++)
00147 if (getPlayer(c) != NULL && getPlayer(c)->getTeamId() == team_id)
00148 nb_players++;
00149
00150 return nb_players;
00151 }
00152
00153 template <typename T>
00154 inline int Field<T>::getNbPlayersInMiddle(int team_id) const
00155 {
00156 Coordinates c;
00157 int nb_players = 0;
00158
00159
00160 for (c.row = team_id * (ROWS / 2) + 1;
00161 c.row <= (team_id + 1) * (ROWS / 2) - 2;
00162 c.row++)
00163 for (c.col = SIDE; c.col <= (COLS - 1) - SIDE; c.col++)
00164 if (getPlayer(c) != NULL && getPlayer(c)->getTeamId() == team_id)
00165 nb_players++;
00166
00167 return nb_players;
00168 }
00169
00170 template <typename T>
00171 inline int Field<T>::isPlacementValid(int team_id) const
00172 {
00173 int n, nb_players;
00174
00175 nb_players = getNbPlayersInOppositeHalf(team_id);
00176 if (nb_players > 0)
00177 return false;
00178
00179 n = getNbPlayersInLeftWideZone(team_id);
00180 if (n > 2)
00181 return false;
00182 nb_players += n;
00183
00184 n = getNbPlayersInRightWideZone(team_id);
00185 if (n > 2)
00186 return false;
00187 nb_players += n;
00188
00189 nb_players += getNbPlayersInEndZone(team_id);
00190 nb_players += getNbPlayersInMiddle(team_id);
00191
00192 n = getNbPlayersOnLineOfScrimmage(team_id);
00193 nb_players += n;
00194
00195
00196 return (nb_players < 12 && (n >= 3 || n == nb_players));
00197 }
00198
00199 template <typename T>
00200 inline bool Field<T>::hasAdjacentEmptySquare(const Coordinates& coord) const
00201 {
00202 Coordinates next_square;
00203 enum eDirection dir;
00204 for (dir = DIR_LAST; dir > DIR_UNASSIGNED; dir = static_cast<enum eDirection>(dir - 1))
00205 {
00206 next_square = coord + dirToCoord(dir);
00207 if (intoField(next_square)
00208 && getPlayer(next_square) == NULL)
00209 return true;
00210 }
00211 return false;
00212 }
00213
00214 template <typename T>
00215 inline CoordList Field<T>::getAdjacentEmptySquares(const Coordinates& coord) const
00216 {
00217 CoordList squares;
00218 Coordinates next_square;
00219 enum eDirection dir;
00220 for (dir = DIR_LAST; dir > DIR_UNASSIGNED; dir = static_cast<enum eDirection>(dir - 1))
00221 {
00222 next_square = coord + dirToCoord(dir);
00223 if (intoField(next_square)
00224 && getPlayer(next_square) == NULL)
00225 squares.push_back(next_square);
00226 }
00227 return squares;
00228 }
00229
00230 template <typename T>
00231 inline bool Field<T>::hasAdjacentPlayer(const Coordinates& coord) const
00232 {
00233 enum eDirection dir;
00234 for (dir = DIR_LAST; dir > DIR_UNASSIGNED; dir = static_cast<enum eDirection>(dir - 1))
00235 {
00236 if (getPlayer(coord + dirToCoord(dir)) != NULL)
00237 return true;
00238 }
00239 return false;
00240 }
00241
00242 template <typename T>
00243 inline bool Field<T>::hasAdjacentPlayer(const Coordinates& coord, enum eStatus s, int team_id) const
00244 {
00245 T* player;
00246 enum eDirection dir;
00247 for (dir = DIR_LAST; dir > DIR_UNASSIGNED; dir = static_cast<enum eDirection>(dir - 1))
00248 {
00249 player = getPlayer(coord + dirToCoord(dir));
00250 if (player != NULL
00251 && player->getStatus() == s
00252 && player->getTeamId() == team_id)
00253 return true;
00254 }
00255 return false;
00256 }
00257
00258 template <typename T>
00259 inline std::vector<T*> Field<T>::getAdjacentPlayers(const Coordinates& coord) const
00260 {
00261 std::vector<T*> neighbours;
00262 T* player;
00263 enum eDirection dir;
00264 for (dir = DIR_LAST; dir > DIR_UNASSIGNED; dir = static_cast<enum eDirection>(dir - 1))
00265 {
00266 player = getPlayer(coord + dirToCoord(dir));
00267 if (player != NULL)
00268 neighbours.push_back(player);
00269 }
00270 return neighbours;
00271 }
00272
00273 template <typename T>
00274 inline std::vector<T*> Field<T>::getAdjacentPlayers(const Coordinates& coord, enum eStatus s, int team_id) const
00275 {
00276 std::vector<T*> neighbours;
00277 T* player;
00278 enum eDirection dir;
00279 for (dir = DIR_LAST; dir > DIR_UNASSIGNED; dir = static_cast<enum eDirection>(dir - 1))
00280 {
00281 player = getPlayer(coord + dirToCoord(dir));
00282 if (player != NULL
00283 && player->getStatus() == s
00284 && player->getTeamId() == team_id)
00285 neighbours.push_back(player);
00286 }
00287 return neighbours;
00288 }
00289
00290 template <typename T>
00291 inline int Field<T>::getNbTackleZones(int team_id, const Coordinates& coord) const
00292 {
00293 int res = 0;
00294 Coordinates c;
00295 std::vector<T*> tacklers = getAdjacentPlayers(coord, STA_STANDING, team_id);
00296 for (unsigned i = 0; i < tacklers.size(); i++)
00297 if (tacklers[i]->hasTackleZone())
00298 res++;
00299 return res;
00300 }
00301
00302 template <typename T>
00303 inline int Field<T>::getTackleZonesMalus(int team_id, const Coordinates& coord) const
00304 {
00305 int res = 0;
00306 Coordinates c;
00307 std::vector<T*> tacklers = getAdjacentPlayers(coord, STA_STANDING, team_id);
00308 for (unsigned i = 0; i < tacklers.size(); i++)
00309 if (tacklers[i]->hasTackleZone() && !tacklers[i]->hasSkill(SK_TITCHY))
00310 res++;
00311 return res;
00312 }
00313
00314 template <typename T>
00315 inline bool Field<T>::canAssist(const Coordinates& coord_assister, int team_id,
00316 enum eEffort effort, const Coordinates& coord_target) const
00317 {
00318 return (coord_assister.isNear(coord_target)
00319 && getPlayer(coord_assister)->getStatus() == STA_STANDING
00320 && getPlayer(coord_assister)->hasTackleZone()
00321 && ((effort == EFF_BLOCK
00322 && (getPlayer(coord_assister)->hasSkill(SK_GUARD)
00323 || (getNbTackleZones(team_id, coord_assister) ==
00324 getPlayer(coord_target)->hasTackleZone())))
00325 || (effort == EFF_FOUL
00326 && (getNbTackleZones(team_id, coord_assister) ==
00327 getPlayer(coord_target)->hasTackleZone()))));
00328 }
00329
00330 template <typename T>
00331 inline int Field<T>::getNbAssister(const Coordinates& coord_assisted,
00332 int team_id, enum eEffort effort, const Coordinates& coord_target) const
00333 {
00334 int res = 0;
00335 Coordinates c;
00336
00337 for (c.row = coord_target.row - 1; c.row <= coord_target.row + 1; c.row++)
00338 for (c.col = coord_target.col - 1; c.col <= coord_target.col + 1; c.col++)
00339 if (intoField(c)
00340 && getPlayer(c) != NULL
00341 && c != coord_assisted
00342 && getPlayer(c)->getTeamId() == team_id
00343 && canAssist(c, (team_id + 1) % 2, effort, coord_target))
00344 res++;
00345 return res;
00346 }
00347 template <typename T>
00348 inline int Field<T>::getNbBlockDices(const Coordinates& coord_attacker,
00349 const Coordinates& coord_target) const
00350 {
00351 T* attacker;
00352 T* target;
00353
00354 attacker = getPlayer(coord_attacker);
00355 target = getPlayer(coord_target);
00356 if (attacker == NULL || target == NULL) {
00357 return 0;
00358 }
00359
00360 int mod_st_atk = attacker->getSt()
00361 + ((attacker->hasSkill(SK_HORNS) && attacker->getAction() == ACT_BLITZ) ? 1 : 0)
00362 + getNbAssister(coord_attacker, attacker->getTeamId(),
00363 EFF_BLOCK, coord_target);
00364 int mod_st_df = target->getSt()
00365 + getNbAssister(coord_target, target->getTeamId(),
00366 EFF_BLOCK, coord_attacker);
00367
00368 return (mod_st_atk < mod_st_df ? -1 : 1) *
00369 ((mod_st_atk > 2 * mod_st_df || mod_st_df > 2 * mod_st_atk) ? 3 :
00370 (mod_st_atk != mod_st_df ? 2 : 1 ));
00371 }
00372
00373 template <typename T>
00374 inline int Field<T>::getFoulModifier(const Coordinates& coord_attacker,
00375 const Coordinates& coord_target) const
00376 {
00377 T* attacker;
00378 T* target;
00379
00380 attacker = getPlayer(coord_attacker);
00381 target = getPlayer(coord_target);
00382 if (attacker == NULL || target == NULL) {
00383 return 0;
00384 }
00385
00386 int atk_mod = getNbAssister(coord_attacker, attacker->getTeamId(),
00387 EFF_FOUL, coord_target);
00388 int def_mod = getNbAssister(coord_target, target->getTeamId(),
00389 EFF_FOUL, coord_attacker);
00390
00391 return atk_mod - def_mod;
00392 }
00393