Sulla base della risposta di SimonW , ecco un algoritmo esplicito:
Sia squares
una matrice indicizzata dalle posizioni dei giocatori e contenente, per ogni possibile posizione, l'indice di un'altra posizione o il valore speciale NULL
. (È possibile che si desideri memorizzare questo come un array sparse.) I possibili valori delle voci in questo array possono essere interpretati come segue:
- Se
squares[S]
è NULL
, il quadratoS
è libera di spostarsi.
- Se
squares[S] == S
, il giocatore a S
non può o non si sposta, o due (o più) giocatori hanno tentato di spostarsiS
contemporaneamente e vengono entrambi negati.
- Altrimenti,
squares[S]
conterrà l'indice del quadrato da cui un giocatore vuole passare al quadrato S
.
Ad ogni turno, inizializzare tutte le voci di squares
to NULL
e quindi eseguire il seguente algoritmo:
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
Successivamente, ripeti l'elenco dei giocatori e sposta quelli che sono in grado di farlo:
for each player:
current := the player's current location;
if not squares[current] == current:
move player;
end if
end for
Poiché ogni mossa può essere pianificata una sola volta e annullata al massimo una volta, questo algoritmo verrà eseguito in tempo O ( n ) per n giocatori anche nel caso peggiore.
(Ahimè, questo algoritmo non impedirà ai giocatori di cambiare posto o attraversare percorsi in diagonale. Potrebbe essere possibile adattare il trucco in due fasi di Gajet , ma il modo completamente ingenuo per farlo non funzionerà e sono troppo stanco per capire un modo migliore proprio ora.)