Scrivi il gioco più breve di alak


10

Alak è stato inventato dal matematico AK Dewdney e descritto nel suo libro Planiverse del 1984. Le regole di Alak sono semplici:

Alak è una partita a due giocatori giocata su una tavola unidimensionale con undici slot. Ogni slot può contenere al massimo un pezzo alla volta. Esistono due tipi di pezzi, "x" e "o". x appartiene a un giocatore, o all'altro. La configurazione iniziale della scheda è:

      xxxx___oooo

I giocatori a turno si muovono. Ad ogni turno, ogni giocatore può muovere solo un pezzo, una volta. Un giocatore non può passare nel suo turno. Un giocatore può spostare uno qualsiasi dei suoi pezzi nello slot successivo non occupato a destra o a sinistra, il che può comportare il salto su slot occupati. Un giocatore non può spostare un pezzo dal lato del tabellone.

Se una mossa crea un modello in cui i pezzi dell'avversario sono circondati, su entrambi i lati, da due pezzi del colore del motore (senza spazio vuoto non occupato), allora quei pezzi circondati vengono rimossi dal tabellone.

L'obiettivo del gioco è rimuovere tutti i pezzi del tuo avversario, a quel punto il gioco termina. Anche la rimozione di tutti tranne uno termina il gioco, poiché l'avversario non può circondarti di un pezzo e quindi perderà comunque in poche mosse.

Ho trovato questo gioco online e mi chiedevo: si può giocare a golf?

