% vim: set tw=72: % Part of Hetris \section{Global datatypes}\label{sec:data} There are many points at which we could begin our design of the program. For example, we could start with the user interface and work down to the logic of the game, working through the modules as we explore deeper; another possibility would be to start at the deep logic and work outwards. However, it seems logical to instead start with what one might call global datatypes. The problem we are trying to solve is how information is passed from one module to another, either as an argument to a function or as the result of one. Hiding the details with data abstraction is not the effect we want here---we are trying to \emph{share} the actual information, not simply allow other modules to pass it around. We could, with a minimum of legerdemain, make any of these types ``owned'' by the most appropriate module. However, we would not be being honest with ourselves if we did this---these types really belong, conceptually speaking, to the channels by which modules communicate. There are four types that come into this category; as they just require definitions it does not make seem worth the hassle to split them off into four tiny modules, so instead we bundle them together into this single module. The module export information is shown below, followed by an explanation of each of the four types. \begin{code} module Data (Delay, Vector, Event(..), Change(..)) where \end{code} \subsection{Delay} % XXX Should this be typeset differently? At the very heart of the game is a clock ticking away. On each tick either the active piece is moved down or, if this is not possible, its component blocks are added to the board and a new piece is made active. The time between these clock ticks is a policy decision---as far as the mechanism modules are concerned it need not even necessarily be constant---so it should be set by the \hsmodule{Main} module. However, the user interface will need to stop waiting for input after this time has elapsed, so it needs to know the value too. We therefore make it a globally known type. We will allow modules using the type to assume that it is an instance of the \hsclass{Integral} class, counting the time until the next tick in milliseconds; this means the \hstype{Int} type should be sufficiently wide to hold all the values we care about. \begin{code} type Delay = Int \end{code} \subsection{Vector} % XXX Should this be typeset differently? We need to talk about positions, widths and heights on and of the playing area all over the place. For example, the policy module \hsmodule{Main} will need to agree on a size, i.e., width and height, that the mechanism module \hsmodule{UI} can display. For an example of when positions on the playing area need to be passed around consider what happens when the playing area is altered and the user interface needs to be updated accordingly. We could always pass around lists of lists, say, to describe the current state of the board to the user interface, but it is more efficient to pass around a list of changes which describe a change of a particular square, i.e., a position, on the playing area. We can use the same type for talking about both positions and the width and height of the board, so we would like a name that conveys the impression that its value may be either a length or position; for lack of a better word we choose \hstype{Vector}. Again it makes sense if we allow ourselves to assume that the type is an instance of class \hsclass{Integral}, and again \hstype{Int} should be easily wide enough for our purposes. \begin{code} type Vector = Int \end{code} A value of 0 refers to the the uppermost or leftmost cell as appropriate if the \hstype{Vector} is referring to a position. \subsection{Event} % XXX Should this be typeset differently? The user interface will need to communicate with the policy module to inform it of events that have happened. We don't want to pass low level things like what key was pressed around, not least because this precludes interfaces that don't work in this way, e.g., mouse driven interfaces. Instead we use an abstract datatype \hstype{Event} where each constructor corresponds to one of the possible events that can occur. \begin{code} data Event = RotL | RotR | MDown | MLeft | MRight | Drop | Tick | Quit | None deriving Eq \end{code} We derive Eq as it will allow us to use slightly simpler code later on. The meaning of each constructor is as follows: \bigskip\noindent \begin{tabularx}{\hsize}{@{\hspace{2em}}X@{}} \omit\hsconstructor{RotL}, \hsconstructor{RotR}, \hsconstructor{MDown}, \hsconstructor{MLeft}, \hsconstructor{MRight}\hfil\smallskip\cr These correspond to requests to rotate the active piece left or right or move it down, left or right respectively.\medskip\cr \omit\hsconstructor{Drop}\hfil\smallskip\cr Corresponds to a request to drop the piece as far down as possible, i.e., equivalent to multiple \hsconstructor{MDown} events.\medskip\cr \omit\hsconstructor{Tick}\hfil\smallskip\cr This event occurs when the time until the next clock tick hits zero.\medskip\cr \omit\hsconstructor{Quit}\hfil\smallskip\cr The user has requested the program to quit.\medskip\cr \omit\hsconstructor{None}\hfil\smallskip\cr This is not a real event; it will be created when, for example, a user presses a key that is not bound to any real event. Its purpose is simply to make things more convenient for us in some circumstances.\medskip\cr \end{tabularx} \subsection{Change} % XXX Should this be typeset differently? As we briefly mentioned earlier, changes in the playing area need to be sent to the user interface module. In this simplified specification of the game there are three things we will want to be able to do. First we may want to turn a given square on the board on. Second we may want to turn a square off. Finally, after deleting a complete row we may want to pause briefly for the user to be able to see what has happened; the amount of time we should wait is a look-and-feel issue, so we leave it up to the user interface to decide. These map fairly directly to an abstract datatype as shown: \begin{code} data Change = On Vector Vector | Off Vector Vector | Delay \end{code} The two \hstype{Vector}s used by the \hsconstructor{On} and \hsconstructor{Off} constructors are $x$ and $y$ coordinates respectively.