En s'appuyant sur la réponse de SimonW , voici un algorithme explicite:
Soit squares
un tableau indexé par les emplacements des joueurs et contenant, pour chaque emplacement possible, soit l'index d'un autre emplacement, soit la valeur spéciale NULL
. (Vous souhaiterez peut-être le stocker en tant que tableau fragmenté.) Les valeurs possibles des entrées de ce tableau peuvent être interprétées comme suit:
- Si
squares[S]
c'est leNULL
, le carré S
est libre de se déplacer.
- Si
squares[S] == S
, soit le joueur S
ne peut pas ou ne veut pas bouger, soit deux joueurs (ou plus) ont essayé de se déplacer en S
même temps et ont tous deux été refusés.
- Autrement,
squares[S]
contiendra l'index du carré à partir duquel un joueur veut se déplacer vers le carré S
.
À chaque tour, initialisez toutes les entrées de squares
to NULL
puis exécutez l'algorithme suivant:
for each player:
current := the player's current location;
target := the location the player wants to move to (may equal current);
if squares[target] is NULL:
squares[target] := current; // target is free, mark planned move
else
// mark the target square as contested, and if necessary, follow
// the pointers to cancel any moves affected by this:
while not (target is NULL or squares[target] == target):
temp := squares[target];
squares[target] := target;
target := temp;
end while
// mark this player as stationary, and also cancel any moves that
// would require some else to move to this square
while not (current is NULL or squares[current] == current):
temp := squares[current];
squares[current] := current;
current := temp;
end while
end if
end for
Après cela, parcourez à nouveau la liste des joueurs et déplacez ceux qui sont capables de le faire:
for each player:
current := the player's current location;
if not squares[current] == current:
move player;
end if
end for
Étant donné que chaque mouvement ne peut être planifié qu'une seule fois et annulé au plus une fois, cet algorithme s'exécutera en temps O ( n ) pour n joueurs, même dans le pire des cas.
(Hélas, cet algorithme n'empêchera pas les joueurs de changer de place ou de se croiser en diagonale. Il pourrait être possible d'adapter l' astuce en deux étapes de Gajet , mais la façon complètement naïve de le faire ne fonctionnera pas et je suis trop fatigué pour trouver un meilleur moyen tout à l'heure.)