หมากรุก - ค้นหาการเคลื่อนไหวทางกฎหมายทั้งหมด (ยกเว้นการโยนและการผ่าน)


19

เขียนรหัสที่สั้นที่สุดซึ่งคำนวณการเคลื่อนไหวที่เป็นไปได้ (ถูกกฎหมาย) ทั้งหมดของผู้เล่นปัจจุบันจากสตริง FEN ที่กำหนด สตริง FEN คืออะไร (วิกิพีเดีย)

  • รหัสที่สั้นที่สุดชนะภาษาไม่สำคัญ
  • ย้ายขาออกต้องปฏิบัติตามกฎระเบียบของการเคลื่อนไหวหมากรุก ยกเว้นการกิน , ขุนและการส่งเสริมการจำนำ
  • ละเว้นการตรวจสอบรุกฆาตและจนมุมคิงไม่สามารถจับสถานการณ์ได้เช่นกัน

คุณสามารถตั้งค่าเอาท์พุทที่แตกต่างกันตามที่คุณต้องการ (ตัวอย่างเช่น: A2-A4, A2A4, a2a4, a2->a4... )

กรณีทดสอบ:

# INPUT 1:

rnbqkbnr / pppppppp / 8/8/8/8 / PPPPPPPP / RNBQKBNR w KQkq - 0 1
# เอาท์พุท 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
# INPUT 2

7k / 8/8/8/8/8 / PP6 / Q1q4K กว้าง - - 0 1

# เอาท์พุท 2

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

นี่คือวิธีการที่บอร์ดทดสอบกรณีการป้อนข้อมูลมีลักษณะเช่น: i.stack.imgur.com/qlbH4.png
golffzz


1
@ugoren ฉันคิดว่า แต่การแจกแจงการเคลื่อนไหวที่เป็นไปได้ทั้งหมดอาจกำจัดทางลัดบางอย่าง ฉันไม่แน่ใจว่าทำไมไม่จำเป็นต้องใช้คนเดิน: ส่วนหนึ่งของจุด FEN คือมันมีข้อมูลเพียงพอที่จะทำให้คนเดินผ่านเป็นไปได้
Peter Taylor

@ PeterTaylor ฉันเขียนว่าเพียงเพื่อลดการทำงาน ฉันสงสัยว่าทำไมไม่มีใครสนใจกอล์ฟนี้ :)
golffzz

1
@ golffzz ไม่ควรป้อนกรณีทดสอบของคุณ 2 เป็น 7k / 8/8/8/8/8 / PP6 / Q1q4K w - - 0 1 แทน 6pk / 6pp / 8/8/8/8 / p7 / PP4pp / Q2p2pK w - - 0 1 (ซึ่งเหนือสิ่งอื่นใดดูเหมือนว่าจะมีเบี้ยในท้ายที่สุด)?
Penguino

คำตอบ:


8

C - 391 ไบต์

รับอินพุตเป็นอาร์กิวเมนต์บรรทัดรับคำสั่งและพิมพ์ไปยัง stdout พร้อมกับกำลังสองที่มีเลเบลจาก 0 ถึง 63

ตกลงฉันมีเวลาสองสามนาทีดังนั้นฉันจึงพยายามลบบิตทั้งหมดที่เกี่ยวข้องกับการตรวจจับการตรวจสอบ ฉันคิดว่าตอนนี้มันไม่ได้มีประสิทธิภาพมาก แต่ ...

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

รุ่นตรวจจับ 478 ไบต์

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

นี่เป็นสิ่งที่น่าอัศจรรย์ แต่ไม่ตรงกับคำถาม: "เพิกเฉยตรวจสอบรุกฆาตและจนมุมกษัตริย์ไม่สามารถจับสถานการณ์ได้เช่นกัน"
edc65

@ edc65 ฉันไม่เห็นด้วยกับการตีความคำแนะนำที่ไม่ต่อเนื่องเหล่านี้ของคุณ มันบอกว่า "การเคลื่อนย้ายเอาท์พุทจะต้องปฏิบัติตามกฎการเคลื่อนที่ของหมากรุกยกเว้นการส่งเสริมการขว้างการขว้างและการจำนำ" การย้ายเข้าสู่การตรวจสอบจะไม่ปรากฏในรายการตัวหนาของกฎที่จะไม่สนใจ ฉันใช้สัญลักษณ์แสดงหัวข้อย่อยที่สามเป็นบันทึกที่คุณไม่จำเป็นต้องตรวจสอบสถานการณ์เหล่านี้และสะท้อนให้เห็นในทางใดทางหนึ่งในผลลัพธ์ (เช่นการประชุมการเขียน '+' หลังจากการตรวจสอบ) นอกจากนี้กรณีทดสอบที่สอง 2 นั้นถูกต้องตามที่เขียนไว้ตั้งแต่แรกให้ละเว้นการส่งเสริมการจำนำตามที่ระบุ (แต่ไม่ได้ให้ข้อมูลเชิงลึกเกี่ยวกับการตรวจสอบ)
feersum

