Vụ nổ trên bàn cờ vua


14

Cờ nguyên tử là một biến thể (rất vui) của cờ vua, trong đó mọi lần bắt đều gây ra một "vụ nổ", phá hủy quân cờ bị bắt, quân cờ thực hiện việc bắt và tất cả các quân cờ trong bán kính 1 ô vuông. Mục tiêu của thử thách này không phải là chơi toàn bộ trò chơi cờ nguyên tử, mà chỉ đơn giản là mô phỏng những gì xảy ra khi một nước cờ nhất định được thực hiện.

Disclaimer: Không bao gồm hiệu ứng âm thanh nổ.

Đầu vào

Vị trí bảng sẽ được đưa ra trong Ký hiệu Forsyth-Edwards (thường được gọi là FEN), nhưng chỉ với trường đầu tiên. Ví dụ: đầu vào của:

rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR

đại diện cho vị trí bắt đầu:

Vị trí bắt đầu cờ vua.

Điều này phải được coi là một chuỗi hoặc tương đương với ngôn ngữ của bạn. Nó được đảm bảo là hợp lệ; ví dụ, bạn không cần phải quan tâm nếu có mười vị vua, hoặc nếu không có vị vua nào cả.

Bạn cũng sẽ được cung cấp di chuyển mà bạn sẽ mô phỏng, được thể hiện dưới dạng hai tên hình vuông: hình vuông mà phần được di chuyển là và hình vuông mà nó đang di chuyển. Ví dụ: di chuyển cầm đồ của nhà vua hai khoảng trống về phía trước trên hình trên sẽ được biểu diễn dưới dạng:

e2e4

Điều này cũng phải được thực hiện như một chuỗi. Việc di chuyển sẽ luôn có hiệu lực và bạn không cần phải hỗ trợ castling . Bạn cần phải hỗ trợ en passant , điều này sẽ được giải thích chi tiết hơn trong phần tiếp theo.

Đầu ra

Đầu ra của chương trình của bạn phải ở cùng một ký hiệu FEN một phần với đầu vào, với bước di chuyển được chỉ định (và bất kỳ phần nào phát nổ nếu cần thiết).

Các quy tắc chính xác cho vụ nổ là tổ chức khi một mảnh được chụp:

  • Loại bỏ mảnh đang được chụp (đây sẽ luôn là mảnh trên hình vuông thứ hai có tên trong đầu vào, ngoại trừ khi chụp là một en passant ).

  • Loại bỏ mảnh đang thực hiện việc chụp (đây sẽ luôn là mảnh trên hình vuông đầu tiên có tên trong đầu vào).

  • Xóa mọi phần đó là:

    • nằm trên một trong 8 ô vuông xung quanh một nơi diễn ra vụ bắt giữ (đối với người qua đường , đây là hình vuông mà con tốt bị bắt sẽ được bật lên, nếu nó không nổ).

    • không phải là một con tốt

Tổng quan nhanh về quy tắc en passant , đối với những người không quen: nếu một con tốt di chuyển hai khoảng trống từ thứ hạng bắt đầu của nó, và có một con tốt có thể bắt được nó nếu nó chỉ di chuyển một ô vuông về phía trước, dù sao nó cũng có thể bắt được nó, nhưng chỉ trên di chuyển tiếp theo. Chụp này được cho là được thực hiện " trong việc thông qua " (hoặc bằng tiếng Pháp: " en passant ").

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

Trong các bức ảnh, mũi tên màu xanh lá cây phản hồi lại việc di chuyển sắp được thực hiện và các vòng tròn màu xanh lá cây đại diện cho các mảnh bị nổ tung.

Đầu vào : rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR, g1f3
Đầu ra:rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R
Trường hợp kiểm tra 1.


