stdin에 보드가 주어지면 유효한 체스 움직임을하십시오


11

이 프로그램은 흰색으로 재생됩니다.

stdin 예제 :

8 ║♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟ … ♟ ♟ ♟
6 ║… … … … … … … …
5 ║… … … … ♟ … … …
4 ║… … … … … … … …
3 ║… … ♘ … … … … …
2 ║♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
1 ║♖ … ♗ ♕ ♔ ♗ ♘ ♖
——╚═══════════════
—— a b c d e f g h

표준 출력 예 :

8 ║♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟ … ♟ ♟ ♟
6 ║… … … … … … … …
5 ║… … … … ♟ … … …
4 ║… … … … ♙ … … …
3 ║… … ♘ … … … … …
2 ║♙ ♙ ♙ ♙ … ♙ ♙ ♙
1 ║♖ … ♗ ♕ ♔ ♗ ♘ ♖
——╚═══════════════
—— a b c d e f g h

유효한 움직임은 괜찮습니다. "En passant"와 castling은 무시됩니다. 유효한 이동이 없으면 오류 메시지를 표시하거나 아무 것도 인쇄하지 않아도됩니다.

가장 많은 표를 얻은 답이 이깁니다.


언어의 내장 기능이 실패하여 발생하는 표준 오류 메시지를 의미합니다. 그래도 괜찮습니까? -이 프로그램이 할 수있는 필수가 어떤 법적 조치를? 아마도 캐스터 링과 폰 스페셜 동작은 약간의 보너스로 선택해야합니까?
차례에 중단는 counterclockwis

2
@leftaroundabout : 성을 할 수있을 때마다 대신 루크를 움직일 수 있으므로 적어도 그 논리를 건너 뛸 수 있습니다.
hammar

2
... 그리고 좀 더 생각해 보면, "통행 성있는"행동은 이전의 움직임에 대한 정보를 필요로합니다. 이전 움직임은 조각의 위치에서만 추론 할 수 없기 때문에 그것을 떨어 뜨리는 것이 안전 할 것 같습니다. 그러나 이중 첫 번째 이동이 가능한지 여부는 폰의 순위에서 유추 할 수 있으므로 포함시킬 수 있습니다.
hammar

@ hammar : 당신이 맞아, 나는 그것에 대해 생각하지 않았다. 한 번의 경우를 제외하고 는 이중 이동도 중요하지 않습니다 . 두 단계를 진행할 수 있으면 한 단계도 진행할 수 있으므로 확인시에만 중요하게되고 이중 이동은 왕을 덮는 유일한 이동입니다. 또한, 경우에도 당신이 모든 움직임을 사용할 수 있도록 할 필요가 없습니다, 당신은 여전히 가능성과 그 검은 깡통 대답을 고려해야합니다.
시계 반대 방향으로 돌리지

9
사직은 합법적 인 행동으로 간주됩니까? :)
gnibbler

답변:


16

나는 공감 율에 대해 불평하지 않지만 공정하게 말하면 ... 여기의 해결책은 실제로 그렇게 위대한 것은 아닙니다. 유니 코드 지원이 부족한 것 외에도 Ugoren이 더 좋습니다. 지금 만이 질문에 부딪 치면 투표하기 전에 모든 답변을 확인하십시오!
어쨌든.

하스켈, 893 888 904 952 (캐스팅 제외)

862 (폰을 두 번 움직이지 않고)

(이것이 코드 골프인지는 지정하지 않았지만 나에게 꼭 필요한 것 같습니다)

χ=w⋈b;w="♙♢♤♔♕♖♗♘";b="♟♦♠♚♛♜♝♞"
μ=t⤀ζ++((\(x,y)->(x,-y))⤀)⤀μ;q c|((_,m):_)<-((==c).fst)☂(χ⋎μ)=m
t(x:y:l)=(d x,d y):t l;t _=[];d c=fromEnum c-78
ζ=["NM","NL","MMOM","MMMNMONMNOOMONOO",σ⋈δ,σ,δ,"MLOLPMPOOPMPLOLM"]
σ=l>>=(\c->'N':c:c:"N");δ=[l⋎l,reverse l⋎l]>>=(>>=(\(l,r)->[l,r]))
l="GHIJKLMOPQRSTU"
α c|c∊"♢♤"='♙'|c∊"♦♠"='♟'|c∊χ=c;π('♙':_)=6;π _=1
(⋎)=zip;(⤀)=map;(∊)=elem;(✄)=splitAt;(☂)=filter;(⋈)=(++)
φ r@(x,y)p a
 |x>7=φ(0,y+1)p a
 |y>7=[]
 |c<-a✠r=(c⌥r)p a y⋈φ(x+1,y)p a
