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)
在线尝试!
到目前为止,打高尔夫球还不够好,但这是一个开始。 在此过程中得到了一些帮助,我现在已经非常积极地进行了深入研究(并修复了过程中的错误)。
它可能做的一件可能值得怀疑的事情是,它假设除了国王或典当行外,您永远无法通过捕获自己的碎片来摆脱失控。在国际象棋中,您不允许这样做,但是我的程序会在假设您处于检查状态的情况下考虑这些移动以节省字节,因为这样做永远都无法使您摆脱困境。
这个假设是正确的,因为这样的举动
无法捕获攻击国王的棋子,因为它们捕获的棋子是黑色的。
无法阻挡正在攻击国王的棋子的路径,因为捕获的黑色棋子已经在这样做了。
我们还添加了额外的规定,即如果您没有国王,则需要检查。
该程序还假设,如果有一个可以同时捕获的棋子,则该棋子是最后移动的棋子,而该移动是合法的棋子。这是因为程序不会检查将黑色棋子移动到的正方形是否为空,所以如果有一块,那东西可能会有些螺丝钉。但是,如果最后的举动是合法的举动,则无法获得此结果,而且不能在FEN中表示。因此,这个假设似乎很可靠。
这是我的“ unolfed”版本供参考:
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)
在线尝试!