|
module Datatypes.Unit (Unit(..), map, centeredIn, collidesWith, isOutsideOf, mergeWith) where
|
|
|
|
import Prelude hiding (map)
|
|
|
|
import Data.Hashable (Hashable(..))
|
|
import qualified Data.List as List
|
|
import Data.Set (Set)
|
|
import qualified Data.Set as Set
|
|
|
|
import Datatypes.Cell (Cell)
|
|
import Datatypes.Board (Board(..))
|
|
import qualified Datatypes.Board as Board
|
|
|
|
data Unit = Unit { pivot :: Cell, members :: Set Cell } deriving Show
|
|
|
|
instance Hashable Unit where
|
|
hashWithSalt salt unit = hashWithSalt salt (sortedMembers, pivot unit) where
|
|
sortedMembers = (List.sort . Set.toList . members) unit
|
|
|
|
map :: (Cell -> Cell) -> Unit -> Unit
|
|
map f (Unit p ms) = Unit (f p) (Set.map f ms)
|
|
|
|
centeredIn :: Unit -> Board -> Unit
|
|
centeredIn u@(Unit _ ms) b = map (\(x, y) -> (x + deltaX, y - unitTop)) u where
|
|
yCoords = Set.map (\(x, y) -> y) ms
|
|
xCoords = Set.map (\(x, y) -> x) ms
|
|
unitTop = Set.findMin yCoords
|
|
unitLeft = Set.findMin xCoords
|
|
unitRight = Set.findMax xCoords
|
|
deltaX = (unitLeft + (Board.width b - unitRight - 1)) `div` 2 - unitLeft
|
|
|
|
collidesWith :: Unit -> Board -> Bool
|
|
collidesWith u b = not . Set.null $ Set.intersection (members u) (Board.filled b)
|
|
|
|
isOutsideOf :: Unit -> Board -> Bool
|
|
isOutsideOf u@(Unit _ ms) b = any isOutside (Set.toList ms) where
|
|
isOutside (x, y) = x < 0 || x >= Board.width b || y < 0 || y >= Board.height b
|
|
|
|
mergeWith :: Unit -> Board -> Board
|
|
mergeWith unit board = board { filled = Set.union unitMembers boardFilled } where
|
|
unitMembers = members unit
|
|
boardFilled = Board.filled board
|