Cờ vua - Tìm tất cả các nước đi hợp pháp (trừ castling và en passant)


19

Viết mã ngắn nhất tính toán tất cả các chuyển động có thể (hợp pháp) của người chơi hiện tại từ một chuỗi FEN nhất định. Chuỗi FEN là gì? (Wikipedia)

  • Mã ngắn nhất thắng, ngôn ngữ không thành vấn đề.
  • Di chuyển đầu ra phải tuân theo các quy tắc di chuyển cờ vua ngoại trừ en passant , castling, và khuyến mãi cầm đồ.
  • Bỏ qua kiểm tra, checkmate và bế tắc, vua cũng không thể bị bắt.

Bạn có thể thiết lập đầu ra khác nhau như bạn muốn (ví dụ: A2-A4, A2A4, a2a4, a2->a4...)

Các trường hợp thử nghiệm:

# VÀO 1:

rnbqkbnr / pppppppp / 8/8/8/8 / PPPPPPPP / RNBQKBNR w KQkq - 0 1
# ĐẦU RA 1

A2-A4, A2-A3, B2-B4, B2-B3, C2-C4, C2-C3, D2-D4, D2-D3, E2-E4, E2-E3,
F2-F4, F2-F3, G2-G4, G2-G3, H2-H4, H2-H3, B1-A3, B1-C3, G1-F3, G1-H3
# VÀO 2

7k / 8/8/8/8/8 / PP6 / Q1q4K w - - 0 1

# ĐẦU RA 2

A1-B1, A1-C1, A2-A3, A2-A4, B2-B3, B2-B4, H1-H2, H1-G1, H1-G2

đây cũng là cách các bảng nhập trường hợp thử nghiệm trông như thế nào: i.stack.imgur.com/qlbH4.png
golffzz


1
@ugoren, tôi đã xem xét điều đó, nhưng liệt kê tất cả các động thái có thể có khả năng loại bỏ một số phím tắt. Tuy nhiên, tôi không chắc chắn tại sao en passant không bắt buộc: một phần quan điểm của FEN là nó bao gồm đủ thông tin để làm cho en passant có thể.
Peter Taylor

@PeterTaylor Tôi viết rằng chỉ để giảm bớt công việc. Tôi tự hỏi tại sao không ai quan tâm đến môn đánh gôn này :)
golffzz

1
@golffzz không nên nhập trường hợp kiểm tra của bạn 2 là 7k / 8/8/8/8/8 / PP6 / Q1q4K w - - 0 1 thay vì 6pk / 6pp / 8/8/8 / p7 / PP4pp / Q2p2pK w - - 0 1 (trong số những thứ khác, dường như có những con tốt trên hàng ngũ cuối)?
Penguino

Câu trả lời:


8

C - 391 byte

Đưa đầu vào dưới dạng đối số dòng lệnh và in ra thiết bị xuất chuẩn với các ô vuông được dán nhãn từ 0 đến 63.

OK, tôi đã có một vài phút vì vậy tôi đã cố gắng xóa tất cả các bit liên quan đến việc phát hiện kiểm tra. Tôi nghĩ rằng bây giờ nó không hiệu quả lắm ...

O(x,y){return((x&7)-(y&7))/5;}
B[64],*b=B,J=32,M,L,x,*X,N;
main(int c,char**V){
for(;x=*V[1]++;c=J&2**V[2])
x>56?*b++=x:x>47?b+=x-48:0;
for(;b-->B;)
for(M=-1,N=*b%J^16,*V=strchr("bGInFJOQrAHkAGHIqAGHIpGHIx",*b|J);*b&&*b&J^c&&(M=M<0?*++*V%J:-M,**V<96);)
for(x=b-B,L=N?9^*b&8:1+(x/8==1+c/6);L--*!(O(x,x+M)|O(x>>3,x+M>>3));L=!*X|~*X&J^c&&N|(!*X^M&1&&M<0^!c)?printf("%d-%d ",b-B,x),L*!*X:0)
X=B+(x+=M);}

Phiên bản phát hiện kiểm tra 478 byte

