Commit 873bc504 authored by simonpj's avatar simonpj

[project @ 2003-10-09 11:52:01 by simonpj]

Update mate problem
parent 14533628
module Board(Kind(..), Colour(..), Piece, Square, Board,
showBoard, showPiece, showSquare,
emptyBoard, pieceAt, rmPieceAt, putPieceAt,
emptyAtAll, kingSquare, forcesColoured,
colourOf, kindOf, opponent, onboard) where
import Char
data Kind = King | Queen | Rook | Bishop | Knight | Pawn deriving (Eq,Ord)
data Colour = Black | White deriving (Eq,Ord,Show,Read)
type Piece = (Colour,Kind)
type Square = (Int,Int)
data Board = Board
[(Kind,Square)] -- white
[(Kind,Square)] -- black
showBoard bd =
unlines (map showRank (reverse [1..8]))
where
showRank r = foldr consFile [] [1..8]
where
consFile f s =
case pieceAt bd (f,r) of
Nothing -> " -" ++ s
Just p -> ' ': pieceToChar p : s
pieceToChar :: Piece -> Char
pieceToChar (Black,k) = kindToChar k
pieceToChar (White,k) = toLower (kindToChar k)
kindToChar :: Kind -> Char
kindToChar k =
case k of
King -> 'K'
Queen -> 'Q'
Rook -> 'R'
Bishop -> 'B'
Knight -> 'N'
Pawn -> 'P'
showPiece :: Piece -> String
showPiece (c,k) = [kindToChar k]
showSquare :: Colour -> Square -> String
showSquare c (x,y) =
["QR","QN","QB","Q","K","KB","KN","KR"] !! (x-1) ++
show ( case c of
Black -> 9-y
White -> y )
pieceAt :: Board -> Square -> Maybe Piece
pieceAt (Board wkss bkss) sq =
pieceAtWith White (pieceAtWith Black Nothing bkss) wkss
where
pieceAtWith c n [] = n
pieceAtWith c n ((k,s):xs) = if s==sq then Just (c,k) else pieceAtWith c n xs
emptyAtAll :: Board -> (Square->Bool) -> Bool
emptyAtAll (Board wkss bkss) e =
emptyAtAllAnd (emptyAtAllAnd True bkss) wkss
where
emptyAtAllAnd b [] = b
emptyAtAllAnd b ((_,s):xs) = not (e s) && emptyAtAllAnd b xs
rmPieceAt White sq (Board wkss bkss) = Board (rPa sq wkss) bkss
rmPieceAt Black sq (Board wkss bkss) = Board wkss (rPa sq bkss)
rPa sq (ks@(k,s):kss) = if s==sq then kss else ks : rPa sq kss
putPieceAt sq (White,k) (Board wkss bkss) = Board ((k,sq):wkss) bkss
putPieceAt sq (Black,k) (Board wkss bkss) = Board wkss ((k,sq):bkss)
kingSquare :: Colour -> Board -> Square
kingSquare White (Board kss _) = kSq kss
kingSquare Black (Board _ kss) = kSq kss
kSq ((King,s):_) = s
kSq ( _:kss) = kSq kss
opponent Black = White
opponent White = Black
colourOf :: Piece -> Colour
colourOf (c,_) = c
kindOf :: Piece -> Kind
kindOf (_,k) = k
onboard :: Square -> Bool
onboard (p,q) = 1<=p && p<=8 && 1<=q && q<=8
forcesColoured White (Board kss _) = kss
forcesColoured Black (Board _ kss) = kss
emptyBoard = Board [] []
module Board(
Kind(King,Queen,Rook,Bishop,Knight,Pawn),
Colour(Black,White), Piece, Square, Board,
showBoard, showPiece, showSquare,
emptyBoard, pieceAt, rmPieceAt, putPieceAt,
emptyAtAll, kingSquare, forcesColoured,
colourOf, kindOf, opponent, onboard) where
import Char(toLower)
data Kind = King | Queen | Rook | Bishop | Knight | Pawn deriving (Eq,Ord)
data Colour = Black | White deriving (Eq,Ord,Read,Show)
type Piece = (Colour,Kind)
type Square = (Int,Int)
data Board = Board
[(Kind,Square)] -- white
[(Kind,Square)] -- black
showBoard bd =
unlines (map showRank (reverse [1..8]))
where
showRank r = foldr consFile [] [1..8]
where
consFile f s =
case pieceAt bd (f,r) of
Nothing -> " -" ++ s
Just p -> ' ': pieceToChar p : s
pieceToChar :: Piece -> Char
pieceToChar (Black,k) = kindToChar k
pieceToChar (White,k) = toLower (kindToChar k)
kindToChar :: Kind -> Char
kindToChar k =
case k of
King -> 'K'
Queen -> 'Q'
Rook -> 'R'
Bishop -> 'B'
Knight -> 'N'
Pawn -> 'P'
showPiece :: Piece -> String
showPiece (c,k) = [kindToChar k]
showSquare :: Colour -> Square -> String
showSquare c (x,y) =
["QR","QN","QB","Q","K","KB","KN","KR"] !! (x-1) ++
show ( case c of
Black -> 9-y
White -> y )
pieceAt :: Board -> Square -> Maybe Piece
pieceAt (Board wkss bkss) sq =
pieceAtWith White (pieceAtWith Black Nothing bkss) wkss
where
pieceAtWith c n [] = n
pieceAtWith c n ((k,s):xs) = if s==sq then Just (c,k) else pieceAtWith c n xs
emptyAtAll :: Board -> (Square->Bool) -> Bool
emptyAtAll (Board wkss bkss) e =
emptyAtAllAnd (emptyAtAllAnd True bkss) wkss
where
emptyAtAllAnd b [] = b
emptyAtAllAnd b ((_,s):xs) = not (e s) && emptyAtAllAnd b xs
rmPieceAt White sq (Board wkss bkss) = Board (rPa sq wkss) bkss
rmPieceAt Black sq (Board wkss bkss) = Board wkss (rPa sq bkss)
rPa sq (ks@(k,s):kss) = if s==sq then kss else ks : rPa sq kss
putPieceAt sq (White,k) (Board wkss bkss) = Board ((k,sq):wkss) bkss
putPieceAt sq (Black,k) (Board wkss bkss) = Board wkss ((k,sq):bkss)
kingSquare :: Colour -> Board -> Square
kingSquare White (Board kss _) = kSq kss
kingSquare Black (Board _ kss) = kSq kss
kSq ((King,s):_) = s
kSq ( _:kss) = kSq kss
opponent Black = White
opponent White = Black
colourOf :: Piece -> Colour
colourOf (c,_) = c
kindOf :: Piece -> Kind
kindOf (_,k) = k
onboard :: Square -> Bool
onboard (p,q) = 1<=p && p<=8 && 1<=q && q<=8
forcesColoured White (Board kss _) = kss
forcesColoured Black (Board _ kss) = kss
emptyBoard = Board [] []
module Move (Move(..), MoveInFull(..), showMoveInFull, showMoves, moveDetailsFor, kingincheck) where
module Move (
Move(Move), MoveInFull(MoveInFull),
showMoveInFull, showMoves, moveDetailsFor, kingincheck) where
import Board
......
module Problem where
import Char
import Board
readProblem :: String -> (Board, (Colour, Int))
readProblem = parseProblem . lines
comment s = (s == [] || take 2 s == "--")
parseProblem :: [String] -> (Board, (Colour, Int))
parseProblem s = (bd, gl)
where
bd = parseBoard bdtxt
gl = parseGoal gltxt
(bdtxt, gltxt) = splitAt 8 (filter (not . comment) s)
parseBoard :: [String] -> Board
parseBoard = convert . concat . zipWith parseRank (reverse [1..8])
where
convert = foldr addPiece emptyBoard
addPiece (p,sq) = putPieceAt sq p
parseRank r = concat . zipWith (parseSquare r) [1..8] . filter (/= ' ')
parseSquare r f '-' = []
parseSquare r f c =
[((clr,kin), (f,r))]
where
clr = if isUpper c then Black else White
kin = case toLower c of
'k' -> King
'q' -> Queen
'r' -> Rook
'b' -> Bishop
'n' -> Knight
'p' -> Pawn
parseGoal :: [String] -> (Colour, Int)
parseGoal [gltxt] = (c, n)
where
ws = words gltxt
c = read (head ws)
n = read (last ws)
module Problem(readProblem) where
import Char(isUpper,toLower)
import Board
readProblem :: String -> (Board, (Colour, Int))
readProblem = parseProblem . lines
comment s = (s == [] || take 2 s == "--")
parseProblem :: [String] -> (Board, (Colour, Int))
parseProblem s = (bd, gl)
where
bd = parseBoard bdtxt
gl = parseGoal gltxt
(bdtxt, gltxt) = splitAt 8 (filter (not . comment) s)
parseBoard :: [String] -> Board
parseBoard = convert . concat . zipWith parseRank (reverse [1..8])
where
convert = foldr addPiece emptyBoard
addPiece (p,sq) = putPieceAt sq p
parseRank r = concat . zipWith (parseSquare r) [1..8] . filter (/= ' ')
parseSquare r f '-' = []
parseSquare r f c =
[((clr,kin), (f,r))]
where
clr = if isUpper c then Black else White
kin = case toLower c of
'k' -> King
'q' -> Queen
'r' -> Rook
'b' -> Bishop
'n' -> Knight
'p' -> Pawn
parseGoal :: [String] -> (Colour, Int)
parseGoal [gltxt] = (c, n)
where
ws = words gltxt
c = read (head ws)
n = read (last ws)
module Solution (solve) where
import Board
import Move
import List (sortBy)
solve :: Board -> Colour -> Int -> String
solve bd c n = showResult (solution bd c (2*n-1))
data Solution = Solution MoveInFull [(MoveInFull,Solution)]
solution :: Board -> Colour -> Int -> Maybe Solution
solution bd c n | n > 0 =
let mds = moveDetailsFor c bd in
foldr solnOr Nothing mds
where
solnOr (mif,b) other =
let rsm = replies b (opponent c) (n-1) in
case rsm of
Nothing -> other
Just [] -> if kingincheck (opponent c) b then
Just (Solution mif [])
else other
Just rs -> Just (Solution mif rs)
replies :: Board -> Colour -> Int -> Maybe [(MoveInFull, Solution)]
replies bd c n | n==0 = if null mds then Just [] else Nothing
| n>0 =
foldr solnAnd (Just []) mds
where
mds = moveDetailsFor c bd
solnAnd (mif,b) rest =
let sm = solution b (opponent c) (n-1) in
case sm of
Nothing -> Nothing
Just s -> case rest of
Nothing -> Nothing
Just ms -> Just ((mif,s):ms)
showResult Nothing = "No solution!\n"
showResult (Just s) = showSoln (compact s) 1
data Soln = Soln MoveInFull [([MoveInFull],Soln)] deriving (Eq,Ord)
compact :: Solution -> Soln
compact (Solution mif rs) = Soln mif (foldr insertCompact [] rs)
insertCompact (mif,s) = ic
where
ic [] = [([mif],cs)]
ic crs@((mifs,cs'):etc) =
case compare (showSoln cs 1) (showSoln cs' 1) of
LT -> ([mif], cs) : crs
EQ -> (insert mif mifs,cs) : etc
GT -> (mifs,cs') : ic etc
cs = compact s
insert x [] = [x]
insert x (y:ys) = case compare x y of
GT -> y : insert x ys
_ -> x : y : ys
showSoln (Soln mif rs) n =
show n ++ ". " ++ showMoveInFull mif ++
( case rs of
[] -> "++\n"
[(mifs,s)] -> ", " ++
( if length mifs > 1 then "..." else showMoves mifs) ++
"; " ++ showSoln s (n+1)
_ -> ",\n" ++ showReplies (sortBy cmpLen rs) n )
where
cmpLen (xs,_) (ys,_) = compare (length xs) (length ys)
showReplies [] n = ""
showReplies ((mifs,s):rs) n =
tab n ++ "if " ++
( if null rs && length mifs > 1 then "others"
else showMoves mifs ) ++ "; " ++
showSoln s (n+1) ++ showReplies rs n
tab :: Int -> String
tab n = take n (repeat '\t')
module Solution (solve) where
import Board
import Move
import List (sortBy)
solve :: Board -> Colour -> Int -> String
solve bd c n = showResult (solution bd c (2*n-1))
data Solution = Solution MoveInFull [(MoveInFull,Solution)]
solution :: Board -> Colour -> Int -> Maybe Solution
solution bd c n | n > 0 =
let mds = moveDetailsFor c bd in
foldr solnOr Nothing mds
where
solnOr (mif,b) other =
let rsm = replies b (opponent c) (n-1) in
case rsm of
Nothing -> other
Just [] -> if kingincheck (opponent c) b then
Just (Solution mif [])
else other
Just rs -> Just (Solution mif rs)
replies :: Board -> Colour -> Int -> Maybe [(MoveInFull, Solution)]
replies bd c n | n==0 = if null mds then Just [] else Nothing
| n>0 =
foldr solnAnd (Just []) mds
where
mds = moveDetailsFor c bd
solnAnd (mif,b) rest =
let sm = solution b (opponent c) (n-1) in
case sm of
Nothing -> Nothing
Just s -> case rest of
Nothing -> Nothing
Just ms -> Just ((mif,s):ms)
showResult Nothing = "No solution!\n"
showResult (Just s) = showSoln (compact s) 1
data Soln = Soln MoveInFull [([MoveInFull],Soln)] deriving (Eq,Ord)
compact :: Solution -> Soln
compact (Solution mif rs) = Soln mif (foldr insertCompact [] rs)
insertCompact (mif,s) = ic
where
ic [] = [([mif],cs)]
ic crs@((mifs,cs'):etc) =
case compare (showSoln cs 1) (showSoln cs' 1) of
LT -> ([mif], cs) : crs
EQ -> (insert mif mifs,cs) : etc
GT -> (mifs,cs') : ic etc
cs = compact s
insert x [] = [x]
insert x (y:ys) = case compare x y of
GT -> y : insert x ys
_ -> x : y : ys
showSoln (Soln mif rs) n =
show n ++ ". " ++ showMoveInFull mif ++
( case rs of
[] -> "++\n"
[(mifs,s)] -> ", " ++
( if length mifs > 1 then "..." else showMoves mifs) ++
"; " ++ showSoln s (n+1)
_ -> ",\n" ++ showReplies (sortBy cmpLen rs) n )
where
cmpLen (xs,_) (ys,_) = compare (length xs) (length ys)
showReplies [] n = ""
showReplies ((mifs,s):rs) n =
tab n ++ "if " ++
( if null rs && length mifs > 1 then "others"
else showMoves mifs ) ++ "; " ++
showSoln s (n+1) ++ showReplies rs n
tab :: Int -> String
tab n = take n (repeat '\t')
b k - - - - - -
- n p - - - - -
- - - - - - - -
r - - - - p - -
R - - - K - - -
- - - r P - p -
- Q - - - - - -
- - - - - q B B
White to move and mate in 2
1. R/Q3-Q7,
if R/QR5-Q5; 2. R/Q7-K7 ++
if B/KN8-KB7; 2. QxB/KR1 ++
if B/KR8-KB6; 2. Q-Q3 ++
if Q-K4; 2. N/QN7-QB5 ++
if Q-Q5; 2. N/QN7-Q6 ++
if QxN/QN2; 2. B/QR8xQ/QN7 ++
if Q-K7, -KB7, -KN2, -KN7, -KR1, -KR7, -QR6, -QR8; 2. N/QN7-Q8 ++
... ; 2. Q-KB4 ++
b k - - - - - -
- n p - - - - -
- - - - - - - -
r - - - - p - -
R - - - K - - -
- - - r P - p -
- Q - - - - - -
- - - - - q B B
White to move and mate in 2
1. R/Q3-Q7,
if Q/QN7xN/QN2; 2. B/QR8xQ/QN7++
if Q/QN7-Q5; 2. N/QN7-Q6++
if Q/QN7-K4; 2. N/QN7-QB5++
if B/KR8-KB6; 2. Q/KB1-Q3++
if B/KN8-KB7; 2. Q/KB1xB/KR1++
if R/QR5-Q5; 2. R/Q7-K7++
if Q/QN7-QR8, -QR6, -K7, -KB7, -KN7, -KN2, -KR7, -KR1; 2. N/QN7-Q8++
if others; 2. Q/KB1-KB4++
- - - - - - - -
B - - - - P k -
- P - b - - - -
N - - n - - P -
p - p K - - - -
- - r - - - - -
- - p P B - - -
- - - - - - - q
White to move and mate in 3
1. R/QB3-KB3,
if B/QR2-QN1; 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if P-KB3; 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if P-KB4; 2. Q-QR1,
if K-K5; 3. R/KB3-K3 mate.
if KxP/QB5; 3. N/Q5-K3 mate.
if P-QN4; 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if N/QR4-QN6; 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if N/QR4-QB3; 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if N/QR4-QN2; 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if N/QR4xP/QB5; 2. R/KB3-Q3, B/K7xR/Q6; 3. P-QB3 mate.
if P-KN5; 2. R/KB3-KB4 mate.
if K-K5; 2. R/KB3-KB4 mate.
if KxP/QB5; 2. R/KB3-KB4, P/KN4xR/KB5; 3. Q-K4 mate.
if P/Q7-Q8(Q); 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if P/Q7-Q8(R); 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if P/Q7-Q8(B); 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if P/Q7-Q8(N); 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if B/K7-KB8; 2. Q-KR4,
if P-KN5; 3. QxP/KN4 mate.
if P/KN4xQ/KR5; 3. R/KB3-KB4 mate.
if B/K7-Q8; 2. R/KB3-Q3, KxP/QB5; 3. N/Q5-K3 mate.
if B/K7-Q6; 2. R/KB3xB/Q3, KxP/QB5; 3. N/Q5-K3 mate.
if B/K7xR/KB6; 2. Q-QR1,
if K-K5; 3. Q-K5 mate.
if KxP/QB5; 3. N/Q5-K3 mate.
if B/K7xP/QB5; 2. P-QB3,
if K-K5; 3. N/Q5-KB6 mate.
if KxN/Q4; 3. R/KB3-KB6 mate.
- - - - - - - -
B - - - - P k -
- P - b - - - -
N - - n - - P -
p - p K - - - -
- - r - - - - -
- - p P B - - -
- - - - - - - q
White to move and mate in 3
1. R/QB3-KB3,
if B/K7xP/QB5; 2. P-QB3,
if K-K5; 3. N/Q5-KB6++
if KxN/Q4; 3. R/KB3-KB6++
if B/K7xR/KB6; 2. Q/KR1-QR1,
if KxP/QB5; 3. N/Q5-K3++
if K-K5; 3. Q/QR1-K5++
if P-KB4; 2. Q/KR1-QR1,
if KxP/QB5; 3. N/Q5-K3++
if K-K5; 3. R/KB3-K3++
if KxP/QB5; 2. R/KB3-KB4, P/KN4xR/KB5; 3. Q/KR1-K4++
if N/QR4xP/QB5; 2. R/KB3-Q3, B/K7xR/Q6; 3. P-QB3++
if B/K7-Q8; 2. R/KB3-Q3, KxP/QB5; 3. N/Q5-K3++
if B/K7-Q6; 2. R/KB3xB/Q3, KxP/QB5; 3. N/Q5-K3++
if K-K5, P-KN5; 2. R/KB3-KB4++
if others; 2. Q/KR1-KR4,
if P-KN5; 3. Q/KR4xP/KN4++
if P/KN4xQ/KR5; 3. R/KB3-KB4++
- - - - R - - K
- - - - - - - b
- b - - N - q -
- - - - - - - -
- - - - - - P -
- r - - - - p -
- - p - - - - k
- - - - - - - -
White to move and mate in 4
1. B/QN6-QB7,
if N/K3xB/QB2; 2. R/QN3-QN8,
if R/K1-QB1; 3. R/QN8xR/QB8, N/QB2-K1; 4. R/QB8xN/K8 ++
if R/K1-Q1; 3. R/QN8xR/Q8, N/QB2-K1; 4. R/Q8xN/K8 ++
if R/K1-KN1; 3. R/QN8xR/KN8 ++
if R/K1-KB1; 3. R/QN8xR/KB8 ++
if N/QB2-K3; 3. R/QN8xR/K8, N/K3-KB1; 4. R/K8xN/KB8 ++
if R/K1xR/QN1; 3. B/KR7-KN8,
if R/QN1xB/KN1; 4. Q-KR6 ++
... ; 4. Q-KR7 ++
... ; 3. R/QN8xR/K8 ++
if N/K3-KN2; 2. R/QN3-QN8,
if R/K1-QB1; 3. R/QN8xR/QB8, N/KN2-K1; 4. R/QB8xN/K8 ++
if R/K1-Q1; 3. R/QN8xR/Q8, N/KN2-K1; 4. R/Q8xN/K8 ++
if R/K1-KN1; 3. R/QN8xR/KN8 ++
if R/K1-KB1; 3. R/QN8xR/KB8 ++
if N/KN2-K3; 3. R/QN8xR/K8, N/K3-KB1; 4. R/K8xN/KB8 ++
if R/K1xR/QN1; 3. B/QB7xR/QN8, ... ; 4. Q-KN8 ++
... ; 3. R/QN8xR/K8 ++
if R/K1-QN1; 2. B/QB7-KB4,
if N/K3xB/KB5; 3. R/QN3xR/QN8 ++
if R/QN1-QN2; 3. Q-KN8 ++
if R/QN1-KN1; 3. B/KR7xR/KN8,
if N/K3-KN2, N/K3xB/KB5; 4. Q-KR7 ++
... ; 4. B/KB4-K5 ++
if N/K3-KN2; 3. B/KB4xR/QN8, ... ; 4. Q-KN8 ++
if R/QN1-QN4; 3. B/KB4-K5,
if R/QN4xB/K4; 4. Q-KN8 ++
if N/K3-KN2; 4. B/K5xN/KN7 ++
if R/QN1-KB1; 3. B/KB4-K5,
if R/KB1-KB3; 4. Q-KN8 ++
if N/K3-KN2; 4. B/K5xN/KN7 ++
if N/K3-KB1, -KN4, -Q1, -Q5, -QB2, -QB4; 3. B/KB4-K5 ++
... ; 3. B/KB4-K5, N/K3-KN2; 4. B/K5xN/KN7 ++
if R/K1-KB1; 2. B/QB7-K5,
if R/KB1-KB3; 3. B/K5xR/KB6, N/K3-KN2; 4. B/KB6xN/KN7 ++
if N/K3-KN2; 3. B/K5xN/KN7 ++
if R/K1-K2; 2. B/QB7-K5,
if N/K3-KN2; 3. R/QN3-QN8, R/K2-K1; 4. R/QN8xR/K8 ++
if R/K2-KN2; 3. B/K5-KB6, ... ; 4. B/KB6xR/KN7 ++
if R/K1-KN1; 2. B/QB7-K5,
if N/K3-KN2; 3. B/K5-QR1, ... ; 4. B/QR1xN/KN7 ++
if R/KN1-KN2; 3. B/K5-KB6, ... ; 4. B/KB6xR/KN7 ++
if R/K1-Q1, -QB1, -QR1; 2. B/QB7-K5, N/K3-KN2; 3. B/K5xN/KN7 ++
... ; 2. B/QB7-K5, R/K1xB/K4; 3. Q-KN8 ++
File: holzhausen.prob
- - - - R - - K
- - - - - - - b
- b - - N - q -
- - - - - - - -
- - - - - - P -
- r - - - - p -
- - p - - - - k
- - - - - - - -
White to move and mate in 4
1. B/QN6-QB7,
if R/K1-KB1; 2. B/QB7-K5,
if N/K3-KN2; 3. B/K5xN/KN7++
if R/KB1-KB3; 3. B/K5xR/KB6, N/K3-KN2; 4. B/KB6xN/KN7++
if R/K1-K2; 2. B/QB7-K5,
if R/K2-KN2; 3. B/K5-KB6, ...; 4. B/KB6xR/KN7++
if N/K3-KN2; 3. R/QN3-QN8, R/K2-K1; 4. R/QN8xR/K8++
if R/K1-KN1; 2. B/QB7-K5,
if R/KN1-KN2; 3. B/K5-KB6, ...; 4. B/KB6xR/KN7++
if N/K3-KN2; 3. B/K5-QR1, ...; 4. B/QR1xN/KN7++
if R/K1-QN1; 2. B/QB7-KB4,
if R/QN1-KB1; 3. B/KB4-K5,
if N/K3-KN2; 4. B/K5xN/KN7++
if R/KB1-KB3; 4. Q/KN6-KN8++
if R/QN1-QN4; 3. B/KB4-K5,
if N/K3-KN2; 4. B/K5xN/KN7++
if R/QN4xB/K4; 4. Q/KN6-KN8++
if N/K3-Q1; 3. B/KB4xR/QN8,
if N/Q1-QN2; 4. B/QN8-K5++
if others; 4. Q/KN6-KN8++
if N/K3-QB4; 3. B/KB4xR/QN8,
if N/QB4-QR5, -QR3, xR/QN6, -QN2; 4. B/QN8-K5++
if others; 4. Q/KN6-KN8++
if N/K3-KN2; 3. B/KB4xR/QN8, ...; 4. Q/KN6-KN8++
if R/QN1-KN1; 3. B/KR7xR/KN8,
if N/K3xB/KB5, -KN2; 4. Q/KN6-KR7++
if others; 4. B/KB4-K5++
if R/QN1-QN2; 3. Q/KN6-KN8++
if N/K3xB/KB5; 3. R/QN3xR/QN8++
if N/K3-QB2, -Q5, -KB1, -KN4; 3. B/KB4-K5++
if others; 3. B/KB4-K5, N/K3-KN2; 4. B/K5xN/KN7++
if N/K3xB/QB2; 2. R/QN3-QN8,
if R/K1xR/QN1; 3. B/KR7-KN8,
if R/QN1xB/KN1; 4. Q/KN6-KR6++
if others; 4. Q/KN6-KR7++
if N/QB2-K3; 3. R/QN8xR/K8, N/K3-KB1; 4. R/K8xN/KB8++
if R/K1-KB1; 3. R/QN8xR/KB8++
if R/K1-KN1; 3. R/QN8xR/KN8++
if R/K1-Q1; 3. R/QN8xR/Q8, N/QB2-K1; 4. R/Q8xN/K8++
if R/K1-QB1; 3. R/QN8xR/QB8, N/QB2-K1; 4. R/QB8xN/K8++
if others; 3. R/QN8xR/K8++
if N/K3-KN2; 2. R/QN3-QN8,
if R/K1xR/QN1; 3. B/QB7xR/QN8, ...; 4. Q/KN6-KN8++
if N/KN2-K3; 3. R/QN8xR/K8, N/K3-KB1; 4. R/K8xN/KB8++
if R/K1-KB1; 3. R/QN8xR/KB8++
if R/K1-KN1; 3. R/QN8xR/KN8++
if R/K1-Q1; 3. R/QN8xR/Q8, N/KN2-K1; 4. R/Q8xN/K8++
if R/K1-QB1; 3. R/QN8xR/QB8, N/KN2-K1; 4. R/QB8xN/K8++
if others; 3. R/QN8xR/K8++
if R/K1-QR1, -QB1, -Q1; 2. B/QB7-K5, N/K3-KN2; 3. B/K5xN/KN7++
if others; 2. B/QB7-K5, R/K1xB/K4; 3. Q/KN6-KN8++
- - - - - - - -
- - - - - - - -
- - - - P b - -
- - P - - - - -
- - K P p - - -
- - - - - - - -
- r - k - - - -
- - - - - - - -
White to move and mate in 4
1. R/QN2-QN1,
if P-K4; 2. B/KB6-Q8, P-Q6; 3. B/Q8-QN6, K-Q5; 4. R/QN1-QN4 mate.
if P-Q6; 2. B/KB6-QR1, P-K4; 3. R/QN1-QN2, K-Q5; 4. R/QN2-QN4 mate.
- - - - - - - -
- - - - - - - -
- - - - P b - -
- - P - - - - -