Sobre la base de la respuesta de SimonW , aquí hay un algoritmo explícito:
Sea squares
una matriz indexada por las ubicaciones del jugador y que contenga, para cada posible ubicación, el índice de otra ubicación o el valor especial NULL
. (Es posible que desee almacenar esto como una matriz dispersa). Los posibles valores de las entradas en esta matriz pueden interpretarse de la siguiente manera:
- Si
squares[S]
es así NULL
, el cuadrado S
puede moverse libremente.
- Si
squares[S] == S
, o el jugador S
no puede o no se moverá, o dos (o más) jugadores intentaron moverse al S
mismo tiempo y ambos fueron denegados.
- De lo contrario,
squares[S]
contendrá el índice del cuadrado desde el cual un jugador quiere moverse al cuadrado S
.
En cada turno, inicializar todas las entradas de squares
a NULL
y ejecute el siguiente 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
Después de eso, recorra la lista de jugadores nuevamente y mueva los que puedan hacerlo:
for each player:
current := the player's current location;
if not squares[current] == current:
move player;
end if
end for
Dado que cada movimiento solo se puede planificar una vez y cancelar como máximo una vez, este algoritmo se ejecutará en tiempo O ( n ) para n jugadores, incluso en el peor de los casos.
(Por desgracia, este algoritmo no impedirá que los jugadores cambien de lugar o se crucen en diagonal. Podría ser posible adaptar el truco de dos pasos de Gajet , pero la forma completamente ingenua de hacerlo no funcionará y estoy demasiado cansado para encontrar una mejor manera ahora).