O(x,y){return((x&7)-(y&7))/5;}
B[64],*b=B,c,I,J=32;
main(int C,char**V){
int*D,M,L,t,x,*X,N;
for(;b-B<64;C=c=J&2**V[2])
(t=*V[1]++)>56?*b++=t:t>47?b+=t-48:0;
for(D=b;D-->B;)
for(M=-1,N=*D%J^16,*V=strchr("bGInFJOQrAHkAGHIqAGHIpGHIx",*D|J);*D&&*D&J^C&&(M=M<0?*++*V%J:-M,**V<96);)
for(x=D-B,L=N?9^*D&8:1+(x/8==1+C/6);L--*!(O(x,x+M)|O(x>>3,x+M>>3));L=!*X|~*X&J^C&&N|(!*X^M&1&&M<0^!C)?c^C?I|=*X%J==11:(*X=*D,*D=I=0,main(C^J,V+1),*D=*X,I||printf("%d-%d ",D-B,x)),L*!(*X=t):0)
X=B+(x+=M),t=*X;}

Điều này thật tuyệt vời, nhưng không tương ứng với câu hỏi: "Bỏ qua kiểm tra, kiểm tra và bế tắc, vua cũng không thể bị bắt."
edc65

@ edc65 Tôi không đồng ý với cách giải thích của bạn về những hướng dẫn không phù hợp này. Nó nói "Di chuyển đầu ra phải tuân theo các quy tắc di chuyển của cờ vua ngoại trừ en passant, castling, và khuyến mãi cầm đồ." Di chuyển vào kiểm tra không xuất hiện trong danh sách các quy tắc được in đậm để bỏ qua. Tôi lấy điểm đầu dòng thứ ba làm một lưu ý rằng bạn không cần phải phát hiện các tình huống này và phản ánh chúng theo bất kỳ cách nào trong đầu ra (ví dụ: quy ước viết '+' sau khi kiểm tra). Ngoài ra, trường hợp thử nghiệm thứ hai 2 đúng như được viết ban đầu, được đưa ra một lần bỏ qua khuyến mãi cầm đồ theo quy định (nhưng không có cái nhìn sâu sắc về kiểm tra).
frageum

Trường hợp thử nghiệm thứ hai (đầu vào) không hợp lệ khi có một con tốt màu đen ở hạng 8 và khác với hình ảnh được đăng dưới dạng nhận xét của OP ( also here is how test case input boards look like). Với vị trí trong ảnh, đầu ra của trường hợp thử nghiệm ban đầu là chính xác theo quy tắc.
edc65

2
Oh tuyệt vời, thông số thực sự là trong các ý kiến? Ugh, thật là một câu hỏi nghèo.
frageum

1
Người chiến thắng rõ ràng
edc65

2

Java 1455

String q(String f){int[][]b=new int[8][8];int i=0,j=0,k,l,m,n,c;HashSet<String>h=new HashSet<String>();while((c=f.charAt(i))>32){if(c>48&c<57)j+=c-49;if(c==47)j--;if(c>56)b[j%8][j/8]=c;i++;j++;}boolean w=f.charAt(++i)>99;for(i=0;i<8;i++)for(j=0;j<8;j++)if((c=b[i][j])<91?w&c>0:!w){switch(c%32){case 14:for(k=0;k<8;k++){l=(k/4+1)*(k%2*2-1)+i;m=(2-k/4)*(k%4/2*2-1)+j;if(b(l,m)&&(w&b[l][m]%91<40|!w&b[l][m]<91))h.add(h(i,j,l,m));}break;case 11:for(k=0;k<8;k++){l=i+(k==4?1:k/3-1);m=j+(k==4?1:k%3-1);if(b(l,m)&&(w&b[l][m]%91<40|!w&b[l][m]<91))h.add(h(i,j,l,m));}break;case 17:for(k=0;k<8;k++){for(n=1;n<9;n++){l=i+n*(k==4?1:k/3-1);m=j+n*(k==4?1:k%3-1);if(b(l,m)){c=b[l][m];if(w&c%91<40|!w&c<91)h.add(h(i,j,l,m));if(c>0)break;}else break;}}break;case 2:for(k=0;k<4;k++){for(n=1;n<9;n++){l=i+n*(k/2*2-1);m=j+n*(k%2*2-1);if(b(l,m)){c=b[l][m];if(w&c%91<40|!w&c<91)h.add(h(i,j,l,m));if(c>0)break;}else break;}}break;case 18:for(k=0;k<4;k++){for(n=1;n<9;n++){l=i+n*(k/2*(k%2*2-1));m=j+n*((1-k/2)*(k%2*-2+1));if(b(l,m)){c=b[l][m];if(w&c%91<40|!w&c<91)h.add(h(i,j,l,m));if(c>0)break;}else break;}}break;default:m=w?-1:1;if(b[i][j+m]<1){h.add(h(i,j,i,j+m));if(b[i][j+2*m]<1&j==(w?6:1))h.add(h(i,j,i,j+2*m));}for(l=-1;i+l<8&i+l>=0&l<2;l+=2){c=b[i+l][j+m];if(c>0&(c<91?!w:w))h.add(h(i,j,i+l,j+m));}}}return h.toString();}boolean b(int l,int m){return m>=0&m<8&l>=0&l<8;}String h(int i,int j,int l,int m){return""+g(i)+(8-j)+g(l)+(8-m);}char g(int i){return(char)(i+65);}