Regole del golf

  • Il tuo codice deve seguire tutte le regole del gioco, gestire le catture, muoversi correttamente, ecc. (L'unica eccezione è che non devi aggiungere un bot, ma devi avere entrambi i giocatori controllati in qualche modo e un giocatore deve essere umano).
  • L'ingresso deve essere spostare il pezzo dalla tessera X alla tessera Y, oppure uscire. Ad esempio, puoi usare 1 4per dire 'sposta questo pezzo dalla tessera 1 alla tessera 4'. quitfinirebbe il programma, sebbene l'utilizzo Control- Csarebbe accettabile. Devi anche verificare se una mossa non è valida (andando fuori dal tabellone o spostandoti in un punto in cui dovresti attraversare spazi non occupati per raggiungere o inviare un messaggio che non è una coppia di tessere o quit).
  • Uscite per i giocatori vincenti e non validi devono essere P1 WINS, P2 WINSe INVALID, rispettivamente. (Tutti questi sono 7 caratteri.)
  • L'output deve mostrare la scheda. Questo è tutto ciò che è richiesto.
  • Non importa se usi aiuti come tessere numerate o altri pezzi.
  • La sfida termina se:

    • Una risposta ottiene 50 voti
    • Una risposta rimane la più votata per 3 settimane e nessuna altra risposta è stata pubblicata in quel momento

e la sfida ha almeno 3 risposte (quindi c'è qualche vera competizione).

Le regole del gioco

  • Il giocatore a sinistra deve iniziare per primo.
  • Solo un pezzo occupa un quadrato alla volta. Sposta il pezzo a sinistra o a destra fino a quando non colpisce uno spazio non occupato. La scheda non si avvolge e non puoi muoverti tra le aree non occupate. Per esempio:
    • xoo__o. Qui, la xdestra in movimento cambierebbe la scheda in _oox_o.
    • xxooo_. Qui, la sinistra più lontana xpotrebbe spostarsi per cedere _xooox, che cattura la os, lasciando _x___x.
    • x__oox. Qui, le os non vengono catturate (c'è ancora un gap). L'acquisizione non è possibile perché non è possibile spostarsi attraverso spazi non occupati. La xa sinistra poteva spostare solo di uno spazio, perché non ci sono altri pezzi in mezzo (in partenza _x_oox).
  • Più pezzi adiacenti possono essere catturati contemporaneamente se il gruppo è circondato dai pezzi dell'avversario. Ad esempio, da x_ooxa _xooxacquisirà entrambi oi risultati _x__x.
  • Se dopo una mossa, catturi prima i pezzi dell'avversario , prima di verificare se il tuo pezzo deve essere rimosso. Prendi due esempi:
    • o_oxxa oxox_. Innanzitutto, il secondo oviene catturato ox_x_, quindi il primo xrimane sul tabellone.
    • o_ooxa oxoo_. Questa volta, nessuna delle os viene catturata, quindi xviene catturata invece.
    • Se hai un solo pezzo, il gioco finisce, perché non puoi catturare con un solo pezzo.

Che i giochi inizino! Non vedo l'ora di vedere cosa ti viene in mente.


I commenti sono stati eliminati perché obsoleti. Vi prego di avvisarmi di eventuali commenti che dovrebbero essere eliminati.
Maniglia della porta

Risposte:


9

C, 617 592 byte

#define O(x)(x-'x'?'x':'o')
q,f,t,k,i,x=4,o=4,*d;main(){char*A,Q[9],c='x',b[]="xxxx___oooo";printf(b);while(!q){scanf(" %8[^\n]%*[^\n]",Q);if(!strcmp(Q,"quit"))break;f=*Q>47&&*Q<58?atoi(Q):-1;A=f>9?Q+2:Q+1;t=*A==32&&A[1]>47&&A[1]<58?atoi(A+1):-1;i=t==f&&t<0&&f<0?1:0;for(k=f;k!=t;k+=(t-f)/abs(t-f))if(b[k]==95||b[t]-95||b[f]-c)i=1;if(i){printf("INVALID");continue;}b[t]=c;b[f]=95;for(t=0;t<2;t++){d=c-'x'?&o:&x;for(k=1;k<11;k++)if(b[k]==O(c)){for(i=k+1;b[i]==O(c)&&b[i];i++);if(b[i]==c&&b[k-1]==c)while(k<i)b[k++]=95,(*d)--;}c=t?c:O(c);}printf(b);if(o<2||x<2)printf("P%d WINS",(x>1)+1),q=1;}}

svelato:

#define O(x)(x-'x'?'x':'o')
q,f,t,k,i,x=4,o=4,*d;
main(){
    char*A,Q[9],c='x',b[]="xxxx___oooo";
    printf(b);
    while(!q){
        scanf(" %8[^\n]%*[^\n]",Q);
        if(!strcmp(Q,"quit"))break;
        f=*Q>47&&*Q<58?atoi(Q):-1;
        A=f>9?Q+2:Q+1;
        t=*A==32&&A[1]>47&&A[1]<58?atoi(A+1):-1;
        i=t==f&&t<0&&f<0?1:0;
        for(k=f;k!=t;k+=(t-f)/abs(t-f))
            if(b[k]==95||b[t]-95||b[f]-c)
                i=1;
        if(i){
            printf("INVALID");
            continue;
        }
        b[t]=c;
        b[f]=95;
        for(t=0;t<2;t++){
            d=c-'x'?&o:&x;
            for(k=1;k<11;k++)
                if(b[k]==O(c)){
                    for(i=k+1;b[i]==O(c)&&b[i];i++);
                    if(b[i]==c&&b[k-1]==c)
                        while(k<i)b[k++]=95,(*d)--;
                }
            c=t?c:O(c);
        }
        printf(b);
        if(o<2||x<2)printf("P%d WINS",(x>1)+1),q=1;
    }
}

Volevo davvero ottenere questo in ~ 400 byte, ma ci sono molte piccole regole qui e l'elaborazione dell'input è risultata piuttosto odiosa. Non ho assolutamente finito con questo. Ecco una serie di esecuzioni di esempio che coprono praticamente tutto:

xxxx___oooo0 4
_xxxx__oooo7 6
_xxxx_o_ooo4 5
_xxx_xo_ooo8 6
INVALID8 7
_xxx_xoo_oo3 4
_xx_xxoo_oo7 3
_xxo__o__oo1 4
__x_x_o__oo10 9
INVALID10 8
__x_x_o_oo_2 3
___xx_o_oo_6 5
___xxo__oo_6 6
INVALID5 5
INVALID3 6
____x_x_oo_8 7
____x_xo_o_6 8
____x__o_o_P2 WINS

xxxx___oooo0 4
_xxxx__oooo10 6
_xxxx_oooo_1 5
__xxxxoooo_9 1
_o____ooo__P2 WINS

xxxx___oooo0 4
_xxxx__oooo7 6
_xxxx_o_ooo1 5
__xxxxo_ooo10 7
__xxxxoooo_2 10
___xxx____xP1 WINS

xxxx___oooo3 4
xxx_x__ooooquits
INVALIDtestme
INVALID3*4
INVALID3 four
INVALIDthree four
INVALIDthisstringislongerthanmybuffer
INVALID10 0
INVALID4 5
INVALID7 6
xxx_x_o_oooquit

Se ho interpretato male qualcosa, per favore fatemi sapere!


L'ho provato, funziona bene e nulla è stato lasciato fuori. Buon lavoro!
ASCIIThenANSI,

È possibile salvare alcuni byte sostituendo printf("INVALID");con puts("INVALID");, o<2||x<2con o<2|x<2e printf(b);while(!q){confor(printf(b);!q;){
es1024

3

PHP - 505

<?php
$s="xxxx___ooo".$y=o;$x=x;$c=function($m)use(&$x){return$x.str_repeat('_',strlen($m[1])).$x;};$e='$s=preg_replace_callback("~$x($y+)$x~",$c,$s);';$_=substr_count;while(true){echo$s;if($_($s,x)<2)die("P2 WINS");if($_($s,o)<2)die("P1 WINS");$i=trim(fgets(STDIN));if($i=='quit')die;if(!preg_match('!^(\d+) (\d+)$!',$i,$m)||$s[$f=$m[1]]!=$x||$s[$t=$m[2]]!="_"||(0&($a=min($f,$t))&$b=max($f,$t))||$_($s,"_",$a,($b-$a)+1)>1)echo"INVALID\n";else{$s[$f]='_';$s[$t]=$x;eval($e);$z=$x;$x=$y;$y=$z;eval($e);}}

Le comunicazioni devono essere eliminate reindirizzando STDERRa /dev/null.

Con spazi bianchi sani:

<?php
@$s = "xxxx___ooo".($y = o);
@$x = x;
$c = function($m)usea(&$x){
    return$x.str_repeat('_',strlen($m[1])).$x;
};
$e = '$s=preg_replace_callback("~$x($y+)$x~",$c,$s);';
@$_ = substr_count;
while (true){
    echo $s;

    if (@$_($s,x) < 2) die("P2 WINS");
    if (@$_($s,o) < 2) die("P1 WINS");

    $i = trim(fgets(STDIN));
    if($i == 'quit') die;

    if( !preg_match('!^(\d+) (\d+)$!',$i,$m)
    ||   $s[$f = $m[1]] != $x
    ||  @$s[$t = $m[2]] != "_"
    ||  (0 & ($a = min($f, $t)) & $b = max($f, $t))
    ||  $_($s, "_", $a, ($b - $a) + 1) > 1
    ) echo "INVALID\n";
    else {
        $s[$f] = '_';
        $s[$t] = $x;
        eval($e);
        $z = $x;
        $x = $y;
        $y = $z;
        eval($e);
    }
}

Con i casi di test di BrainSteel:

xxxx___oooo0 4
_xxxx__oooo7 6
_xxxx_o_ooo4 5
_xxx_xo_ooo8 6
INVALID
_xxx_xo_ooo8 7
_xxx_xoo_oo3 4
_xx_xxoo_oo7 3
_xxo__o__oo1 4
__x_x_o__oo10 9
INVALID
__x_x_o__oo10 8
__x_x_o_oo_2 3
___xx_o_oo_6 5
___xxo__oo_6 6
INVALID
___xxo__oo_5 5
INVALID
___xxo__oo_3 6
____x_x_oo_8 7
____x_xo_o_6 8
____x__o_o_P2 WINS

xxxx___oooo0 4
_xxxx__oooo10 6
_xxxx_oooo_1 5
__xxxxoooo_9 1
_o____ooo__P2 WINS

xxxx___oooo0 4
_xxxx__oooo7 6
_xxxx_o_ooo1 5
__xxxxo_ooo10 7
__xxxxoooo_2 10
___xxx____xP1 WINS

xxxx___oooo3 4
xxx_x__ooooquits
INVALID
xxx_x__ooootestme
INVALID
xxx_x__oooo3*4
INVALID
xxx_x__oooo3 four
INVALID
xxx_x__oooothree four
INVALID
xxx_x__oooothisstringislongerthanmybuffer
INVALID
xxx_x__oooo10 0
INVALID
xxx_x__oooo4 5
INVALID
xxx_x__oooo7 6
xxx_x_o_oooquit

Cosa intendi con "avvisi / avvertenze"?
ASCIIThenANSI

@ASCIIThenANSI Avvertimenti a causa di valori letterali di caratteri non quotati: Avviso PHP: Uso della costante non definita o - assunto 'o' in /tmp/pcg-48388.php sulla riga 2. È possibile reindirizzarli a / dev / null.
TimWolla,

Ciò interrompe il programma?
ASCIIThenANSI

@ASCIIThenANSI No, funziona bene se vengono reindirizzati /dev/null.
TimWolla,

Quindi va bene averlo finché il programma continua a funzionare correttamente e vengono reindirizzati a /dev/null.
ASCIIThenANSI

1

Python 2, 536 509 448 441 byte

Chiama via a(); le mosse devono essere inserite nel modulo piece,destination(cioè, 1,4); esci con Ctrl-C. Se qualcuno può vedere più potenziale di golf, sono tutto orecchi.

b,r,x='_',lambda p:''.join([p[i]for i in x]),range(11)
def a(m='xo'):
 t=w=0;p=dict(zip(x,'xxxx___oooo'))
 while w<1:
    print r(p);y=m[t%2]
    try:
     s,v=input();1/all([y==p[s],{v}<{r(p).rfind(b,0,s),r(p).find(b,s)},v-s]);p[s],p[v],h,c=b,y,0,{}  
     for _ in y,m[-~t%2]:
        for i in p:exec{_:"h=1;p.update(c)",b:"h,c=0,{}"}.get(p[i],h*"c[i]=b")
     w=min(map(r(p).count,m))<2;t+=1
    except:print"INVALID"
 print"P%d WINS"%-~(r(p).count('o')<2)

1

SpecBAS - 718 byte

SpecBAS è una versione aggiornata di Sinclair / ZX BASIC che può essere eseguita all'esterno di un emulatore. (Ancora interpretato).

Ho usato alcune delle nuove funzionalità per ridurre le dimensioni il più possibile.

La riga 12 imposta una regex per la ricerca di pezzi "sandwich" usando inline IF e la riga 18 usa la natura avvolgente di INC (piuttosto che dire INC p: IF p=3 THEN LET p=1)

1 LET b$="xxxx---oooo": LET p=1: LET c$="xo": DIM s=4,4
2 LET v=0: PRINT b$'"[";p;"] ";
3 INPUT m$: IF m$(1)="Q" THEN PRINT "QUIT": STOP 
4 LET f=VAL(ITEM$(m$,1," ")): LET t=VAL(ITEM$(m$,2," ")): PRINT f;" ";t
5 IF (f<1 OR f>11) OR (t<1 OR t>11) THEN LET v=1: GO TO 10
6 IF (b$(f)<>c$(p)) OR b$(t)<>"-" THEN LET v=1: GO TO 10
7 FOR i=f TO t STEP SGN(t-f)
8 IF b$(i)="-" THEN IF i<>t THEN LET v=1
9 NEXT i
10 IF v=1 THEN PRINT "INVALID": GO TO 2
11 LET b$(t)=b$(f): LET b$(f)="-"
12 LET r$=IIF$(p=1,"xo+x","ox+o")
13 LET m=MATCH(r$,b$): IF m=0 THEN GO TO 18
14 FOR i=m+1 TO POS(c$(p),b$,m+2)
15 IF b$(i)=c$(3-p) THEN LET b$(i)="-": DEC s(3-p): END IF
16 NEXT i
17 IF s(3-p)<2 THEN PRINT b$'"P";p;" WINS": STOP 
18 INC p,1 TO 2
19 GO TO 2

Output (impossibile copiare dalla vedova di output, quindi schermata) inserisci qui la descrizione dell'immagine

inserisci qui la descrizione dell'immagine


0

C #, 730 byte

using System;using System.Linq;class P{static void Main(string[]z){int p=1,d,e,g,x,y;var b=new[]{3,1,1,1,1,0,0,0,2,2,2,2};var o=new[]{"_","x","o"};Action<string>h=s=>{Console.Write(s,p);Environment.Exit(0);};Action i=()=>h("INVALID");Func<int,int,bool>j=(q,r)=>b.Select((v,w)=>w<=q||w>=r||v>0?0:w).Any(w=>w>0);Action<int>k=m=>{e=0;for(d=1;d<12;d++){if(b[d]==m){if(e>0&&!j(e,d))for(g=e+1;g<d;g++)b[g]=0;e=d;}}if(b.Count(w=>w>0&&w!=m)<3)h("P{0} WINS");};try{for(;;){for(g=1;g<12;g++)Console.Write(o[b[g]]);var n=Console.ReadLine();if(n=="quit")h("");var c=n.Split(' ');x=int.Parse(c[0]);y=int.Parse(c[1]);if(c.Length>2||b[x]!=p||b[y]!=0||(p>1?y:x)>=(p>1?x:y)||j(x<y?x:y,x<y?y:x))i();b[x]=0;b[y]=p;k(p);p=p>1?1:2;k(p);}}catch{i();}}}

Immagino che siano possibili ulteriori miglioramenti. D'altra parte, ho interpretato l' INVALIDoutput come termine dell'esecuzione, quindi potrebbe essere necessario risolvere il problema per essere in parità con altre risposte.

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.