체스 엔드 게임 : 화이트 투 메이트 인


19

체스 게임의 현재 상태를 나타내는 8x8 문자 그리드가 주어지면 프로그램의 과제는 흰색으로 이동하여 체크 메이트를 얻는 것입니다 (답은 항상 한 번에 메이트됩니다).

입력

입력은 STDIN-8 자씩 8 줄로 이루어집니다. 각 문자의 의미는 다음과 같습니다.

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

대문자는 흰색 조각을 나타내고 소문자는 검은 색을 나타냅니다. 보드는 흰색이 아래쪽에서 재생되고 검은 색이 위쪽에서 재생되도록 방향이 지정됩니다.

산출

대수 표기법으로 장군이되는 흰색으로의 이동 . 한 조각을 가져 왔을 때 알림을받을 필요가 없으며 동일한 움직임을 만들어 낼 수있는 두 개의 동일한 조각 사이를 명확하게 할 필요가 없습니다.

샘플 입력

실시 예 1

입력:

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

산출:

c6

실시 예 2

입력:

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

산출:

Nf5

실시 예 3

입력:

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

산출:

Rh5

솔루션에 castling 또는 en-passant가 포함되지 않는다고 가정 할 수 있습니다.

이것은 코드 골프입니다-가장 짧은 솔루션이 승리합니다.

( mateinone.com 에서 가져온 예 -퍼즐 81, 82 및 83)


아니요.이 질문의 목적에 따라 답변에 거세 나 참여자가 포함되지 않는다고 가정 할 수 있습니다. 질문을 업데이트하겠습니다.
Gareth

둘 이상의 친구가있는 직책을 어떻게 처리해야합니까?
Rob

@Rob 하나의 솔루션 만 필요하므로 먼저 찾은 솔루션을 출력하십시오.
Gareth

솔루션에 프로모션이 포함되지 않았다고 가정해도 안전합니까?
피터 테일러

@Peter 예, 문제를 너무 복잡하게하고 싶지 않습니다.
Gareth

답변:


7

루비, 589 512 510 499 493 자

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]+/]}

입력은 stdin을 통해 제공됩니다. 예 :

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

출력은 메이트를 한 번에 강제하는 하나의 움직임이 아니라 그렇게하는 모든 움직임입니다.

편집 1 : 함수 e가 한 번만 사용되어 인라인되었습니다. 둘째, 인코딩은 이제 10 대신 5를 기준으로합니다. 보드 복제를 리팩토링하면 많은 문자가 절약되었습니다.

편집 2 : 여전히 원하는만큼 개선되지 않았습니다. 에서 해시 변경 {a=>b,c=>d}Hash[a,b,c,d]. 비용은 4 자이지만 키-값 쌍당 하나씩 저장합니다.

편집 3 : 사소한 축소 : M (4 자) 인라인 t==?--> t<?.(2), 마지막에 대수 표기법에서 폰을 제거하고 (2) 풋을 대체했습니다 (3). 프로그램은 현재 500 자 미만입니다.

편집 4 : 그러한 프로그램에서 여전히 찾을 수있는 것이 흥미 롭습니다. 루프 외부에서 불변을 이동하고 다른 중복 계산을 찾았습니다.


"하나가 아니라 하나"는 "하나가 아니라 반드시"를 의미합니까?
Matthew 읽기

@Matthew 당신이 맞아요. 나는 "모두"를 의미했다.
Howard

[*$<]대신 사용할 수 있습니다 $<.map{|l|l}.
Lowjacker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.