% Filename: ChessSetList.lhs
% Version : 1.4
% Date : 3/4/92
\section{Building Chess Boards Out Of Lists.}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%M O D U L E%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Lots of data abstraction is used in this version of the knights tour. The
searching mechanism can be either a sequential depth first search, or a
data parallel search (for instance wedge first??). This module
abstracts data type specific operations used in the Heuristic part of the tour.
\begin{code}
module ChessSetList(Tile,
ChessSet,
createBoard,
sizeBoard,
addPiece,
deleteFirst,
noPieces,
positionPiece,
lastPiece,
firstPiece,
pieceAtTile,
isSquareFree
) where
\end{code}
%%%%%%%%%%%%%%%%%% I M P O R T S / T Y P E D E F S %%%%%%%%%%%%%%
@Tile@ is a type synonym that represents the $(x,y)$ coordinates of a
tile on chess board. The chess board is represented as an algebraic
data type\footnote{And hence we can include it in class @Text@, making it
@show@able} of an :
\begin{itemize}
\item {\tt Int} representing the size of the chess board.
\item {\tt Int} representing the current move number.
\item {\tt Tile} representing the first move of the knight.
\item {\tt [Tile]} representing the trail of the knights moves, where the
$n^{th}$ tile from the back of the list represents the $n^{th}$ move.
\end{itemize}
We include information in this type that could of been deduced from the
trail alone, but adding the information prevents
unnecessary traversal of the trail.
\begin{code}
import Sort(quickSort)
type Tile = (Int,Int)
data ChessSet = Board Int Int Tile [Tile]
\end{code}
%%%%%%%%%%%%%%%%%%%% C L A S S I N S T A N C E S %%%%%%%%%%%%%%%%%%%
Various instance declarations for @show@ , @==@ and @<=@. Note the little
hack with ordinals, we do not want to compare chess sets, but if we have
for instance a tuple of @(Int,ChessSet)@, then we want to compare on the
@Int@ part of the tuple. Therefore {\em any} @ChessSet@ is smaller than any
other.
\begin{code}
instance Eq ChessSet where
_ == _ = True
instance Ord ChessSet where
_ <= _ = True
instance Show ChessSet where
showsPrec p board@(Board sze n f ts)
= showString (printBoard sze sortedTrail 1)
where
sortedTrail = quickSort
(assignMoveNo ts sze n)
\end{code}
%%%%%%%%%%%%%%%%%%%%% B O D Y O F M O D U L E %%%%%%%%%%%%%%%%%%%%%
\begin{code}
createBoard::Int -> Tile -> ChessSet
createBoard x t= Board x 1 t [t]
sizeBoard::ChessSet -> Int
sizeBoard (Board s _ _ _) = s
noPieces::ChessSet -> Int
noPieces (Board _ n _ _) = n
addPiece::Tile -> ChessSet -> ChessSet
addPiece t (Board s n f ts) = Board s (n+1) f (t:ts)
\end{code}
@deletePiece@ deletes the $x^{th}$ piece placed on the board, and
depending on the representation ensures the remaining trail is valid
(i.e info reguarding position in valid).
\begin{code}
deleteFirst::ChessSet -> ChessSet
deleteFirst (Board s n f ts) = Board s (n-1) (last ts') ts'
where
ts' = init ts
positionPiece::Int -> ChessSet -> Tile
positionPiece x (Board _ n _ ts) = ts !! (n - x)
lastPiece::ChessSet -> Tile
lastPiece (Board _ _ _ (t:ts)) = t
firstPiece::ChessSet -> Tile
firstPiece (Board _ _ f _) = f
pieceAtTile::Tile -> ChessSet -> Int
pieceAtTile x (Board _ _ _ ts)
= find x ts
where
find x [] = error "Tile not used"
find x (y:xs)
| x == y = 1 + length xs
| otherwise = find x xs
isSquareFree::Tile -> ChessSet -> Bool
isSquareFree x (Board _ _ _ ts) = x `notElem` ts
\end{code}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% M I S C %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Various auxiliary functions used above which I would of liked to
include in @where@ clauses if they were not so large.
\begin{code}
assignMoveNo [] size x
= []
assignMoveNo ((x,y):t) size z
=(((y-1)*size)+x,z):assignMoveNo t size (z-1)
printBoard s [] n
| (n > (s*s)) = ""
| (n `mod` s /=0)= "*"++(spaces (s*s) 1) ++(printBoard s [] (n+1))
| (n `mod` s ==0)= "*\n" ++(printBoard s [] (n+1))
printBoard s trail@((i,j):xs) n
| (i==n) &&
(n `mod` s ==0)= (show j)++"\n"++(printBoard s xs (n+1))
| (i==n) &&
(n `mod` s /=0)= (show j)++(spaces (s*s) j)++(printBoard s xs (n+1))
| (n `mod` s /=0)= "*" ++(spaces (s*s) 1)++(printBoard s trail (n+1))
| (n `mod` s ==0)= "*\n" ++(printBoard s trail (n+1))
spaces s y = take ((logTen s) - (logTen y) + 1) [' ',' '..]
where
logTen 0 = 0
logTen x = 1+ logTen (x `div` 10)
\end{code}
|