Com base na resposta do SimonW , aqui está um algoritmo explícito:
Seja squares
uma matriz indexada pelos locais dos jogadores e contendo, para cada local possível, o índice de outro local ou o valor especial NULL
. (Você pode armazenar isso como uma matriz esparsa.) Os possíveis valores das entradas nessa matriz podem ser interpretados da seguinte maneira:
- Se
squares[S]
for NULL
, o quadrado S
está livre para entrar.
- Se
squares[S] == S
, ou o jogador S
não puder ou não se mover, ou dois (ou mais) jogadores tentaram se mover ao S
mesmo tempo e ambos foram negados.
- Caso contrário,
squares[S]
conterá o índice do quadrado do qual um jogador deseja mover para o quadrado S
.
Em cada turno, inicializar todas as entradas de squares
a NULL
e, em seguida, execute o seguinte 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
Depois disso, percorra a lista de jogadores novamente e mova aqueles que são capazes de fazê-lo:
for each player:
current := the player's current location;
if not squares[current] == current:
move player;
end if
end for
Como cada jogada só pode ser planejada uma vez e cancelada no máximo uma vez, esse algoritmo será executado em O ( n ) tempo para n jogadores, mesmo no pior caso.
(Infelizmente, esse algoritmo não impedirá os jogadores de trocar de lugar ou de cruzar na diagonal. Pode ser possível adaptar o truque de duas etapas do Gajet a ele, mas a maneira completamente ingênua de fazer isso não funcionará e eu estou cansado demais para descobrir uma maneira melhor agora.)