alak의 가장 짧은 게임을 작성


10

Alak은 수학자 AK Dewdney에 의해 발명되었으며 그의 1984 년 책 Planiverse에 설명되어 있습니다. Alak의 규칙은 간단합니다.

Alak은 11 개의 슬롯이있는 1 차원 보드에서 재생되는 2 인용 게임입니다. 각 슬롯은 한 번에 최대 하나의 부품을 수용 할 수 있습니다. "x"와 "o"의 두 가지 조각이 있습니다. x는 한 선수에게, o는 다른 선수에게 속합니다. 보드의 초기 구성은 다음과 같습니다.

      xxxx___oooo

플레이어는 교대로 움직입니다. 매 턴마다 각 플레이어는 한 조각 만 움직일 수 있습니다. 플레이어는 자신의 차례를 넘길 수 없습니다. 플레이어는 자신의 조각 중 하나를 다음 비어있는 슬롯으로 오른쪽 또는 왼쪽으로 이동할 수 있으며,이 경우 점유 된 슬롯 위로 점프 할 수 있습니다. 플레이어는 보드 측면에서 조각을 이동할 수 없습니다.

움직임으로 상대방의 조각이 양쪽에 움직이는 두 가지 색으로 둘러싸여있는 패턴을 만들면 (빈 슬롯이없는 상태) 보드에서 제거 된 조각이 제거됩니다.

게임의 목표는 게임이 끝나는 시점에서 상대방의 모든 조각을 제거하는 것입니다. 상대를 한 조각으로 감쌀 수 없기 때문에 모든 것을 제거하면 게임도 끝납니다.

이 게임을 온라인에서 찾았으며 궁금한 점이 있습니다. 골프를 탈 수 있습니까?

골프의 규칙

  • 코드는 게임의 모든 규칙, 캡처 처리, 적절한 이동 등을 따라야합니다. 봇을 추가 할 필요는 없지만 두 플레이어가 어떻게 든 제어해야하며 한 플레이어는 사람이어야합니다.
  • 입력은 타일 X에서 타일 Y로 이동하거나 종료해야합니다. 예를 들어 1 4'타일 1에서이 조각을 타일 4로 이동'을 말하는 데 사용할 수 있습니다 . - quit사용하는 것이 허용 되지만 프로그램을 종료합니다 . 또한 이동이 유효하지 않은지 확인해야합니다 (보드 외부로 나가거나 비어있는 공간을 넘어서 타일 쌍이나 아닌 메시지를 보내거나 보내야하는 곳으로 이동 ).ControlCquit
  • 경력 선수 무효에 대한 출력은해야합니다 P1 WINS, P2 WINS그리고 INVALID각각. (모두 7 자입니다.)
  • 출력은 보드를 보여 주어야합니다. 그게 전부입니다.
  • 번호가 매겨진 타일이나 다른 조각과 같은 보조 도구를 사용하더라도 중요하지 않습니다.
  • 다음과 같은 경우 도전이 끝납니다.

    • 하나의 답변은 50 표를 얻습니다
    • 하나의 답변이 3 주 동안 가장 많이 투표 된 상태로 남아 있으며 그 때 다른 답변은 게시되지 않았습니다.

도전에는 3 가지 이상의 답변이 있습니다 (따라서 실제 경쟁이 있습니다).

