Viết trò chơi ngắn nhất của alak


10

Alak được phát minh bởi nhà toán học AK Dewdney, và được mô tả trong cuốn sách Planiverse năm 1984 của ông. Các quy tắc của Alak rất đơn giản:

Alak là một trò chơi hai người chơi trên một bảng một chiều với mười một khe trên đó. Mỗi khe có thể chứa tối đa một mảnh cùng một lúc. Có hai loại mảnh, "x" và "o". x thuộc về một người chơi, thuộc về người chơi khác. Cấu hình ban đầu của bảng là:

      xxxx___oooo

Các cầu thủ thay phiên nhau di chuyển. Ở mỗi lượt, mỗi người chơi chỉ có thể di chuyển một mảnh, một lần. Một người chơi không thể vượt qua lượt của mình. Người chơi có thể di chuyển bất kỳ một trong những quân cờ của mình sang vị trí không có người tiếp theo sang phải hoặc trái, điều này có thể liên quan đến việc nhảy qua các vị trí bị chiếm đóng. Một người chơi không thể di chuyển một mảnh ra khỏi bảng.

Nếu di chuyển tạo ra một mô hình trong đó các mảnh của đối thủ được bao quanh, ở cả hai bên, bởi hai mảnh màu của động cơ (không có khe trống không được can thiệp), thì các mảnh được bao quanh sẽ bị xóa khỏi bảng.

Mục tiêu của trò chơi là loại bỏ tất cả các quân cờ của đối thủ, tại thời điểm trò chơi kết thúc. Loại bỏ tất cả mọi thứ cũng kết thúc trò chơi, vì đối thủ không thể bao vây bạn bằng một mảnh, và vì vậy dù sao cũng sẽ luôn thua trong một vài động tác.

Tôi tìm thấy trò chơi này trực tuyến và tự hỏi: nó có thể được chơi golf không?

Luật chơi golf

  • Mã của bạn phải tuân theo tất cả các quy tắc trong trò chơi, xử lý các cảnh quay, di chuyển thích hợp, v.v. (chỉ có ngoại lệ là bạn không phải thêm bot, nhưng bạn phải kiểm soát cả hai người chơi và một người chơi phải là người).
  • Đầu vào phải được di chuyển mảnh tại ô X sang ô Y hoặc thoát. Ví dụ: bạn có thể sử dụng 1 4để nói 'di chuyển đoạn này tại ô 1 sang ô 4'. quitsẽ kết thúc chương trình, mặc dù sử dụng Control- Csẽ được chấp nhận. Bạn cũng phải kiểm tra xem một di chuyển có hợp lệ không (bằng cách đi ra ngoài bảng hoặc di chuyển đến một nơi nào đó mà bạn sẽ phải vượt qua các không gian trống để đến hoặc gửi tin nhắn không phải là một cặp hoặc quit).
  • Đầu ra cho người chơi chiến thắng và không hợp lệ phải là P1 WINS, P2 WINSINVALID, tương ứng. (Tất cả đều có 7 ký tự.)
  • Đầu ra phải hiển thị bảng. Đó là tất cả những gì cần thiết.
  • Sẽ không có vấn đề gì nếu bạn sử dụng bất kỳ công cụ hỗ trợ nào như gạch được đánh số hoặc các phần khác.
  • Thử thách kết thúc nếu:

    • Một câu trả lời được 50 phiếu
    • Một câu trả lời vẫn được bình chọn hàng đầu trong 3 tuần và không có câu trả lời nào khác được đăng trong thời gian đó

và thử thách có ít nhất 3 câu trả lời (vì vậy có một số cạnh tranh thực sự).

