Haskell , 1165 1065 1053 ไบต์
จำนวนไบต์ที่บันทึกไว้ต้องขอบคุณLeo Tenenbaum
n=Nothing
x?y=Just(x,y)
o(x,y)=x<0||y<0||x>7||y>7
m#k@(x,y)|o k=n|1>0=m!!x!!y
z(x,y)m p(a,b)|o(x+a,y+b)=1<0|Just g<-m#(x+a,y+b)=elem g[(p,0),(5,0)]|1>0=z(x+a,y+b)m p(a,b)
t(x,y)p(a,b)m|o(x+a,y+b)=[]|g<-(x+a,y+b)=(g%p)m++do[0|m#g==n];t g p(a,b)m
c m|(x,y):_<-[(a,b)|a<-u,b<-u,m#(a,b)==6?1],k<-z(x,y)m=or$[m#(x+a,y+b)==6?0|a<-0:s,b<-0:s]++do a<-s;[k 3(a,b)|b<-s]++(k 2<$>[(a,0),(0,a)])++[m#l==4?0|b<-[2,-2],l<-[(x+a,y+b),(x+b,y+a)]]++[m#(x-1,y+a)==p?0|p<-[0,1]]
c m=1>0
(k%p)m=[[[([p|a==k]++[m#a])!!0|a<-(,)b<$>u]|b<-u]|not$o k]
w(Just(_,1))=1<0
w x=1>0
m!u@(x,y)|g<-m#u,Just(q,1)<-g,v<-((u%n)m>>=),r<-v.t u g,k<-(do[0|n==m#(x+1,y)];(u%n)m>>=(x+1,y)%g)++(do a<-s;[0|n<m#(x+1,y+a)];v$(x+1,y+a)%g)++(do[0|(x,n,n)==(1,m#(x+1,y),m#(x+2,y))];v$(x+2,y)%g)++(do a<-s;[0|1?0==m#(x,y+a)];v((x,y+a)%n)>>=(x+1,y+a)%g)=[k,k,do a<-s;[(a,0),(0,a)]>>=r,do a<-s;b<-s;r(a,b),do a<-s;b<-[2,-2];l<-[(x+a,y+b),(x+b,y+a)];v$l%g,do a<-0:s;b<-[0|a/=0]++s;r(a,b),do a<-[x-1..x+1];b<-[y-1..y+1];[0|w$m#(a,b)];v$(a,b)%g]!!q
m!u=[]
u=[0..7]
s=[1,-1]
q m=all c$m:do a<-u;b<-u;m!(a,b)
ลองออนไลน์!
นี่ไม่ใช่การเล่นกอล์ฟที่ดีในตอนนี้ แต่มันเป็นการเริ่มต้น ด้วยความช่วยเหลือไปพร้อมกันตอนนี้ฉันเล่นกอล์ฟนี้ลงอย่างจริงจัง (และแก้ไขข้อผิดพลาดระหว่างทาง)
สิ่งหนึ่งที่น่าสงสัยในเรื่องนี้ก็คือสมมติว่านอกเหนือจากกษัตริย์หรือผู้ที่จำนำคุณไม่สามารถออกจากการตรวจสอบได้โดยจับชิ้นส่วนของคุณเอง ในหมากรุกคุณไม่ได้รับอนุญาตให้ทำการย้ายนี้ แต่โปรแกรมของฉันพิจารณาการย้ายเหล่านี้เพื่อบันทึกไบต์ภายใต้สมมติฐานว่าหากคุณอยู่ในการตรวจสอบนี้ไม่สามารถพาคุณออกจากมันได้
สมมติฐานนี้ใช้ได้เนื่องจากการเคลื่อนไหวดังกล่าว
ไม่สามารถจับชิ้นส่วนที่โจมตีกษัตริย์เนื่องจากชิ้นส่วนที่พวกเขาจับเป็นสีดำ
ไม่สามารถบล็อกเส้นทางของชิ้นส่วนที่โจมตีกษัตริย์ได้เนื่องจากชิ้นส่วนสีดำที่จับได้จะทำเช่นนั้นแล้ว
นอกจากนี้เรายังเพิ่มข้อกำหนดเพิ่มเติมว่าหากคุณไม่มีกษัตริย์คุณกำลังอยู่ในการตรวจสอบ
โปรแกรมนี้ทำให้สมมติฐานที่ว่าหากมีเบี้ยที่สามารถจับ en passant แล้วเบี้ยเป็นชิ้นสุดท้ายที่จะย้ายและย้ายที่ถูกกฎหมาย นี่เป็นเพราะโปรแกรมไม่ได้ตรวจสอบว่าสี่เหลี่ยมจัตุรัสมันเคลื่อนตัวเบี้ยสีดำไปว่างเปล่าหรือเปล่าดังนั้นถ้ามีชิ้นส่วน อย่างไรก็ตามสิ่งนี้ไม่สามารถรับได้หากการย้ายครั้งสุดท้ายเป็นการย้ายที่ถูกกฎหมายและไม่สามารถแสดงในFENได้ ดังนั้นสมมติฐานนี้ค่อนข้างแข็ง
นี่คือรุ่น "ungolfed" ของฉันสำหรับการอ้างอิง:
import Control.Monad
out(x,y)=x<0||y<0||x>7||y>7
at b (x,y)
|out(x,y)=Nothing
|otherwise=(b!!x)!!y
inLine (x,y) ps m (a,b)
| out (x+a,y+b) = False
| elem (m `at` (x+a,y+b)) $ Just <$> ps = True
| m `at` (x+a,y+b) == Nothing = inLine (x+a,y+b) ps m (a,b)
| otherwise = False
goLine (x,y) p (a,b)m
| out (x+a,y+b) = []
| otherwise = case m `at` (x+a,y+b) of
-- Just (n,1) -> []
Just (n,_) -> set(x+a,y+b)p m
Nothing -> set(x+a,y+b)p m ++ goLine(x+a,y+b)p(a,b)m
checkBishop (x,y) m=or[inLine(x,y)[(3,0),(5,0)]m(a,b)|a<-[1,-1],b<-[1,-1]]
checkRook (x,y) m=or$do
a<-[1,-1]
inLine(x,y)[(2,0),(5,0)]m<$>[(a,0),(0,a)]
checkKnight (x,y) m=any((==Just(4,0)).(at m))$do
a<-[1,-1]
b<-[2,-2]
[(x+a,y+b),(x+b,y+a)]
checkPawn (x,y) m=or[at m a==Just(p,0)|a<-[(x-1,y+1),(x-1,y-1)],p<-[0,1]]
checkKing (x,y) m=or[at m(a,b)==Just(6,0)|a<-[x-1..x+1],b<-[y-1..y+1]]
check m
| u:_<-[(a,b)|a<-[0..7],b<-[0..7],(m!!a)!!b==Just(6,1)] =
checkBishop u m ||
checkRook u m ||
checkKnight u m ||
checkPawn u m ||
checkKing u m
| otherwise = True
set (x,y) p m=[[[head$[p|(a,b)==(y,x)]++[(m!!b)!!a]|a<-[0..7]]|b<-[0..7]]|not$out(x,y)]
white(Just(n,0))=True
white x=False
moves m (x,y)
|g<-m `at` (x,y)=case g of
Just(2,1) -> do
a<-[1,-1]
b<-[(a,0),(0,a)]
set(x,y)Nothing m>>=goLine (x,y) g b
Just(3,1) -> do
a<-[1,-1]
b<-[1,-1]
set(x,y)Nothing m>>=goLine (x,y) g(a,b)
Just(4,1) -> do
n<-set(x,y)Nothing m
a<-[1,-1]
b<-[2,-2]
l<-[(x+a,y+b),(x+b,y+a)]
-- guard$white$n `at` l
set l g n
Just(5,1) -> do
a<-[1,-1]
c<-[(a,0),(0,a),(a,1),(a,-1)]
set(x,y)Nothing m>>=goLine (x,y) g c
Just(6,1) -> do
a<-[x-1..y+1]
b<-[x-1..y+1]
guard$white(m `at`(a,b))||Nothing==m`at`(a,b)
set(x,y)Nothing m>>=set(a,b)g
Just(n,1) -> (do
guard$Nothing==m `at` (x+1,y)
set(x,y)Nothing m>>=set(x+1,y)g) ++ (do
a<-[1,-1]
guard$white$m`at`(x+1,y+a)
set(x,y)Nothing m>>=set(x+1,y+a)g) ++ (do
guard$(x,Nothing,Nothing)==(1,m`at`(x+1,y),m`at`(x+1,y))
set(x,y)Nothing m>>=set(x+2,y)g) ++ (do
a<-[1,-1]
guard$Just(1,0)==m`at`(x,y+a)
set(x,y)Nothing m>>=set(x,y+a)Nothing>>=set(x+1,y+a)g)
_ -> []
checkmate m=all check$m:do
a<-[0..7]
b<-[0..7]
moves m(a,b)
ลองออนไลน์!