Schreiben Sie das kürzeste Alak-Spiel

10

Alak wurde vom Mathematiker AK Dewdney erfunden und in seinem 1984 erschienenen Buch Planiverse beschrieben. Die Regeln von Alak sind einfach:

Alak ist ein Zwei-Spieler-Spiel, das auf einem eindimensionalen Brett mit elf Slots gespielt wird. Jeder Steckplatz kann höchstens ein Stück gleichzeitig aufnehmen. Es gibt zwei Arten von Stücken, "x" und "o". x gehören einem Spieler, o dem anderen. Die anfängliche Konfiguration der Karte lautet:

      xxxx___oooo

Die Spieler wechseln sich ab. In jeder Runde kann jeder Spieler nur einmal eine Figur bewegen. Ein Spieler kann seinen Zug nicht verpassen. Ein Spieler kann eine seiner Figuren auf den nächsten freien Platz rechts oder links verschieben, was das Springen über besetzte Plätze bedeuten kann. Ein Spieler kann keine Figur von der Seite des Bretts bewegen.

Wenn ein Zug ein Muster erzeugt, bei dem die Teile des Gegners auf beiden Seiten von zwei Teilen der Farbe des Bewegers umgeben sind (ohne dazwischen liegenden unbesetzten leeren Schlitz), werden diese umgebenen Teile vom Brett entfernt.

Das Ziel des Spiels ist es, alle Teile deines Gegners zu entfernen. An diesem Punkt endet das Spiel. Das Entfernen von All-außer-Eins beendet das Spiel ebenfalls, da der Gegner Sie nicht mit einer Figur umgeben kann und daher immer innerhalb weniger Züge verliert.

Ich fand dieses Spiel online und fragte mich: Kann es Golf gespielt werden?

Regeln des Golfsports

  • Ihr Code muss allen Regeln im Spiel folgen, mit Captures umgehen, sich richtig bewegen usw. (einzige Ausnahme ist, dass Sie keinen Bot hinzufügen müssen, aber beide Spieler müssen irgendwie kontrolliert werden und ein Spieler muss ein Mensch sein).
  • Die Eingabe muss auf Kachel X auf Kachel Y verschoben oder beendet werden. Sie können beispielsweise 1 4sagen, dass Sie dieses Teil auf Kachel 1 auf Kachel 4 verschieben möchten. quitwürde das Programm beenden, obwohl die Verwendung von Control- Cakzeptabel wäre. Sie müssen auch überprüfen, ob ein Zug ungültig ist (indem Sie außerhalb des Spielfelds gehen oder an einen Ort ziehen, an dem Sie nicht belegte Bereiche überqueren müssten, um zu einer Nachricht zu gelangen oder eine Nachricht zu senden, die kein Kachelpaar ist oder quit).
  • Ausgänge für die Spieler zu gewinnen und ungültig sein muss P1 WINS, P2 WINSund INVALID, respectively. (Alle diese sind 7 Zeichen.)
  • Die Ausgabe muss die Karte anzeigen. Das ist alles was benötigt wird.
  • Es spielt keine Rolle, ob Sie Hilfsmittel wie nummerierte Kacheln oder andere Teile verwenden.
  • Die Herausforderung endet, wenn:

    • Eine Antwort erhält 50 Stimmen
    • Eine Antwort bleibt 3 Wochen lang die am besten gewählte, und in dieser Zeit wurden keine anderen Antworten veröffentlicht

und die Herausforderung hat mindestens 3 Antworten (es gibt also echte Konkurrenz).