Nội quy của trò chơi

  • Người chơi bên trái phải bắt đầu trước.
  • Chỉ có một mảnh chiếm một hình vuông tại một thời điểm. Bạn di chuyển mảnh sang trái hoặc phải cho đến khi nó chạm vào một không gian trống. Bảng không bọc và bạn không thể di chuyển qua các khu vực không có người ở. Ví dụ:
    • xoo__o. Ở đây, xquyền di chuyển sẽ thay đổi bảng thành _oox_o.
    • xxooo_. Ở đây, phía xa nhất bên trái xcó thể di chuyển đến năng suất _xooox, bắt được os, rời đi _x___x.
    • x__oox. Ở đây, os không bị bắt (vẫn còn một khoảng trống). Không thể chụp vì bạn không thể di chuyển qua các không gian trống. Bên xtrái chỉ có thể di chuyển một không gian, bởi vì không có phần nào khác ở giữa (để lại _x_oox).
  • Nhiều mảnh liền kề có thể bị bắt cùng một lúc nếu nhóm bị bao vây bởi quân cờ của đối thủ. Ví dụ: từ x_ooxđến _xooxsẽ chụp cả os và kết quả _x__x.
  • Nếu sau khi di chuyển, trước tiên bạn chụp các mảnh của đối thủ , trước khi kiểm tra xem mảnh của riêng bạn có nên được gỡ bỏ không. Lấy hai ví dụ:
    • o_oxxđể oxox_. Đầu tiên, cái thứ hai ođược chụp ox_x_, vì vậy cái đầu tiên xvẫn còn trên bảng.
    • o_ooxđể oxoo_. Lần này, không ai trong số họ obị bắt, vì vậy người xta bị bắt thay.
    • Nếu bạn chỉ có một mảnh, trò chơi kết thúc, bởi vì bạn không thể chụp chỉ bằng một mảnh.

Hãy để cuộc chơi bắt đầu! Tôi mong muốn được nhìn thấy những gì bạn nghĩ ra.


Bình luận bị thanh trừng, vì chúng đã lỗi thời. Xin vui lòng thông báo cho tôi về bất kỳ ý kiến ​​nên được xóa.
Doorknob

Câu trả lời:


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

Làm sáng tỏ:

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

Tôi thực sự muốn có được cái này trong ~ 400 byte, nhưng có rất nhiều quy tắc nhỏ ở đây và việc xử lý đầu vào kết thúc khá đáng ghét. Tôi chắc chắn không làm điều này. Đây là một tập hợp các mẫu chạy bao gồm tất cả mọi thứ:

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

Nếu tôi giải thích sai điều gì đó, xin vui lòng cho tôi biết!


Tôi đã thử nó, nó hoạt động tốt, và không có gì bị bỏ rơi. Làm tốt lắm!
ASCIIThenANSI

Bạn có thể tiết kiệm một vài byte bằng cách thay thế printf("INVALID");với puts("INVALID");, o<2||x<2với o<2|x<2printf(b);while(!q){vớifor(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);}}

Thông báo phải được loại bỏ bằng cách chuyển hướng STDERRđến /dev/null.

Với khoảng trắng lành mạnh:

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

Với các trường hợp thử nghiệm của 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

Bạn có ý nghĩa gì bởi 'thông báo / cảnh báo'?
ASCIIThenANSI

@ASCIIThenANSI Cảnh báo vì các ký tự không được trích dẫn: Thông báo PHP: Sử dụng hằng số không xác định o - giả định 'o' trong /tmp/pcg-48388.php trên dòng 2. Người ta có thể chuyển hướng chúng đến / dev / null.
TimWolla

Điều đó có phá vỡ chương trình không?
ASCIIThenANSI

@ASCIIThenANSI Không, nó hoạt động tốt là chúng được chuyển hướng đến /dev/null.
TimWolla

Sau đó, sẽ ổn thôi nếu chương trình tiếp tục hoạt động bình thường và chúng được chuyển hướng đến /dev/null.
ASCIIThenANSI

1

Python 2, 536 509 448 441 byte

Gọi qua a(); di chuyển sẽ được nhập dưới dạng piece,destination(nghĩa là 1,4); thoát bằng Ctrl-C. Nếu bất cứ ai có thể nhìn thấy tiềm năng chơi gôn nhiều hơn, tôi đều là tai.

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 là phiên bản cập nhật của Sinclair / ZX BASIC có thể chạy bên ngoài trình giả lập. (Vẫn diễn giải).

Đã sử dụng một số tính năng mới để giảm kích thước hết mức có thể.

Dòng 12 thiết lập một biểu thức chính để tìm kiếm các phần "được kẹp" bằng cách sử dụng IF nội tuyến và dòng 18 sử dụng bao quanh bản chất của INC (thay vì nói 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

Đầu ra (không thể sao chép từ góa phụ đầu ra, vì vậy ảnh chụp màn hình) nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


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

Tôi tưởng tượng rằng những cải tiến hơn nữa là có thể. Mặt khác, tôi diễn giải INVALIDđầu ra là kết thúc thực hiện, vì vậy tôi có thể cần khắc phục vấn đề đó để tương đương với các câu trả lời khác.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.