(c⌥r)p a y
 |c==p!!0=(a☈r)c χ++const(y==π p)☂(a☈r)(p!!1)χ++(a☈r)(p!!2)('…':w)
 |c∊p=(a☈r)c χ
 |True=[]
a✠(x,y)=a!!y!!(x*2);o(x,y)=x>=0&&x<8&&y>=0&&y<8
(n➴a)(x,y)|(u,m:d)<-y✄a,(l,_:r)<-(x*2)✄m=u⋈(l⋈(n:r):d)
(a☈r@(x,y))c b=(α c➴('…'➴a)r)⤀((\r->o r&&not((a✠r)∊b))☂((\(ξ,υ)->(x+ξ,y+υ))⤀q c))
main=interact$unlines.uncurry((⋈).zipWith((⋈).(:" ║"))['8','7'..]
 .head.((all(any('♔'∊)).φ(0,0)b)☂).φ(0,0)w.(drop 3⤀)).(8✄).lines

GHC를 설치 했으면 (예 : Haskell 플랫폼의 일부로 )

$ runhaskell def0.hs < examplechessboard.txt
8 ║♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟ … ♟ ♟ ♟
6 ║… … … … … … … …
5 ║… ♘ … … ♟ … … …
4 ║… … … … … … … …
3 ║… … … … … … … …
2 ║♙ ♙ ♙ ♙ ♙ ♙ ♙ ♙
1 ║♖ … ♗ ♕ ♔ ♗ ♘ ♖
——╚═══════════════
—— a b c d e f g h

지금 이것은 미쳤다 :) 나는 그것을 확인할 것이다 :)
Hristo Hristov

이 훌륭함을 테스트하는 방법에 대한 아이디어가 있습니까? Ideone.com는 그것을 처리 할 수 ​​없습니다 ...
Hristo Hristov

@HristoHristov : Ideone에서 작동하지 않는 것이 이상합니다. ASCII가 아닌 문자와 관련이있을 수 있습니다.
차례에 중단는 counterclockwis

네, 이것이 이데온의 문제입니다
Hristo Hristov

14
축하합니다. Haskell을 APL처럼 보이게 만들었습니다. :-)
Ilmari Karonen

11

C, 734 672 640 자

제거 가능한 공백없이 문자를 계산합니다.
내가 사용한 파일 형식은 요청 된 형식이 아니라 단순화 된 ASCII입니다.
유니 코드 문자 지원을 추가해야하는데 약간의 비용이 듭니다.

char*r=" kpnbrq  KPNBRQ $ ,&)$wxy()879()8(6:GI(",B[256],*b=B,i;
e(x,d,m,V,c,r,n,p){
    for(r=0,p=b[x];m/++r;){
        n=x+d*r;
        if(p==2+8*(d<0)||n&136||!(b[n]?r=8,8^p^b[n]^8&&c&65^64:c&65^65)
            ? r=m,0
            : V?v(n,x):b[n]==1)
            return b[x]=0,b[n]=p%8-2||n/16%7?p:p+4;
    }
    return d>0&&e(x,-d,m,V,c);
}
d(x,v,m,i)char*m;{
    return(i=*m-40)?e(x,i%64,b[x]%8-2?b[x]&4?7:1:(x/16-1)%5|i%2?1:2,v,i)||d(x,v,m+1):0;
}
v(t,f){
    bcopy(B,b+=128,128);
    b[t]=b[f];b[f]=0;
    i=a(1,63);
    b=B;
    return!i;
}
a(c,n){
    return b[i=n*2-n%8]&&b[i]/8==c&&d(i,!c,r+r[b[i]%8+15]-10)||n--&&a(c,n);
}
main(){
    for(;gets(b);b+=8)for(;*b;b++)*b=strchr(r,*b)-r;b=B;
    for(i=64*!a(0,63);i<64;i++%8-7||puts(""))putchar(r[b[i*2-i%8]]);
}

