Cờ vua kết thúc: Trắng thành Mate In One


19

Đưa ra một lưới các chữ cái 8x8 đại diện cho trạng thái hiện tại của một ván cờ, nhiệm vụ của chương trình của bạn là tìm một nước đi tiếp theo cho màu trắng dẫn đến kết quả là người chơi (câu trả lời sẽ luôn được giao phối trong một lần di chuyển).

Đầu vào

Đầu vào sẽ ở trên STDIN - mỗi dòng gồm 8 ký tự. Ý nghĩa của mỗi nhân vật như sau:

K/k - king
Q/q - queen
B/b - bishop
N/n - knight
R/r - rook
P/p - pawn
- - empty square

Chữ in hoa đại diện cho các mảnh màu trắng, và chữ thường đại diện cho màu đen. Bảng sẽ được định hướng sao cho màu trắng được chơi từ dưới lên và màu đen được chơi từ trên xuống.

Đầu ra

Một động thái cho màu trắng dẫn đến kết quả là checkmate, trong ký hiệu đại số . Bạn không cần phải thông báo khi một mảnh đã được thực hiện, bạn cũng không cần phải lo lắng về việc phân định giữa hai mảnh giống hệt nhau có thể thực hiện cùng một di chuyển.

Đầu vào mẫu

ví dụ 1

Đầu vào:

------R-
--p-kp-p
-----n--
--PPK---
p----P-r
B-------
--------
--------

Đầu ra:

c6

Ví dụ 2

Đầu vào:

--b-r--r
ppq-kp-p
-np-pn-B
--------
---N----
--P----P
PP---PP-
R--QRBK-

Đầu ra:

Nf5

Ví dụ 3

Đầu vào:

---r-nr-
-pqb-p-k
pn--p-p-
R-------
--------
-P-B-N-P
-BP--PP-
---QR-K-

Đầu ra:

Rh5

Bạn có thể giả định rằng giải pháp sẽ không liên quan đến castling hoặc en-passant.

Đây là code-golf - giải pháp ngắn nhất thắng.

(Ví dụ lấy từ mateinone.com - câu đố 81, 82 và 83)


Không. Tôi nghĩ cho mục đích của câu hỏi này, bạn có thể cho rằng câu trả lời sẽ không liên quan đến việc ném đá hay en-passant. Tôi sẽ cập nhật câu hỏi.
Gareth

Làm thế nào chúng ta nên xử lý các vị trí có nhiều hơn một người bạn đời?
Cướp

@Rob Chỉ có một giải pháp được yêu cầu, vì vậy hãy xuất bất kỳ giải pháp nào bạn tìm thấy đầu tiên.
Gareth

Có an toàn không khi cho rằng giải pháp không liên quan đến quảng cáo?
Peter Taylor

@Peter Có, tôi không muốn quá phức tạp hóa vấn đề.
Gareth

Câu trả lời:


7

Ruby, 589 512 510 499 493 ký tự

R=0..7
a=->b{o=[];R.map{|r|R.map{|c|v=Hash[?K,[6,7,8,11,13,16,17,18],?R,s=[157,161,163,167],?B,t=[156,158,166,168],?Q,s+t,?N,[1,3,5,9,15,19,21,23],?P,[32,181,183]][z=b[r][c]];v&&v.map{|s|k=2!=l=s/25+1;u=r;v=c;l.times{u+=s/5%5-2;v+=s%5-2;R===u&&R===v||break;t=b[u][v];j=t<?.&&l<8;(j||t=~/[a-z]/&&k)&&o<<=(h=b.map &:swapcase;h[u][v]=h[r][c];h[r][c]=?-;[z+"%c%d"%[97+v,8-u],h.reverse]);j&&(k||r==6)||break}}}};o}
a[$<.map{|l|l}].map{|m,b|a[b].any?{|f,x|a[x].all?{|g,y|y*""=~/K/}}||$><<m[/[^P]+/]}

Đầu vào được đưa ra thông qua stdin, ví dụ:

> ruby mateinone.rb
--------
--------
--------
-k------
b-------
-N-P----
--------
-----K-Q
^Z
Qb7

Đầu ra không chỉ là một động tác buộc một người bạn đời trong một mà là mọi di chuyển làm như vậy.

Chỉnh sửa 1: Hàm chỉ eđược sử dụng một lần nên tôi đã nội tuyến. Thứ hai, mã hóa bây giờ dựa trên số 5 thay vì 10. Và tái cấu trúc bản sao của bảng đã lưu khá nhiều ký tự.

Chỉnh sửa 2: Vẫn không cải thiện nhiều như tôi muốn. Thay đổi hàm băm từ {a=>b,c=>d}sang Hash[a,b,c,d]. Điều này có giá 4 ký tự nhưng tiết kiệm một ký tự cho mỗi cặp khóa-giá trị.

Chỉnh sửa 3: Chỉ giảm bớt nhỏ: nội tuyến M (4 ký tự), t==?--> t<?.(2), loại bỏ Cầm đồ trong ký hiệu đại số ở cuối (2), thay thế đặt (3). Chương trình bây giờ ít hơn 500 ký tự.

Chỉnh sửa 4: Thật thú vị khi người ta vẫn có thể tìm thấy bao nhiêu trong một chương trình như vậy. Di chuyển một bất biến bên ngoài vòng lặp và tìm thấy một phép tính trùng lặp khác.


Bởi "không phải một, mà là" bạn có nghĩa là "không nhất thiết phải là một, mà là"?
Matthew Đọc

@Matthew Bạn nói đúng. Tôi có nghĩa là "mỗi".
Howard

Bạn có thể sử dụng [*$<]thay vì $<.map{|l|l}.
Lowjacker
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.