Gioca una partita perfetta a Mu Torere


14

sfondo

Mu Torere è un gioco che è uno dei due conosciuti per essere giocato dai maori della Nuova Zelanda prima dell'influenza europea. Questo lo rende un gioco davvero unico in quanto ha un "criterio vincente oggettivo" e regole di gioco diverse dalla maggior parte degli altri giochi esistenti.

gameplay:

Il tabellone è un ottagono. Esistono connessioni tra ciascun vertice adiacente e un nodo centrale è collegato a tutti i vertici. In qualsiasi momento, otto dei nove nodi sono occupati da pietre. All'inizio, ci sono quattro pietre bianche e quattro pietre nere che occupano ciascuna metà dell'ottagono, con il nodo centrale vuoto. Il nero si muove per primo.

Ogni turno, un giocatore può spostare una delle sue pietre lungo uno dei 16 bordi da un nodo al nodo vuoto. Una pietra può essere spostata da un nodo esterno al nodo centrale solo se la pietra si trova vicino alla pietra di un avversario.

Un giocatore perde quando non è in grado di effettuare una mossa legale, che si verifica quando non c'è bordo che collega una pietra al nodo vuoto.

Un diagramma e una spiegazione delle regole

Ecco un sito Web che spiega le regole (con un diagramma) e offre alcune analisi.

La sfida

La tua sfida è quella di scrivere il programma più breve in grado di giocare una partita perfetta di Mu Torere contro un avversario umano. Il tuo programma dovrebbe essere in grado di visualizzare e aggiornare il tabellone, fare mosse e ricevere mosse da un avversario umano. Ancora più importante, dovrebbe giocare un gioco perfetto.

Gioco perfetto?

Sì, gioco perfetto. Ho fatto alcune analisi del gioco e ho scoperto che il gioco dura per un tempo infinito se giocato perfettamente da entrambe le parti. Ciò significa che il tuo programma non dovrebbe mai perdere. Inoltre, il tuo programma dovrebbe essere in grado di forzare una vittoria ogni volta che l'avversario umano commette un errore che consente al programma di forzare una vittoria. Per quanto riguarda il modo in cui il tuo programma trova la mossa perfetta, dipende da te.

Dettagli

Dopo ogni mossa (e all'inizio del gioco), il tuo programma dovrebbe stampare il tabellone. Comunque tu scelga di visualizzare la scheda, deve mostrare tutti i nodi ed essere completamente connessa (tutte le 16 linee di connessione devono essere disegnate senza linee incrociate). All'inizio, la scheda dovrebbe avere la posizione iniziale corretta. Un modo per raggiungere questo obiettivo è rendere il tabellone un quadrato.

w-w-w
|\|/|
b-o-w
|/|\|
b-b-b

I due colori sono bianco e nero o scuro / chiaro. Il tabellone deve mostrare quali nodi sono occupati da quali pezzi del giocatore, come segnarli con una "b" o "w", e quale nodo è libero. I partecipanti sono incoraggiati (ma non tenuti) a rendere il tabellone più grafico, piuttosto che semplice.

Il tuo tabellone di gioco dovrebbe avere un sistema di numerazione che dia a ciascun nodo un numero univoco. Puoi scegliere di numerare la tavola come preferisci, ma dovrebbe essere spiegata nella tua risposta o dal programma. La scheda quadrata può essere numerata come segue:

1-2-3
|\|/|
4-5-6
|/|\|
7-8-9

L'umano è il primo a muoversi. Il suo input sarà un singolo numero. Questo sarà il numero del nodo in cui si trova attualmente la pietra spostata. Se volessi spostare una pietra dal nodo 4 a un nodo vuoto 5, scriverò a 4. Il 5 è implicito in quanto è l'unico nodo vuoto.

Supponiamo che l'umano farà sempre una mossa legale.

Dopo che l'umano ha fatto la sua mossa, dovrebbe essere stampata una tavola aggiornata. Dopo che il programma ha deciso di effettuare una mossa legale, dovrebbe stampare un'altra scheda aggiornata e quindi attendere che l'essere umano inserisca un'altra mossa.

Il tuo programma dovrebbe terminare una volta che ha vinto.

Appunti

Si applicano le regole standard per il golf del codice, nessun accesso a file esterni, ecc. Ecc. Inoltre, imporrò un limite di tempo flessibile di 15 secondi (su una macchina ragionevole) per consentire al programma di eseguire ciascuna delle sue mosse. Come detto, questo gioco ha la possibilità di formare loop infiniti e non voglio che una ricerca approfondita entri in un loop infinito.


2
Grande sfida. Solo "Se l'essere umano inserisce una mossa illegale, il tuo programma dovrebbe attendere e consentirgli di inserire una mossa diversa." mi sembra un po 'non golfistico: non possiamo lasciare il comportamento indefinito in caso di input illegali?
cessò di girare in senso antiorario

1
Ho gettato questo requisito all'ultimo minuto e immagino che andrebbe bene se lo eliminassimo. Questo rende solo più difficile per l'umano, che è già condannato a non vincere. :)
PhiNotPi,

