En kısa alak oyununu yaz


10

Alak, matematikçi AK Dewdney tarafından icat edildi ve 1984 tarihli Planiverse kitabında açıklandı. Alak'ın kuralları basit:

Alak, on bir yuvalı tek boyutlu bir tahtada oynanan iki kişilik bir oyundur. Her yuva bir seferde en fazla bir parça tutabilir. İki tür parça vardır, "x" ve "o". x bir oyuncuya ait, o diğer oyuncuya ait. Kartın ilk yapılandırması:

      xxxx___oooo

Oyuncular sırayla hareket ediyor. Her turda, her oyuncu bir defada sadece bir taş hareket edebilir. Bir oyuncu sırayla pas alamaz. Bir oyuncu taşlarından herhangi birini boş veya boş olan bir sonraki boş yuvaya taşıyabilir, bu da işgal edilmiş yuvaların üzerinden atlamayı içerebilir. Oyuncu bir parçayı tahtanın yanından çıkaramaz.

Eğer bir hamle, rakibin taşlarının her iki tarafta, taşıyıcının renginin iki parçasıyla (arada kalan boş yuva olmadan) çevrelendiği bir desen oluşturursa, o çevrili parçalar tahtadan çıkarılır.

Oyunun amacı, rakibinizin tüm parçalarını kaldırmaktır, bu noktada oyun biter. All-one-one'ı kaldırmak oyunu da bitirir, çünkü rakip sizi tek parça ile kuşatamaz ve bu yüzden her zaman birkaç hamle içinde kaybeder.

Bu oyunu online buldum ve merak ediyordum: golf oynayabilir mi?

Golf kuralları

  • Kodunuz, oyundaki tüm kurallara uymalı, yakalama işlemlerini, uygun hareket etmeyi vb. (Tek istisna, bir bot eklemeniz gerekmemesi, ancak her iki oyuncunun da bir şekilde kontrol edilmesi ve bir oyuncunun insan olması gerekir).
  • Giriş, döşemeyi X döşemesinde Y döşemesine taşımalı veya çıkmalıdır. Örneğin, 1 4'bu parçayı 1. döşemeye 4. döşemeye taşı' diyebilirsiniz. quitprogramı Control- sona Cerse de - kabul edilebilir. Ayrıca, bir hareketin geçersiz olup olmadığını da kontrol etmelisiniz (tahtanın dışına çıkarak veya bir çift fayans veya olmayan bir mesaj göndermek veya boş alanların üzerinden geçmek zorunda kalacağınız bir yere taşınarak quit).
  • Kazanan oyuncular ve geçersiz için Çıkışlar olmalı P1 WINS, P2 WINSve INVALIDsırasıyla. (Bunların hepsi 7 karakterdir.)
  • Çıktı panosu göstermelidir. Tüm gereken bu.
  • Numaralı fayans veya diğer parçalar gibi yardımcıları kullanmanız önemli değildir.
  • Zorluk şu durumlarda sona erer:

    • Bir cevap 50 oy alır
    • Bir cevap 3 hafta boyunca en çok oy alan seçildi ve o zaman başka cevap gönderilmedi

ve mücadelenin en az 3 cevabı var (bu yüzden gerçek bir rekabet var).

Oyunun kuralları

  • Soldaki oyuncu ilk olarak başlamalıdır.
  • Bir seferde sadece bir parça kare kaplar. Parçayı boş bir alana varana kadar sola veya sağa hareket ettirirsiniz. Tahta sarılmaz ve boş alanlardan geçemezsiniz. Örneğin:
    • xoo__o. Burada, xsağa hareket etmek kurulu değiştirir _oox_o.
    • xxooo_. Burada, en soldaki xhareket _xooox, os'yi yakalayarak ayrılmaya başlayabilir _x___x.
    • x__oox. Burada, os yakalanmaz (hala bir boşluk vardır). Yakalamak mümkün değildir, çünkü boş alanlardan geçemezsiniz. xSoldaki ancak başka parçalar arasında olduğundan (bırakarak bir boşluk hareket edebilir _x_oox).
  • Eğer grup rakibin taşlarıyla çevrelenmişse, birden fazla bitişik taş yakalanabilir. Örneğin gelen x_ooxetmek _xooxhem yakalayacaktır os ve neden _x__x.
  • Bir hamleden sonra , kendi parçanızın kaldırılıp kaldırılmayacağını kontrol etmeden önce rakibin taşlarını yakalarsınız. İki örnek alın:
    • o_oxxiçin oxox_. Birincisi, ikincisi oyakalanır ox_x_, böylece ilki xtahtada kalır.
    • o_ooxiçin oxoo_. Bu sefer, hiçbir os yakalanmaz, xbunun yerine yakalanır.
    • Sadece bir parçanız varsa, oyun biter, çünkü tek bir parça ile yakalayamazsınız.