입 / 출력 파일 형식 :
정확히 8 자 정확히 8 줄이어야합니다. pnbrqk흰색 조각, PNBRQK검은 조각, 공백에 사용됩니다.

RNBQKBNR
PPPP PPP

 n  P


pppppppp
r bqkbnr

논리는 매우 간단합니다.
각 흰색 조각을 움직일 때마다 검은 색 조각을 움직일 수 있습니다.
흰색 움직임이 흰색 움직임을 포착하지 않으면 흰색 움직임이 유효합니다.

이 보드는 char[256]16x16 매트릭스로 취급되며 왼쪽 상단 8x8 만 사용됩니다. 위치 및 이동 벡터는 8 비트 정수 ( x:4,y:4) 로 유지됩니다 . 여분의 비트를 사용 new_pos = old_pos + steps*direction하면 보드 가장자리를 쉽게 감지 하여 간단한 산술 ( )을 사용할 수 있습니다 ( &0x88매직). r[]세 가지를 인코딩합니다.

  1. 처음 15 바이트는 내부 조각 코드 (K = 1, P = 2, N = 3, B = 4, R = 5, Q = 6)를 문자로 매핑합니다.
  2. 다음 6 바이트는 내부 조각 코드를 마지막 부분의 오프셋에 매핑합니다 (K와 Q는 동일하고 B는 꼬리 임).
  3. 마지막 16 바이트는 모든 조각의 움직임을 다음과 같이 인코딩합니다 '('+vector.

기능 :

  1. main보드를 읽고, 문자를 내부 코드로 변환하고, a흰색 움직임을 찾기 위해 호출 하고, 보드를 인쇄합니다.
  2. a재귀 적으로 64 사각형을 반복합니다. 올바른 색상 (매개 변수 c) 의 각 조각에 대해 조각의 이동 규칙을 찾아 호출합니다 d.
  3. d인코딩 된 이동 규칙을 반복적으로 반복합니다.이 규칙 e은 각 벡터를 호출하는 벡터 목록입니다 . 이는 범 e원래 위치 벡터 및 제한 범위 (제 랭크 졸위한 B, 상기 2 개의 7, 1, 그렇지 않은 경우).
  4. e벡터를 따라 모든 움직임을 테스트합니다. 이동이 가능한 경우 (즉, 폰이 보드 내에서 앞으로 이동하고, 막히지 않고, 폰 캡처 대각선으로), 두 가지 중 하나를 확인합니다. 흰색 이동의 v경우 이동을 확인하기 위해 실행 됩니다. 검은 색 움직임의 경우 흰색 왕이 붙잡 혔는지 확인합니다. true 인 경우 이동이 보드에서 재생됩니다.
  5. v하얀 움직임을 확인합니다. 보드를 옆으로 복사하고 테스트를 위해 이동을 실행 한 다음 a다시 호출 하여 검은 색 이동을 찾습니다.

마지막으로, 가능한 이동에 대한 적절한 압축 인코딩 솔루션 ! 그리고 아주 빠릅니다. 유니 코드 래퍼를 추가 할 수 있지만 여전히 내 코드보다 짧을 것이라고 생각하지 않습니까?
반 시계 회전을 중단

@ leftaroundabout, 할 수 있다고 생각합니다. 주요 문제는 유니 코드를 볼 수없는 Linux 명령 줄에서 작업 중이므로 디버깅하는 것이 성가신 것입니다. 또한 약 40 바이트를 더 절약하는 버전이 있습니다 (곧 업데이트 예정). 작업 할 문자가 많이 있습니다.
ugoren

@ugoren : 현대식 리눅스 배포판이 UTF-8을 즉시 지원합니까?
han

@han, Windows에서 일하고 SSH로 Linux에 연결하는데 유니 코드가 작동하지 않습니다. 파일에 쓰고 Windows에서 열 수 있지만 더 이상 흥미롭지 않습니다.
ugoren