1
Non è poi così difficile entrare sempre in una mossa legale ... A proposito, dopo un'analisi abbastanza dettagliata penso che non sia necessario cercare più di 1,5 mosse in avanti. Se questo approccio sia il più breve è un'altra domanda.
Peter Taylor,

3
Il sito Web collegato non è più disponibile, sarebbe meglio trasformarlo in un collegamento a una versione archiviata.
Tally

Risposte:


6

Rubino, 390 caratteri

o=->s,c{f=s=~/o/;[*0..8].select{|t|s[t]==c&&(t<1||(t+6)%8+1==f||t%8+1==f||f<1&&(s[(t+6)%8+1]!=c||s[t%8+1]!=c))}.map{|t|k=s*1;k[f]=c;k[t]=?o;k}}
v=->s,c,h{f=o[s,c];f==[]?0:h<1?1:2-f.map{|t|v[t,c>?b??b:?w,h-1]}.min}
q=->g{puts"1-2-3\n|\\|/|\n8-0-4\n|/|\\|\n7-6-5\n".tr"0-8",g;$>.flush}
q[g="obbbbwwww"]
(g.tr!?o,?b;g[gets.to_i]=?o;q[g];q[g=o[g,?w].sort_by{|q|v[q,?w,5]}[-1]])while v[g,?b,5]>0

Un'implementazione in ruby ​​che calcola direttamente l'albero del gioco (che richiede un bel po 'di codice) e quindi gioca sempre in modo ottimale. Le posizioni della scacchiera si muovono a spirale verso l'esterno, come mostrato nella figura seguente:

1 - 2 - 3
| \ | / |
8 - 0 - 4
| / | \ |
7 - 6 - 5

5

bash and friends ( 463 447 caratteri)

t(){ tr 0-8a-i $b$b
}
p(){ t<<E
0-1-2
|\|/|
3-4-5
|/|\|
6-7-8

E
}
g(){ b=`tr $x$e $e$x<<<012345678|t`
p
e=$x
}
b=bbbbowwww
e=4
m=0
p
while [ $m != 5 ]&&read x;do
g
m=0
for y in {0..8};do
s=0
S=05011234
grep -E "w.*($y$e|$e$y)"<<<${b:$y:1}30125876340142548746>/dev/null&&for p in wow.\*/ww wow.\*/w bbo.\*/b obb.\*/b www wbw .
do
((s++))
tr $y$e $e$y<<<3012587630/4e|t|grep $p>/dev/null&&break
done
s=${S:$s:1}
[ $s -gt $m ]&&m=$s x=$y
done
g
done

Giochi umani come b, computer come w. La posizione della scacchiera è numerata come nel documento qui in alto. Si scopre che l'euristica di giocare un gioco perfetto è sorprendentemente semplice.

D'altra parte, perdere il percorso interessante è piuttosto difficile. http://ideone.com/sXJPy dimostra il suicidio più breve possibile contro questo bot. Si noti che lo 0 aggiuntivo alla fine è verificare che si interrompa correttamente dal ciclo.


NB Potrei salvare un personaggio rendendo read xobbligatorio, ma ciò renderebbe i test abbastanza frustranti. Potrei anche salvare un personaggio rimuovendo la riga vuota dopo il tabellone, ma ...
Peter Taylor,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.