Oyunlar başlasın! Ne bulduğunuzu görmek için sabırsızlanıyorum.


Yorumlar eskimiş olduğu için tasfiye edildi. Silinmesi gereken tüm yorumlar için lütfen beni bilgilendirin.
Kapı Tokmağı

Yanıtlar:


9

C, 617592 bayt

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

sökülmüş:

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

Bunu ~ 400 baytta almak istedim, ancak burada çok az kural var ve giriş işlemleri oldukça iğrenç hale geldi. Bunu kesinlikle bitirmedim. İşte hemen hemen her şeyi kapsayan bir dizi örnek çalıştırma:

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

Bir şeyi yanlış yorumladıysam, lütfen bana bildirin!


Test ettim, iyi çalışıyor ve hiçbir şey kalmadı. Aferin!
ASCIIThenANSI

Sen değiştirerek birkaç byte kaydedebilirsiniz printf("INVALID");ile puts("INVALID");, o<2||x<2birlikte o<2|x<2ve printf(b);while(!q){birliktefor(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);}}

Uyarılar yönlendirerek bastırılmış olmalıdır STDERRiçin /dev/null.

Aklı başında boşluk olan:

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

BrainSteel test vakaları ile:

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

'Bildirimler / uyarılar' ile ne demek istiyorsun?
ASCIIThenANSI

@ASCIIThenANSI Alıntılanmamış karakter değişmezleri nedeniyle uyarılar: PHP Uyarı: 2. satırdaki /tmp/pcg-48388.php dosyasındaki tanımsız sabit o - varsayılan 'o' kullanımı. / Dev / null öğesine yönlendirebilirsiniz.
TimWolla

Bu programı bozuyor mu?
ASCIIThenANSI

@ASCIIThenANSI Hayır, yönlendirildiği için iyi çalışıyor /dev/null.
TimWolla

Ardından, program düzgün çalışmaya devam ettiği ve yeniden yönlendirildiği sürece buna sahip olmak sorun değildir /dev/null.
ASCIIThenANSI

1

Python 2, 536 509 448 441 bayt

Aramak için a(); hareketler forma piece,destination(ör. 1,4) girilmelidir ; Ctrl-C ile çıkın. Eğer kimse daha fazla golf potansiyeli görebilirse, ben kulaklarım.

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 bayt

SpecBAS , bir emülatörün dışında çalışabilen Sinclair / ZX BASIC'in güncellenmiş bir sürümüdür. (Hala yorumlanmaktadır).

Boyutu olabildiğince azaltmak için yeni özelliklerden bazılarını kullandım.

Satır 12, satır içi IF kullanarak "sandviç" parçaları aramak için bir normal ifade oluşturur ve satır 18 INC'nin doğası etrafındaki sargıyı kullanır (söylemek yerine 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

Çıktı (çıkış dulundan kopyalanamaz, bu yüzden ekran görüntüsü) resim açıklamasını buraya girin

resim açıklamasını buraya girin


0

C #, 730 bayt

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

Daha fazla iyileştirmenin mümkün olduğunu düşünüyorum. Öte yandan, INVALIDçıktıyı yürütmeyi sona erdirme olarak yorumladım , bu yüzden bu konuyu diğer cevaplarla eşleşecek şekilde düzeltmem gerekebilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.