1 > module InterpUtils where
7 %------------------------------------------------------------------------------
9 This part computes the effect a move has on its board.
11 > findCastleKMove brd = (castleK,makeACastleK brd)
12 > findCastleQMove brd = (castleQ,makeACastleQ brd)
21 First the pawns. They are seprate because:
22 1. There are many pawns, so knowing the file helps.
23 2. You dont need to dis-ambiguate a pawn move. exf7 is fine.
25 > findAPawnMove move_src move_dest queen brd@(Board arr mv _)
26 > = debug (move_txt,new_brd)
29 > move_colour = getMoveColour mv
32 > {- userFormat brd ++ -}
33 > userFormat (getMoveColour mv) ++
34 > -- " (" ++ userFormat absmove ++ ")" ++
35 > "\nALL :" ++ unwords (map userFormat all_moves) ++
38 Now get all valid moves (for the correct piece), including some
39 illegal moves (ie. pinned pieces).
41 > correct_src = concat (map (getAllMovesFor brd) currPieces)
45 > (x,y) <- start_range,
47 > lookupSquare move_colour r == Friendly,
48 > (Just Pawn) <- [getSquarePiece r]]
50 Now filter out the moves it *cant* be.
53 > = case (move_src,move_dest) of
54 > ((Just f,Just r),_) -> [(f,r)]
55 > ((Just f,_),_) -> [(f,r) | r <- [2..7]]
57 > (_,(Just f,_)) -> [(f,r) | r <- [2..7]]
58 > _ -> error "strange pawn move:"
60 > the_correct_move = if (length correct_move /= 1)
61 > then error ("\nAmbiguous move:"
62 > ++ show (unwords (map userFormat correct_move))
63 > ++ ":" ++ {- userFormat absmove ++ -} "\n"
65 > else head correct_move
68 > filter (sameQueening queen.extractSpecialFromPlayMove)
69 > (filter (compExBPandBP move_dest.extractDestFromPlayMove)
71 > sameQueening (Just p) (Queening p') = p == p'
72 > sameQueening Nothing (Queening p') = Queen == p'
73 > sameQueening _ _ = True
75 > move_txt = createShortMove the_correct_move "" brd
78 > (extractSrcFromPlayMove the_correct_move) ++
80 > (extractDestFromPlayMove the_correct_move)
82 > new_brd = makeAMove brd the_correct_move
84 Now castling, which is very obvious.
95 > findAMove move_piece move_src move_dest brd@(Board arr mv _)
96 > = debug (move_txt,new_brd)
99 First get char's about this move
101 > move_colour = getMoveColour mv
104 > {- userFormat brd ++ -}
105 > userFormat (getMoveColour mv) ++
106 > " (" ++ {- userFormat absmove ++ -} ")" ++
107 > "\nALL :" ++ unwords (map userFormat all_moves) ++
108 > "\nDEST :" ++ unwords (map userFormat correct_dest) ++
109 > "\nSRC :" ++ unwords (map userFormat correct_move) ++
113 Now get all valid moves (for the correct piece), including some
114 illegal moves (ie. pinned pieces).
116 > all_moves = allValidMoves brd move_piece (const True)
118 Now filter out the moves it *cant* be.
120 > correct_dest = filter
121 > (compExBPandBP move_dest.extractDestFromPlayMove)
123 > correct_move = filter
124 > (compExBPandBP move_src.extractSrcFromPlayMove)
126 > the_correct_move = if (length correct_move /= 1)
127 > then error ("\nAmbiguous move:"
128 > ++ show (unwords (map userFormat correct_move))
129 > ++ ":" {- ++ userFormat absmove -} ++ "\n"
131 > else head correct_move
132 > disamb = case move_dest of
133 > (Just _,Nothing) -> "" -- fg => fxg4, no disambig.
135 > (extractSrcFromPlayMove the_correct_move)
136 > (map (extractSrcFromPlayMove) correct_dest)
138 > move_txt = createShortMove the_correct_move disamb brd
141 > (extractSrcFromPlayMove the_correct_move) ++
143 > (extractDestFromPlayMove the_correct_move)
145 > new_brd = makeAMove brd the_correct_move
146 > --partain: findAMove _ _ _ brd = error ("strange move: ")
148 > allValidMoves :: Board -> Piece -> (ChessFile -> Bool) -> [PlayMove]
149 > allValidMoves brd piece corr_file
150 > = concat (map (getAllMovesFor brd) (getCurrPieces brd piece corr_file))
155 > -> (ChessFile -> Bool)
156 > -> [(Piece,ChessFile,ChessRank)]
157 > getCurrPieces (Board arr (MoveNumber _ col) _) pc corr_file =
159 > ((x,y), r) <- assocs arr,
160 > lookupSquare col r == Friendly,
161 > (Just p) <- [getSquarePiece r],
166 %------------------------------------------------------------------------------
168 Given a board and a particular piece,
169 where can it get to ?
171 > getAllMovesFor :: Board -> (Piece,Int,Int) -> [PlayMove]
173 First the easy pieces, the gliders.
175 > getAllMovesFor brd (Rook,x,y) =
176 > [ mkPlayMove Rook (x,y) (x',y')
178 > movePiece 0 1 brd x y ++
179 > movePiece 0 (-1) brd x y ++
180 > movePiece 1 0 brd x y ++
181 > movePiece (-1) 0 brd x y) ]
182 > getAllMovesFor brd (Bishop,x,y) =
183 > [ mkPlayMove Bishop (x,y) (x',y')
185 > movePiece 1 1 brd x y ++
186 > movePiece 1 (-1) brd x y ++
187 > movePiece (-1) 1 brd x y ++
188 > movePiece (-1) (-1) brd x y) ]
189 > getAllMovesFor brd (Queen,x,y) =
190 > [ mkPlayMove Queen (x,y) (x',y')
192 > movePiece 0 1 brd x y ++
193 > movePiece 0 (-1) brd x y ++
194 > movePiece 1 0 brd x y ++
195 > movePiece (-1) 0 brd x y ++
196 > movePiece 1 1 brd x y ++
197 > movePiece 1 (-1) brd x y ++
198 > movePiece (-1) 1 brd x y ++
199 > movePiece (-1) (-1) brd x y) ]
203 > getAllMovesFor brd (Knight,x,y) =
204 > [ mkPlayMove Knight (x,y) (x',y')
205 > | (xd,yd) <- concat
206 > [ [(d1,d2 * 2),(d1 * 2,d2)]
207 > | d1 <- [1,-1], d2 <- [1,-1]],
210 > case lookupBoard brd (x',y') of
216 > getAllMovesFor brd (King,x,y) =
217 > [ mkPlayMove King (x,y) (x',y')
218 > | (xd,yd) <- [(1,1),(1,0),(1,-1),(0,1),
219 > (0,-1),(-1,1),(-1,0),(-1,-1)],
222 > case lookupBoard brd (x',y') of
228 Now the *special* case, the pawn! Pain in the neck.
231 > getAllMovesFor brd@(Board _ (MoveNumber _ col) may_ep) (Pawn,x,y)
235 > case lookupBoard brd (x,y+del) of
238 > Vacant -> (mkPlayMove Pawn (x,y) (x,y+del) :
239 > if y /= sta then [] else
240 > case lookupBoard brd (x,y+del*2) of
244 > [ PlayMove Pawn (x,y) (x,y+del*2) BigPawnMove])
245 > left_pc = case lookupBoard brd (x-1,y+del) of
246 > Baddy -> [mkPlayMove Pawn (x,y) (x-1,y+del) ]
248 > right_pc = case lookupBoard brd (x+1,y+del) of
249 > Baddy -> [mkPlayMove Pawn (x,y) (x+1,y+del) ]
251 > all_pawn_moves = pawn_moves ++ left_pc ++ right_pc
252 > real_pawn_moves = en_passant ++
253 > (if y + del == qn -- if can queens
254 > then concat [ let fn = PlayMove Pawn f t . Queening
260 > | PlayMove _ f t _ <- all_pawn_moves ]
261 > else all_pawn_moves)
263 > case (y == ep,may_ep) of
264 > (True,Just f) | f == x+1 || f == x-1
265 > -> [PlayMove Pawn (x,y) (f,y+del) EnPassant]
267 > del,sta,qn,ep :: Int
268 > (del,sta,qn,ep) -- delta (direction), start, Queening and E.P. Rank
271 > Black -> (-1,7,1,4)
273 > movePiece xd yd brd x y =
274 > case lookupBoard brd (x',y') of
278 > Vacant -> (x',y') : movePiece xd yd brd x' y'
284 %------------------------------------------------------------------------------
286 > makeAMove :: Board -> PlayMove -> Board
287 > makeAMove board@(Board brd mv@(MoveNumber _ col) _)
288 > move@(PlayMove piece pos pos' NothingSpecial) =
289 > Board (brd // [ pos =: VacantSq,
290 > pos' =: mkColBoardSq col piece ])
291 > (incMove mv) Nothing
292 > makeAMove board@(Board brd mv@(MoveNumber _ col) _)
293 > move@(PlayMove piece pos@(f,_) pos' BigPawnMove) =
294 > Board (brd // [ pos =: VacantSq,
295 > pos' =: mkColBoardSq col piece ])
296 > (incMove mv) (Just f)
297 > makeAMove board@(Board brd mv@(MoveNumber _ col) _)
298 > move@(PlayMove piece pos@(f,_) pos' (Queening q)) =
299 > Board (brd // [ pos =: VacantSq,
300 > pos' =: mkColBoardSq col q])
301 > (incMove mv) (Just f)
302 > makeAMove board@(Board brd mv@(MoveNumber _ col) _) -- ASSERT ?
303 > move@(PlayMove piece (f,_) (f',_) EnPassant) =
304 > Board (brd // [ (f,st) =: VacantSq,
305 > (f',fn) =: mkColBoardSq col Pawn,
306 > (f',st) =: VacantSq ])
307 > (incMove mv) Nothing
308 > where (st,fn) = case col of
312 > makeACastleK (Board brd mv@(MoveNumber _ White) _) =
314 > [ (5,1) =: VacantSq,
315 > (6,1) =: mkColBoardSq White Rook,
316 > (7,1) =: mkColBoardSq White King,
317 > (8,1) =: VacantSq ]) (incMove mv) Nothing
318 > makeACastleK (Board brd mv@(MoveNumber _ Black) _) =
321 > [ (5,8) =: VacantSq,
322 > (6,8) =: mkColBoardSq Black Rook,
323 > (7,8) =: mkColBoardSq Black King,
324 > (8,8) =: VacantSq ]) (incMove mv) Nothing
325 > makeACastleQ (Board brd mv@(MoveNumber _ White) _) =
327 > [ (5,1) =: VacantSq,
328 > (4,1) =: mkColBoardSq White Rook,
329 > (3,1) =: mkColBoardSq White King,
330 > (1,1) =: VacantSq ]) (incMove mv) Nothing
331 > makeACastleQ (Board brd mv@(MoveNumber _ Black) _) =
333 > [ (5,8) =: VacantSq,
334 > (4,8) =: mkColBoardSq Black Rook,
335 > (3,8) =: mkColBoardSq Black King,
336 > (1,8) =: VacantSq ]) (incMove mv) Nothing
339 > disAmb (a,b) t@[(n,m),(x,y)]
340 > | n == x = userFormatRank b
341 > | otherwise = userFormatFile a
342 > disAmb src lst = error ("PANIC: cant disambiguate: " ++ show src ++ show lst)
344 > createShortMove :: PlayMove -> String -> Board -> String
345 > createShortMove (PlayMove Pawn (f,r) dest q) "" brd =
346 > (if lookupBoard brd dest == Baddy || EnPassant == q
347 > then userFormatFile f ++ "x" ++ userFormatBoardPos dest
348 > else userFormatBoardPos dest) ++
350 > Queening p -> "=" ++ userFormat p
352 > createShortMove (PlayMove p _ dest _) extra brd =
353 > userFormat p ++ extra ++ capt ++ userFormatBoardPos dest
355 > capt = if lookupBoard brd dest == Baddy
359 > getEPStart :: Colour -> ChessFile
360 > getEPStart White = 5
361 > getEPStart Black = 4
363 > getEPEnd :: Colour -> ChessFile
367 > getHomeRank :: Colour -> ChessRank
368 > getHomeRank White = 1
369 > getHomeRank Black = 8