J'ai un jeu composé de navires qui volent sur une grille 2d. J'écris une fonction qui prend un emplacement, et détermine si la cible (prédéfinie) peut être touchée à partir de là. Cela nécessite simplement de vérifier tous les carrés de la grille dans la ligne de tir de l'agresseur potentiel.C# XNA: Comment supprimer la répétition de cette fonction simple?
Dans la plupart des cas, ceci est une croix, formé comme ceci:
(currX +/- SHOT_RANGE, currY) and (currX, currY +/- SHOT_RANGE)
Où SHOT_RANGE
est la distance maximale d'un coup de feu peut se déplacer, et le navire de tir est actuellement situé à (currX, currY)
.
Le code pour vérifier ces deux lignes est assez simple:
for (int i = x - SHOT_RANGE; i < x + SHOT_RANGE; i++) {
if (target.TileX == i && target.TileY == y) {
return true;
}
}
for (int j = y - SHOT_RANGE; j < y + SHOT_RANGE; j++) {
if (target.TileX == x && target.TileY == j) {
return true;
}
}
Cependant, sur certains « tuiles électriques » le navire peut aussi tirer en diagonale. Tous ces carrés doivent être vérifiés aussi. C'est là que la répétition entre en jeu. Pouvez-vous voir un moyen de le faire avec moins de code?
/// <param name="x">Current x-coord of the potential ship</param>
/// <param name="y">Current y-coord of the potential ship</param>
private bool CanShootTargetFrom(int x, int y) {
if ((target.TileX == x && Math.Abs(target.TileY - y) <= SHOT_RANGE) || (target.TileY == y && Math.Abs(target.TileX - x) <= SHOT_RANGE)) {
return true;
}
if (board.IsPowerTileAt(x, y)) {
int i = x - SHOT_RANGE;
int j = y - SHOT_RANGE;
while (i != x + SHOT_RANGE && j != y + SHOT_RANGE) {
if (target.TileX == i && target.TileY == j) {
return true;
}
i++;
j++;
}
i = x - SHOT_RANGE;
j = y + SHOT_RANGE;
while (i != x + SHOT_RANGE && j != y - SHOT_RANGE) {
if (target.TileX == i && target.TileY == j) {
return true;
}
i++;
j--;
}
}
return false;
}
MISE À JOUR utiliser la suggestion de Carra, et je compris que je pouvais éliminer deux des boucles de contrôle en augmentant les diagonales des limites supérieures.
mais pour les diagonales, cela ne serait-il pas vrai si le tireur est à '(3, 3)' et que la cible est '((1, 2)'? Ce ne serait pas correct. le navire ne tire que le long des diagonales. (Donc à partir de '(3, 3)', un vaisseau pourrait frapper '(2, 2)', '(1, 1)', etc.) –
Bon point. Mais c'est un angle de 90 degrés donc a == b. – Carra