2

Trăn 553 649 678

b,Q=raw_input(),range;R=Q(8);D="w"in b
for i in Q(9):b=b.replace(`i`,"_"*i)
if D:b=b.swapcase()
def X(h,v,c):
 h+=x;v+=y
 if c and h|v in R and"a">b[v*9+h]:print chr(65+x)+`8-y`+chr(65+h)+`8-v`;return"_"==b[v*9+h]
for y in R:
 for x in R:
  z=y*9+x;p=b[z];N=p=="n";j=[p in"qrk"]*4+[p in"qbk"]*4
  if"p"==p:j[D]=k=(1,-1)[D];X(1,k,b[z+10*k]<"_");X(-1,k,b[z+8*k]<"_")
  for i in Q(1,(2,(y==(1,6)[D])+2,8)["kp".find(p)]):
   for k in R:j[k]=X((0,0,-i,i,-i,i,-i,i)[k],(i,-i,0,0,-i,-i,i,i)[k],j[k])
  for v,h in((2,1),(1,2)):X(v,h,N);X(-v,-h,N);X(-v,h,N);X(v,-h,N)

Thụt lề hai không gian là tab char, giúp tiết kiệm 5 byte.

Tôi nhận thấy rằng bạn có thể khiến nó đánh giá các bước di chuyển hợp lý thành một đồng minh đàng hoàng và giữ nó dưới 1024 byte :) Tôi bắt đầu xem qua các câu hỏi khác , nhưng dường như không có câu hỏi nào về động cơ cờ vua ...


2
Làm tốt cho việc hồi sinh câu hỏi này! (Tôi nghĩ rằng tôi có thể đặt tiền thưởng cho nó chỉ để xem điều gì xảy ra.) Câu trả lời của bạn có vẻ tốt, nhưng nó bỏ lỡ B1C3H2H3trong ví dụ đầu tiên được hiển thị trong câu hỏi.
squossish ossifrage

Xin lỗi, không H2H3, ý tôi là G1H3- nói cách khác, các hiệp sĩ trắng của bạn chỉ rẽ trái.
squossish ossifrage

Nó sẽ phải đợi cho đến khi tôi ở trên máy tính, nhưng đây là một lỗi dễ dàng và tôi cũng có thể thấy rất nhiều cách để rút ngắn nó. Hy vọng có những mục khác.
Sẽ

@squeamishossifrage đã được sửa :)
Sẽ

1

Python 638 637 (482?) Byte