Spielregeln

  • Der Spieler links muss zuerst starten.
  • Es nimmt jeweils nur ein Stück ein Quadrat ein. Sie bewegen das Stück nach links oder rechts, bis es auf ein nicht besetztes Feld trifft. Das Brett wickelt sich nicht ein und Sie können sich nicht durch unbesetzte Bereiche bewegen. Beispielsweise:
    • xoo__o. Hier xwürde die Bewegung nach rechts das Board ändern _oox_o.
    • xxooo_. Hier xkönnte sich die am weitesten links stehende Person bewegen, um nachzugeben _xooox, was das os einfängt und verlässt _x___x.
    • x__oox. Hier werden die os nicht erfasst (es gibt noch eine Lücke). Die Erfassung ist nicht möglich, da Sie sich nicht durch nicht belegte Bereiche bewegen können. Die xlinks konnten nur ein Feld bewegen, da sich keine anderen Teile dazwischen befinden (Verlassen _x_oox).
  • Mehrere benachbarte Teile können gleichzeitig erfasst werden, wenn die Gruppe von den Teilen des Gegners umgeben ist. ZB von x_ooxbis _xooxerfasst beide os und führt zu _x__x.
  • Wenn Sie nach einem Zug zuerst die Figuren des Gegners erfassen , bevor Sie prüfen, ob Ihre eigene Figur entfernt werden soll. Nehmen Sie zwei Beispiele:
    • o_oxxzu oxox_. Erstens wird der zweite oerfasst, ox_x_sodass der erste xauf dem Brett bleibt.
    • o_ooxzu oxoo_. Dieses Mal wird keines der os erfasst, daher xwird stattdessen das s erfasst.
    • Wenn Sie nur eine Figur haben, endet das Spiel, da Sie nicht mit nur einer Figur erfassen können.

Lasst die Spiele beginnen! Ich freue mich darauf zu sehen, was Sie sich einfallen lassen.

ASCIIThenANSI
quelle
Kommentare wurden gelöscht, da sie veraltet waren. Bitte benachrichtigen Sie mich über Kommentare, die nicht gelöscht werden sollten.
Türknauf

Antworten:

9

C 617 592 Bytes

#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;}}

Enträtselt:

#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;
    }
}

Ich wollte dieses wirklich in ~ 400 Bytes bekommen, aber es gibt viele kleine Regeln hier und die Eingabeverarbeitung endete ziemlich widerlich. Damit bin ich definitiv nicht fertig. Hier ist eine Reihe von Beispielläufen, die fast alles abdecken:

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

Wenn ich etwas falsch interpretiert habe, lass es mich wissen!

BrainSteel
quelle
Ich habe es getestet, es funktioniert gut und nichts wurde ausgelassen. Gut gemacht!
ASCIIThenANSI
Sie können ein paar Bytes sparen, indem Sie printf("INVALID");durch puts("INVALID");, o<2||x<2mit o<2|x<2und printf(b);while(!q){mitfor(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);}}

Benachrichtigungen müssen durch Umleiten STDERRan unterdrückt werden /dev/null.

Mit vernünftigen Leerzeichen:

<?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);
    }
}

Mit den Testfällen von 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
TimWolla
quelle
Was meinst du mit "Hinweisen / Warnungen"?
ASCIIThenANSI
@ASCIIThenANSI Warnungen wegen nicht zitierter Zeichenliterale: PHP Hinweis: Verwendung der undefinierten Konstante o - angenommen 'o' in /tmp/pcg-48388.php in Zeile 2. Man kann sie nach / dev / null umleiten.
TimWolla
Bricht das das Programm?
ASCIIThenANSI
@ASCIIThenANSI Nein, es funktioniert gut, wenn sie umgeleitet werden /dev/null.
TimWolla
Dann ist es in Ordnung, es zu haben, solange das Programm weiterhin ordnungsgemäß funktioniert und sie umgeleitet werden /dev/null.
ASCIIThenANSI
1

Python 2, 536 509 448 441 Bytes

Anruf über a(); Züge sind in der Form piece,destination(dh 1,4) einzugeben; Beenden Sie mit Strg-C. Wenn jemand mehr Golfpotential sehen kann, bin ich ganz Ohr.

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)
Sirpercival
quelle
1

SpecBAS - 718 Bytes

SpecBAS ist eine aktualisierte Version von Sinclair / ZX BASIC, die außerhalb eines Emulators ausgeführt werden kann. (Immer noch interpretiert).

Habe einige der neuen Funktionen verwendet, um die Größe so weit wie möglich zu verringern.

Zeile 12 richtet einen regulären Ausdruck ein, um mithilfe von Inline-IF nach "Sandwich" -Stücken zu suchen, und Zeile 18 verwendet die Umlaufnatur von INC (anstatt zu sagen 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

Ausgabe (kann nicht von der Ausgabe-Witwe kopiert werden, also Screenshot) Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Brian
quelle
0

C #, 730 Bytes

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();}}}

Ich stelle mir vor, dass weitere Verbesserungen möglich sind. Auf der anderen Seite habe ich die INVALIDAusgabe als Beendigung der Ausführung interpretiert , sodass ich dieses Problem möglicherweise beheben muss, um mit anderen Antworten gleich zu sein.

Andrew
quelle