게임의 규칙

  • 왼쪽 플레이어가 먼저 시작해야합니다.
  • 한 번에 한 조각 만 사각형을 차지합니다. 빈 공간에 닿을 때까지 조각을 왼쪽이나 오른쪽으로 움직입니다. 보드는 랩핑되지 않으며 빈 공간을 이동할 수 없습니다. 예를 들면 다음과 같습니다.
    • xoo__o. 여기서 x오른쪽으로 이동하면 보드가로 바뀝니다 _oox_o.
    • xxooo_. 여기에서 가장 왼쪽 x이 yield로 이동 _xooox하여을 캡처하고을 (를 o) 남깁니다 _x___x.
    • x__oox. 여기서 os는 캡처되지 않습니다 (아직 틈이 있습니다). 빈 공간을 이동할 수 없기 때문에 캡처 할 수 없습니다. x왼쪽은 다른 조각 사이에 없기 때문에 (떠나, 하나 개의 공간을 이동할 수있다 _x_oox).
  • 그룹이 상대방의 조각으로 둘러싸여 있으면 여러 개의 인접한 조각을 한 번에 캡처 할 수 있습니다. 예는에서 x_oox까지 _xoox모두 사로 잡을 것입니다 o들과의 결과 _x__x.
  • 이동 한 후에는 상대방 조각을 먼저 빼내어 자신의 조각을 제거해야하는지 확인합니다. 두 가지 예를 들어 보자.
    • o_oxxoxox_. 먼저, 두 번째 o는 캡처 ox_x_되므로 첫 번째 x는 보드에 남아 있습니다.
    • o_ooxoxoo_. 이번에는 os가 캡처 되지 않으므로 x대신 s 가 캡처됩니다.
    • 한 조각 만 가지고 있으면 한 조각만으로 캡처 할 수 없으므로 게임이 종료됩니다.

게임을 시작하자! 나는 당신이 무엇을 보게되기를 기대합니다.


더 이상 사용되지 않는 주석이 제거되었습니다. 삭제를 취소해야하는 의견이 있으면 알려주십시오.
Doorknob

답변:


9

C, 617 592 바이트

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

풀리지 않은 :

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

나는 이것을 ~ 400 바이트로 얻고 싶었지만 여기에는 많은 작은 규칙이 있으며 입력 처리는 꽤 불쾌합니다. 나는 이것으로 끝나지 않았다. 다음은 거의 모든 것을 다루는 일련의 샘플 실행입니다.

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

내가 잘못 해석 한 경우 알려주십시오.


나는 그것을 테스트했는데 잘 작동하며 아무것도 빠지지 않았다. 잘 했어!
ASCIIThenANSI

당신은 대체하여 몇 바이트를 저장할 수 printf("INVALID");puts("INVALID");, o<2||x<2o<2|x<2printf(b);while(!q){for(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);}}

로 리디렉션 STDERR하여 알림을 표시하지 않아야합니다 /dev/null.

제정신 공백으로 :

<?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의 테스트 사례 :

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

'알림 / 경고'는 무슨 뜻입니까?
ASCIIThenANSI

@ASCIIThenANSI 인용되지 않은 문자 리터럴로 인한 경고 : PHP주의 : 정의되지 않은 상수 o-라인 2의 /tmp/pcg-48388.php에서 'o'라고 가정합니다. / dev / null로 리디렉션 할 수 있습니다.
TimWolla

그 프로그램을 중단합니까?
ASCIIThenANSI

@ASCIIThenANSI 아니요,로 리디렉션되면 제대로 작동합니다 /dev/null.
TimWolla

그런 다음 프로그램이 계속 제대로 작동하고 리디렉션되는 한 계속 사용할 수 있습니다 /dev/null.
ASCIIThenANSI

1

파이썬 2, 536 509 448 441 바이트

통해 전화 a(); 움직임은 형식 piece,destination(즉, 1,4) 으로 입력되어야한다 . Ctrl-C로 종료하십시오. 더 많은 골프 잠재력을 볼 수 있다면 나는 모두 귀입니다.

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 바이트

SpecBAS 는 에뮬레이터 외부에서 실행할 수있는 업데이트 된 Sinclair / ZX BASIC 버전입니다. (아직 해석 됨).

새로운 기능 중 일부를 사용하여 최대한 크기를 줄였습니다.

정규식 최대 선 (12 개) 세트는 인라인을 사용하여 "샌드위치"조각을 검색합니다 IF 라인 (18 개) 사용 INC의 특성 (보다는 말을 주위에 랩 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

출력 (출력 창에서 복사 할 수 없으므로 스크린 샷) 여기에 이미지 설명을 입력하십시오

여기에 이미지 설명을 입력하십시오


0

C #, 730 바이트

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

추가 개선이 가능하다고 생각합니다. 반면에, 나는 INVALID출력을 실행 종료로 해석 했기 때문에 다른 답변과 동등하게 그 문제를 해결해야 할 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.