-- Board.hs -- Tom Moertel -- CVS $Id: Board.hs,v 1.4 2002/09/06 04:03:51 thor Exp $ -- | The Board module represents the game board and provides -- types for board elements. module Board ( Point, Cell(..), Board(..) , readBoard, parseBoardLns, drawBoard, showBoard, boardSize ) where import Data.Array -- |Locations on the game board are represented as /x-y/ pairs type Point = (Int, Int) -- |A cell on the board may be plain, water, a wall, or a base data Cell = Plain | Water | Wall | Base deriving (Eq, Show, Read) -- |The game board is an NxM array of cells newtype Board = Board (Array Point Cell) deriving (Eq, Show, Read) -- |Reads a string representing a board and returns a Board readBoard :: String -> Board readBoard = fst . parseBoardLns . lines -- |Reads a series of lines, creates a Board from the leading lines, -- and returns the Board and any unused lines parseBoardLns :: [String] -- ^input lines -> (Board, [String]) -- ^output: board and unused lines parseBoardLns (l1:rest) = (board, rest') where [boardX, boardY] = map read . words $ l1 (boardLines, rest') = splitAt boardY rest board = Board . array ((1,1), (boardX, boardY)) . zip [(x,y) | y <- [1..boardY], x <- [1..boardX]] . map mkCell . filter (`elem` ".~#@") $ unlines boardLines parseBoardLns _ = error "parseBoardLns: invalid board specification" -- |Makes a Cell from its character representation mkCell :: Char -> Cell mkCell '.' = Plain mkCell '~' = Water mkCell '#' = Wall mkCell '@' = Base mkCell _ = error "mkCell: invalid cell specification" -- |Renders a boards as a string. drawBoard :: Board -> String drawBoard = unlines . reverse . drop 1 . lines . showBoard -- |Shows a Board. Note that @(@'readBoard'@ . @'showBoard'@)@ is an identity -- function for values of type Board. Also note that the board -- represention that 'showBoard' uses is upside down when viewed. -- This is according to the challenge task specification. Use 'drawBoard' -- for a visually correct rendering. showBoard :: Board -> String showBoard (Board barr) = unlines $ (show boardX ++ " " ++ show boardY) : groupsOf boardX cells where (_,(boardX,boardY)) = bounds barr cells = map (showCell . (barr!)) cellIndices cellIndices = [(x,y) | y <- [1..boardY], x <- [1..boardX]] -- |Shows a 'Cell' as a character. showCell :: Cell -> Char showCell Plain = '.' showCell Water = '~' showCell Wall = '#' showCell Base = '@' -- | Returns the size of the game board. boardSize :: Board -> Point boardSize (Board barr) = snd (bounds barr) -- |Collects items into groups of /n/. The last group may have -- fewer than /n/ items if the input list's length is not a -- multiple of /n/. groupsOf :: Int -- ^ desired group size /n/ -> [a] -- ^ input list -> [[a]] -- ^ output: list of groups groupsOf _ [] = [] groupsOf n xs = take n xs : groupsOf n (drop n xs) -- ================================================================= -- -- Copyright (C) 2002 Thomas Moertel. -- -- This program is free software; you can redistribute it and/or -- modify it under the terms of the GNU General Public License -- as published by the Free Software Foundation; either version 2 -- of the License, or (at your option) any later version. -- -- The text of the GNU GPL may be found in the LICENSE file, -- included with this software, or online at the following URL: -- -- http://www.gnu.org/copyleft/gpl.html -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- Except as provided for under the terms of the GNU GPL, all rights -- are reserved worldwide. -- -- =================================================================