Đầu vào : 3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK, f2g3
Đầu ra: 3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK
Trường hợp thử nghiệm 2.
(bị đánh cắp từ http://en.lichess.org/ocoSfS5I/white#36 )


Đầu vào : rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R, f3b7
Đầu ra: 3qk1nr/2p5/p2pp1pp/5p2/1bN5/2P1P2N/PP1P1PPP/R1B1KB1R
Trường hợp thử nghiệm 3.
(bị đánh cắp từ http://en.lichess.org/NCUnA6LV/white#14 )


Đầu vào : rnbqk2r/pp2p2p/2p3pb/3pP3/5P2/2N5/PPPP2P1/R1BQKB1R, e5d6
Đầu ra: rnbqk2r/pp2p2p/2p3pb/8/5P2/2N5/PPPP2P1/R1BQKB1R
Trường hợp thử nghiệm 4.
(bị đánh cắp từ http://en.lichess.org/AvgU4Skq/white#16 ; đây không phải là động thái thực sự, nhưng tôi không thể bận tâm khi tìm một trò chơi nguyên tử thực sự có người qua đường: P)


Đầu vào : 5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q, c6h1
Đầu ra: 5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2
Trường hợp thử nghiệm 5.
(bị đánh cắp từ http://en.lichess.org/l77efXEb/white#58 )

Chấm điểm

Đây là , vì vậy mã ngắn nhất tính bằng byte sẽ thắng.


Vì vậy, ... lấy một mảnh với vua của bạn là một ý tưởng tồi?
mbomb007

@ mbomb007 Bạn không được phép mang theo mảnh ghép với vua của bạn. : P
Doorknob

Tôi có thể nhầm, nhưng làm thế nào để chúng ta biết nếu bắt được người qua đường là có thể? Trong ví dụ của bạn, bước di chuyển cuối cùng được biểu thị bằng hình vuông màu xanh lá cây trống, do đó, người cầm đồ đen có thể bị bắt bởi người qua đường. Nhưng thông tin này không có trong các đầu vào mà chúng tôi được cung cấp, do đó có thể có cùng một bảng nhưng không thể bắt được en passant, vì bước cuối cùng không phải là hai bước tiến.
Gây tử vong vào

1
@Firthize " Việc di chuyển sẽ luôn có hiệu lực " - từ phần "Đầu vào".
Doorknob

Hoàn thành chương trình hay chức năng?
edc65

Câu trả lời:


5

JavaScript ( ES6 ) 305 310 321

Là một hàm có 2 tham số thực (và nhiều hơn nữa với các giá trị mặc định, được sử dụng như một cách nhanh chóng và bẩn thỉu để xác định người địa phương)

Kiểm tra chạy đoạn mã bên dưới (chỉ là EcmaScript 6, chỉ dành cho Firefox)

F=(g,m,b=[...g.replace(/\d/g,c=>'0'.repeat(c))],P=p=>p=='p'|p=='P',n=parseInt(m,32),
  s=n>>5&31,u=n>>15,x=b[y=u+62-(n>>10&31)*9])=>(
  b[b[y]=0,z=s+62-(n&31)*9]<1&!(s!=u&P(x))?b[z]=x:
  [-1,1,8,9,10,-8,-9,-10].map(i=>b[i+=z]>'/'&&!P(b[i])?b[i]=0:0,b[b[z]<1?z>y?z-9:z+9:z]=0),
  b.join('').replace(/0+/g,x=>x.length)
)

//TEST
out=x=>O.innerHTML+=x+'\n'

test=[
 ['rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR', 'g1f3'
  ,'rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R']
,['3kBb1r/pp5p/3p4/4pn2/P7/1P2P1pP/2rP1P2/R1B3RK', 'f2g3'
  ,'3kBb1r/pp5p/3p4/4pn2/P7/1P2P2P/2rP4/R1B3RK']  
,['rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R', 'f3b7'
  ,'3qk1nr/2p5/p2pp1pp/5p2/1bN5/2P1P2N/PP1P1PPP/R1B1KB1R']
,['rnbqk2r/pp2p2p/2p3pb/3pP3/5P2/2N5/PPPP2P1/R1BQKB1R', 'e5d6'
  ,'rnbqk2r/pp2p2p/2p3pb/8/5P2/2N5/PPPP2P1/R1BQKB1R']
,['5r2/2k5/p1B5/1pP1p3/1P4P1/3P4/P7/1K3R1q', 'c6h1'
  ,'5r2/2k5/p7/1pP1p3/1P4P1/3P4/P7/1K3R2']
]

test.forEach(t=>( 
  r=F(t[0],t[1]), 
  out('Test '+(r==t[2]?'Ok':'Fail!')+'  '+t[0]+' move '+t[1]
     +'\nResult   '+r+'\nExpected '+t[2]+'\n')))
<pre id=O></pre>

Ung dung

B=(b,m)=>{
  P=p=>p=='p'|p=='P'
  m=parseInt(m,32) 
  r=m&31 // arrival row
  s=(m/32&31)-10 // arrival column
  z=s+(8-r)*9 // arrival position
  t=m/32/32&31 // start row
  u=(m/32/32/32&31)-10 // start column
  y=u+(8-t)*9 // start position
  b=[...b.replace(/\d/g,c=>'0'.repeat(c))] // board to array, empty squares as 0
  x=b[y] // moving piece
  b[y]=0 
  C=s!=u&P(x) // pawn capture
  if (b[z]<1 && !C)
  {  // no capture
    b[z]=x
  }
  else
  {
    // capture and boom!
    if (b[z]<1) // arrival empty: en passant
      b[z>y?z-9:z+9]=0;
    else
      b[z]=0;
    // zero to nearest 8 squares
    [-1,1,8,9,10,-8,-9,-10].forEach(i=>b[i+=z]>'/'&&!P(b[i])?b[i]=0:0)
  }
  return b.join('').replace(/0+/g,x=>x.length)
}

1
Wow, nó trông đơn giản hơn nhiều so với giải pháp của tôi ... Làm tốt lắm!
cmxu

2

Java, ( 946 777 776 ký tự)

1 char cảm ơn @ edc65

Lưu ý: Chars đếm mà không có trường hợp kiểm tra đưa vào.

class E{public static void main(String[]a){String i=a[0];char[]n=a[1].toCharArray();int j,k,z,w,y,u=56-n[3];char q,p,e ='e';char[][]b=new char[8][8];String[]r=i.split("/");for(j=0;j<8;j++){z=0;for(k=0;k<r[j].length();k++){p=r[j].charAt(k);if(Character.isDigit(p)){for(int l=k+z;l<k+z+p-48;l++)b[j][l]=e;z+=p-49;}else b[j][k+z]=p;}}z=n[0]-97;w=56-n[1];y=n[2]-97;p=b[w][z];q=b[u][y];b[w][z]=e;if(q!=e||((p|32)=='p'&&(w-u<0?u-w:w-u)==1&&(z-y<0?y-z:z-y)==1)){if(q!=e)b[u][y]=e;else b[w][y]=e;for(j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){for(k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++)if((b[k][j]|32)!='p')b[k][j]=e;}}else b[u][y]=p;i="";for(j=0;j<8;j++){z=0;for(k=0;k<8;k++){if(b[j][k]==e)z++;else {if(z>0){i+=z;z=0;}i+=b[j][k];}}if(z>0)i+=z;i+=j!=7?"/":"";}System.out.print(i);}}

Tôi không chắc liệu giải pháp này có tối ưu hay không, nhưng tôi đang làm việc với nó nhiều hơn, mọi đề xuất đều được chào đón. Tôi cũng có thể nhận xét tất cả các mã nếu có ai muốn, nhưng tôi nghĩ rằng nó chủ yếu là tự giải thích, ngoại trừ việc liệt kê biến khó hiểu.

Giải trình

  • Giải nén chuỗi bảng thành ma trận char
  • Tính hiệu quả của việc di chuyển
  • Đóng gói lại bảng thành một chuỗi

Mở rộng

class ExplosionChess{
    public static void main(String[]a){
        String i=a[0];
        //"rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R";
        //"f3b7";
        char[]n=a[1].toCharArray();
        int j,k,z,w,y,u=56-n[3];
        char q,p,e ='e';
        char[][]b=new char[8][8];
        String[]r=i.split("/");
        for(j=0;j<8;j++){
            z=0;
            for(k=0;k<r[j].length();k++){
                p=r[j].charAt(k);
                if(Character.isDigit(p)){
                    for(int l=k+z;l<k+z+p-48;l++)
                        b[j][l]=e;
                    z+=p-49;
                }else 
                    b[j][k+z]=p;
            }
        }
        z=n[0]-97;
        w=56-n[1];
        y=n[2]-97;
        p=b[w][z];
        q=b[u][y];
        b[w][z]=e;
        if(q!=e||((p|32)=='p'&&(w-u<0?u-w:w-u)==1&&(z-y<0?y-z:z-y)==1)){
            if(q!=e)
                b[u][y]=e;
            else
                b[w][y]=e;
            for(j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){
                for(k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++)
                    if((b[k][j]|32)!='p')
                        b[k][j]=e;
            }
        }else 
            b[u][y]=p;
        i="";
        for(j=0;j<8;j++){
            z=0;
            for(k=0;k<8;k++){
                if(b[j][k]==e)
                    z++;
                else {
                    if(z>0){
                        i+=z;
                        z=0;
                    }
                    i+=b[j][k];
                }
            }
            if(z>0)
                i+=z;
            i+=j!=7?"/":"";
        }
        System.out.print(i);
    }
}

class E{public static void main(String[]a){String m,i="rnbqk1nr/1pp5/p2pp1pp/5p2/1bN5/2P1PQ1N/PP1P1PPP/R1B1KB1R";m="f3b7";char[]n=m.toCharArray();int z,w,y,u=56-n[3];z=n[0]-97;w=56-n[1];y=n[2]-97;char e='e';char[][]b=new char[8][8];String[]r=i.split("/");for(int j=0;j<8;j++){int o=0;for(int k=0;k<r[j].length();k++){char q=r[j].charAt(k);if(Character.isDigit(q)){for(int l=k+o;l<k+o+q-48;l++){b[j][l]=e;}o+=q-49;}else b[j][k+o]=q;}}char q,p=b[w][z];q=b[u][y];b[w][z]=e;if(q==e){if((p|32)=='p'&&(w-u<0?u-w:w-u)==1&&(z-y<0?y-z:z-y)==1){b[w][y]=e;for(int j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){for(int k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++){if((b[k][j]|32)!='p')b[k][j]=e;}}}else{b[u][y]=p;}}else{b[u][y]=e;for(int j=y-(y==0?0:1);j<y+(y==8?0:y==7?1:2);j++){for(int k=u-(u==0?0:1);k<u+(u==8?0:u==7?1:2);k++){if((b[k][j]|32)!='p')b[k][j]=e;}}}i="";for(int j=0;j<8;j++){int x=0;for(int k=0;k<8;k++){if(b[j][k]==e)x++;else{if(x>0){i+=x;x=0;}i+=b[j][k];}}if(x>0)i+=x;i+=j!=7?"/":"";}System.out.println(i);}}

String m,i="";m="";char[]n=m.toCharArray()-> String i=a[0];char[]n=a[1].toCharArray()ngắn hơn và do đó bạn nhận được các tham số từ bên ngoài ( dù sao bạn cũng nên )
edc65

À, được rồi, tôi sẽ thay đổi điều đó, cảm ơn!
cmxu
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.