module Datatypes.Board (Board(..), clearLines) where
|
|
|
|
import Data.Set (Set)
|
|
import qualified Data.Set as Set
|
|
|
|
import Datatypes.Cell (Cell)
|
|
|
|
data Board = Board { width :: Int, height :: Int, filled :: Set Cell } deriving Show
|
|
|
|
empty :: Int -> Int -> Board
|
|
empty w h = Board w h Set.empty
|
|
|
|
clearLines :: Board -> (Board, Int)
|
|
clearLines b = let (newFilled, linesDeleted) = collectGarbage yCoords 0 (filled b)
|
|
in (b { filled = newFilled }, linesDeleted)
|
|
where
|
|
yCoords = Set.toList $ Set.map (\(x, y) -> y) (filled b)
|
|
countInLine l items = Set.size $ Set.filter (\(x, y) -> y == l) items
|
|
collectGarbage (l:ls) count items = if countInLine l items == (width b)
|
|
then collectGarbage ls (count + 1) (deleteLine l items)
|
|
else collectGarbage ls count items
|
|
collectGarbage [] count items = (items, count)
|
|
|
|
-- PRIVATE
|
|
|
|
deleteLine :: Int -> Set Cell -> Set Cell
|
|
deleteLine l cells = let updated = Set.filter (\(x, y) -> y /= l) cells
|
|
in Set.map (\(x, y) -> if y < l then (x, y + 1) else (x, y)) updated
|