exec"""p=raw_input()
for x in"12345678":p=p.replace(x,"~"*int(x))
b=map(ord,"#"*21+p[:71].replace("/","##")+"#"*21)
d,e=-10,126
if not"w"in p:b,d=[x^32*(64<x<e)for x in b],10
B=[-9,9,-11,11]
R=[-1,1,-d,d]
Q=B+R
c=Zx:chr(96+x%10)+chr(58-x/10)
for x,p in enumerate(b):
 def O(y):
    if 111<b[y]:print c(x)+c(y)
 s=ZL:[O(x+X)for X in L];m=ZL,z=x:L&(O(z+L[0]),m(L,z+L[0])if e==b[z+L[0]]else m(L[1:]))
 if p==80:e==b[x+d]&(O(x+d)or e==b[x+d*2]&35==b[x-d*2]&O(x+d*2)),111<b[x+d-1]<e&O(x+d-1),111<b[x+d+1]<e&O(x+d+1)
 p==75&s(Q),p==78&s([-12,12,-8,8,-21,21,-19,19]),p==82&m(R),p==66&m(B),p==81&m(Q)""".replace("Z","lambda ").replace("&"," and ")

Lưu ý: sau khi def O(y):có dòng mới và tab char trướcif

Lưu ý: bằng cách sử dụng mô-đun zlib, có thể lấy mã nguồn Python hợp lệ là 482 byte bằng cách nén nguồn thực:

#encoding=koi8-r
import zlib
exec zlib.decompress("x°MRKkЦ0>╞~┘Pы Eё╜Е4▌Ц█.9Br*1зБ┤B╠#°■╙=Лoъ╠M⌡│╬г0█\\pcл⌡╝x9╣ЧМф9^:Х╘e:·=м⌠Eй2oЭ╞нЫsQ9─ЩeсS{ЦAR ╕ПЭруюь4жрГыBшОhЖхпy`B▌╬ 58ёt:NхИHшк█╫ЁSK}VBmРПgOyР╢\n+'╬Z║╔▒╣иу√═╢╜-ы#G╙├з▓²Yк=╘л!dуkг≈┴?u$dOФ╘\n▐HфАюВ9]Шж╦╝╦9^┼▄пзИ√ Э│mi╜WeЧa3ъА╗╢бae┘.║WsьdЫ√Ы<ТВэГзьъ
ЙПiB╤≥П-Ъ■⌡<╡▌Б┬1╚3╕лGjщЫЙ(з╧н,>$Eш⌠FыdmШ<x,Р╔Mc;≥м╒2DLc!`Л≥рvЕFCИЪtyв%Н║╞╤≤O╝|'═┤)B|н*┘T╛▐рKпK;╔Я╓АШ&  бУ╗j└;│И╬Ж╝Щ\\4e]P&НРeZ╢5┼ДГt╚У")

1

JavaScript (E6) 481 492 550

Chỉnh sửa Đã sửa một lỗi khó chịu trong hiệp sĩ di chuyển. Rất nhiều công việc để giữ cho số byte giống nhau.

(Không tính không gian hàng đầu và dòng mới được giữ cho dễ đọc)

B=f=>
  [for(c of(o=b='',f=f.split(w=' '))[0])b+=-c?w.repeat(c):c<'0'?z=10:c]+
  [...b].map((c,p)=>
    (K=d=>(d=b[p+d])==w?0:d>'a'?m:d>'A'?-m:9)(0)-1||(
      t='pPkKnNrRQqBb'.search(c),
      O=d=>K(d)<1?o+=w+P(p)+P(p+d):0,
      S=(d,s=0)=>O(d*++s)&&!K(d*s)&&S(d,s),
      //o+='\n'+P(p)+' '+c, // Uncomment to display pieces list
      t<2?[for(i of[~(s=t<1?z:-z),1-s])~K(i)||O(i)]+!K(s)&&O(s)&&(p/z|0)==t*5+1&!K(s+=s)&&O(s)
      :t<6?[for(i of t<4?[1,9,z,11]:[12,8,21,19])O(i)+O(-i)]
      :[for(i of[t>7&&9,t>7&&11,t<z,t<z&&z])S(i)+S(-i)]
    )
  ,m=f[1]<'w'?1:-1,
  //console.log(','+([...b]+',').replace(/1,0/g,'\n')), // Uncomment to display chessboard
  P=p=>'ABCDEFGH'[p%z]+(9+~p/z|0))&&o

Ít chơi gôn

B=f=>(
  o=b='',[for(c of f)b+=-c?'.'.repeat(c):c],
  m=(w=b[72]=='w')?1:2,n=3-m,
  t=0,
  P=p=>'ABCDEFGH'[p%9]+(9+~p/9|0),
  b=b.slice(0,71),
  // console.log(b.replace(/\//g,'\n')), // Uncomment to display chessboard

  [...b].map((c,p)=>{
    r=p/9|0
    K=k=>(k=b[k])=='.'?0:k>'a'?m:k>'A'?n:9
    J=d=>K(p+d)<2,
    O=d=>J(d)?o+=' '+P(p)+P(p+d):0,
    S=(s,d)=>O(d*++s)&&!K(p+d*s)?S(s,d):0;

    if(K(p)==2){
      // o+='\n'+P(p)+ ' '+c; // Uncomment to display pieces list
      if (c=='P')
      {
        (f=!K(p-9))&&O(-9),
        f&r==6&&!K(p-18)&&O(-18),
        [for(i of[10,8])K(p-i)==1&&O(-i)]
      }
      else if (c=='p')
      {
        (f=!K(p+9))&&O(+9),
        f&r==1&&!K(p+18)&&O(+18),
        [for(i of[10,8])K(p+i)==1&&O(+i)]
      }
      else if (c=='K' |c=='k')
        [for(i of[1,8,9,10])O(i)+O(-i)]
      else if (c=='N' | c=='n')
        [for(i of[11,7,19,17])O(i)+O(-i)]
      else 
      {
        if (c!='r' & c!='R')
          [for(i of[10,8])S(0,i)+S(0,-i)]
        if (c!='b' & c!='B')
          [for(i of[9,1])S(0,i)+S(0,-i)]
      }
    }     
  }),
  o
)

Thử nghiệm trong bảng điều khiển FireFox / FireBug

B("7k/8/8/8/8/1P6/P7/Q1q4K w - - 0 1")

Đầu ra

B3B4 A2A3 A2A4 A1B2 A1C3 A1D4 A1E5 A1F6 A1G7 A1H8 A1B1 A1C1 H1G1 H1H2 H1G2

1

JAVA 631 599 594

Đã sửa lỗi trong phiên bản 599 byte (cảm ơn Jack vì đã chỉ ra điều này!) Và rút ngắn mã thành 594 byte.

class F{
public static void main(String[]A){int p=0,i=8,u,v,d,z[]={0,1,-1,2,1,0,1};String f=A[0],S[]="p,n,rqk,bqk,aA,PNBRQK,aAPNBRQK".split(",");
for(;i>0;)f=f.replace(""+i,"a"+(--i==0?"":i));
for(;p<448;p++)
for(int k=p%7,w=A[1].equals("w")?32:0,c=f.charAt(p/7%8+p/56*9),a=z[k],b=k==4?2:1,q=0;S[(k/2-1|k-1)/2].indexOf(c+w)>=0&&q++<(k<3?1:4);i=a,a=b,b=-i){
for(i=1,d=97;d==97&&((u=p/7%8+i*a)|(v=p/56+i*b*(1-w/16)))>=0&&(u|v)<8&&i<(k>4?(c=='K'||c=='k')?2:9:(k<1&&p/56==w/6+1?3:2))&&S[61/(61^(k*k-2))+5].indexOf((d=f.charAt(u+9*v))-w)>=0;i++)System.out.printf("%c%d%c%d ",65+p/7%8,8-p/56,65+u,8-v);}}}

Biên dịch: javac F.java
Chạy: java F 6pk/6pp/8/8/8/p7/PP4pp/Q2p2pK w - - 0 1
Đầu ra:B2B3 B2B4 B2A3 A1B1 A1C1 A1D1 H1H2 H1G1 H1G2


3Q4/p4r1k/P4pp1/4P3/5n2/3P4/4BbbP/RN3KN1 w - - 0 0tôi không thấy di chuyển F1F2hay F1G2nhà vua có thể nắm bắt?
Jack

Cảm ơn bạn đã chỉ ra điều này. Bạn đúng rồi. Phiên bản đã xuất bản này được tối ưu hóa quá mức :(
Bob Genom

Vì vậy, tôi phải quay trở lại giải pháp dài 631 byte của mình.
Bob Genom
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.