이것이 gcc로 컴파일됩니까? MinGW와 함께 Windows 용 Geany를 사용하고 있으며 많은 오류와 경고로 컴파일되지만 빌드 / 실행되지는 않습니다. . :( 텍스트 + 0x2d8) :`bcopy 'collect2에 정의되지 않은 참조 : 신분증 1 개 종료 상태를 반환
RPD를

5

파이썬 2.6, 886 - (1425 개) 문자

내 초기 버전 (개정판)은 886 자로 나왔지만 사양을 완전히 만족시키지 못했습니다 (체크 메이트를 피하기 위해 검사하지 않았습니다. 검은 조각의 가능한 움직임도 고려하지 않았습니다).

이제는 그렇습니다 (원본에서 몇 가지 버그를 수정했습니다). 아아, 이것은 문자의 비용으로 제공됩니다 : 1425 현재는 개선의 여지가 거의 없습니다. 이 버전은 이전 사례보다 에지 사례를 처리하는 데 훨씬 더 견고해야합니다.

#-*-coding:utf8-*-
import sys;e=enumerate
B,W=["♟","♜","♞","♝","♛","♚"],["♙","♖","♘","♗","♕","♔"]
R={"♙":[11,42],"♖":[28],"♘":[31],"♗":[8],"♕":[8,28],"♔":[1,21]}
def F(w):return sum([[(i,j)for j,p in e(o)if p==w]for i,o in e(Z)],[])
def G(x,y):
 P=Z[x][y];D=P in W;L=[]
 for o in R[P]if D else R[unichr(ord(P.decode('utf8'))-6).encode('utf8')]:
  r,k="%02d"%o        
  for g,h in[[(-1,-1),(1,1),(-1,1),(1,-1)],[[(1,-1),(1,1)],[(-1,-1),(-1,1)]][D],[(-1,0),(1,0),(0,-1),(0,1)],[(-2,-1),(-2,1),(-1,-2),(-1,2),(1,-2),(1,2),(2,-1),(2,1)],[(-1,0)]][int(r)]:
   J=0
   for i in range(int(k)):
    T=x+(i+1)*g;U=y+(i+1)*h
    if T<0 or T>7 or U<0 or U>7:break
    M=Z[T][U]
    if not J:L.append((T,U,P,M))
    else:break
    if r in"02"and(M in W+B):
     J=1
     if not((D and M in B)or(not D and M in W)):L.pop()
    elif(r=="1"and not((D and M in B)or(not D and M in W)))or(r=="4"and((i==1 and x!=6)or M!="…")):L.pop()
 return L  
Z=[[y for y in l[5:].split()]for l in sys.stdin.readlines()[:-2]]
Q=[]
for p in R:
 for i,j in F(p):
  for M,L,c,_ in G(i,j):
   O=Z[M][L];Z[i][j]="…";Z[M][L]=c;E=[];map(E.extend,map(F,B))
   if not any(any(1 for _,_,_,I in G(v,h)if I==["♔","♚"][c in B])for v,h in E):Q.append((i,j,M,L,c))
   Z[i][j]=c;Z[M][L]=O
(x,y,X,Y,p)=Q[0];Z[x][y]="…";Z[X][Y]=p
for i,h in e(Z):print`8-i`+' ║'+' '.join(h)
print"——╚"+"═"*16+"\n—— a b c d e f g h"

입력 및 출력 예 :

# 입력

8 ║♜ ♞ ♝… ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟… ♟ ♟ ♟
6 ║…………………
5 ║………… ♟………
4 ║……………… ♙ ♛
3 ║…………… ♙……
2 ║♙ ♙ ♙ ♙ ♙… ♙…
1 ║♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖
--- ╚ ================
—— abcdefgh
출력

8 ║♜ ♞ ♝… ♚ ♝ ♞ ♜
7 ║♟ ♟ ♟ ♟… ♟ ♟ ♟
6 ║…………………
5 ║………… ♟………
4 ║……………… ♙ ♛
3 ║…………… ♙ ♙…
2 ║♙ ♙ ♙ ♙ ♙………
1 ║♖ ♘ ♗ ♕ ♔ ♗ ♘ ♖
--- ╚ ==================
—— abcdefgh

886 바이트이지만 854 자입니다. (ASCII 이외의 많은 연산자 덕분에 프로그램에 1kB가 넘습니다!) — 아직 왕을 데려 가기위한 검사를 추가 할 예정입니까?
반 시계 회전을 중단

@ leftaroundabout : 나는 왕의 수표를 추가했습니다 (검은 색의 움직임을 설명하고 많은 문자를 추가합니다 ...). 글쎄,이 버전은 가장자리 케이스 주변에서 더 견고해야합니다 (테스트 한 범위 내에서).
ChristopheD
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.