กรณีทดสอบที่สอง (อินพุต) ไม่ถูกต้องโดยมีจำนำสีดำอยู่ในอันดับที่ 8 และแตกต่างจากภาพที่โพสต์เป็นความคิดเห็นโดย OP ( also here is how test case input boards look like) เมื่อกำหนดตำแหน่งในภาพแล้วผลลัพธ์ของเคสทดสอบต้นฉบับนั้นถูกต้องตามกฎ
edc65

2
โอ้เยี่ยมมากสเป็คที่แท้จริงอยู่ในความคิดเห็น? เอ่อคำถามที่น่าสงสาร
feersum

1
ผู้ชนะที่ชัดเจน
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

Python 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)

เยื้องสองช่องว่างคือแท็บถ่านซึ่งจะช่วยประหยัด 5 ไบต์

มันเกิดขึ้นกับฉันว่าคุณมีโอกาสที่จะประเมินการเคลื่อนไหวที่เหมาะสมในระดับที่เหมาะสมและเก็บไว้ไม่เกิน 1024 ไบต์ :) ฉันเริ่มดูคำถามอื่น ๆแต่ดูเหมือนจะไม่เป็นคำถามเกี่ยวกับเครื่องมือหมากรุก codegolf ...


2
ทำได้ดีมากสำหรับการกู้คืนคำถามนี้! (ฉันคิดว่าฉันอาจใส่ความโปรดปรานลงไปเพื่อดูว่าเกิดอะไรขึ้น) คำตอบของคุณดูดี แต่มันหายไปB1C3และH2H3ในตัวอย่างแรกที่แสดงในคำถาม
ossifrage คลื่นไส้

ขอโทษนะH2H3ฉันหมายถึงG1H3- อัศวินขาวของคุณเลี้ยวซ้ายเท่านั้น
ossifrage คลื่นไส้

มันจะต้องรอจนกว่าฉันจะอยู่บนพีซี แต่นี่เป็นข้อผิดพลาดที่ง่ายและฉันสามารถเห็นวิธีมากมายในการย่อให้สั้นเกินไป หวังว่าจะมีรายการอื่น ๆ
จะ

@squeamishossifrage แก้ไขแล้ว :)
จะ

1

Python 638 637 (482?) ไบต์

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 ")

หมายเหตุ: หลังจากdef O(y):มีการขึ้นบรรทัดใหม่และแท็บถ่านก่อนif

หมายเหตุ: โดยใช้โมดูล zlib เป็นไปได้ที่จะได้รับรหัสแหล่ง Python ที่ถูกต้องของ 482 ไบต์โดยเพียงแค่บีบอัดแหล่งที่มาจริง:

#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

แก้ไขข้อผิดพลาดที่น่ารังเกียจในการเคลื่อนย้ายของอัศวิน การทำงานหลายอย่างเพื่อให้ไบต์นับเหมือนกัน

(ไม่นับการเว้นวรรคนำและบรรทัดใหม่ที่เก็บไว้เพื่อให้สามารถอ่านได้)

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

หัก Golfed

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
)

ทดสอบในคอนโซล FireFox / FireBug

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

เอาท์พุต

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

1

JAVA 631 599 594

แก้ไขข้อผิดพลาดในรุ่น 599- ไบต์ (ขอบคุณแจ็คที่ชี้ให้เห็น!) และทำให้รหัสสั้นลงเหลือ 594- ไบต์

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

รวบรวม: javac F.java
เรียกใช้: java F 6pk/6pp/8/8/8/p7/PP4pp/Q2p2pK w - - 0 1
เอาท์พุท:B2B3 B2B4 B2A3 A1B1 A1C1 A1D1 H1H2 H1G1 H1G2


สำหรับ3Q4/p4r1k/P4pp1/4P3/5n2/3P4/4BbbP/RN3KN1 w - - 0 0ฉันไม่เห็นการเคลื่อนไหวF1F2หรือF1G2เป็นกษัตริย์สามารถที่จะจับ?
แจ็ค

ขอบคุณที่ชี้นำสิ่งนี้ คุณพูดถูก รุ่นที่เผยแพร่นี้ได้รับการปรับปรุงให้ดีที่สุด :(
Bob Genom

ดังนั้นฉันต้องถอยกลับไปใช้ทางออกยาว 631 ไบต์ของฉัน
Bob Genom

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.