module World.Lattice ( LatticeCell (..) , Lattice , LatticeRule , updateLattice , applyLatticeProposals ) where import World.Types (Combinable (..) , LatticeProposal (..) , LatticePropList (..) ) data LatticeCell a b = LatticeCell { kind :: a, flags :: b } deriving (Show, Eq) type Lattice a b = [[LatticeCell a b]] type LatticeRule a b = Lattice a b -> Int -> Int -> LatticeCell a b updateLattice :: (Enum a) => Lattice a b -> [LatticeRule a b] -> Lattice a b updateLattice lattice rules = let mapRow = \(row, y) -> map (\((LatticeCell k _), x) -> let rule = rules !! (fromEnum k) in rule lattice x y ) (zip row [0..]) in map mapRow (zip lattice [0..]) applyLatticeProposals :: (Combinable b) => Lattice a b -> LatticePropList a b -> Lattice a b applyLatticeProposals lattice (LatticePropList props) = let update list idx new = let (front, _:back) = splitAt idx list in front ++ (new:back) applyProp l (LatticeProposal (x, y) from to flags) = let row = l !! y cell = row !! x cell' = LatticeCell to (combine flags $ cellFlags cell) in update l y (update row x cell') -- replace each cell's flags with the identity lattice' = map (\row -> map (\cell -> cell { flags = identity } ) row ) lattice in foldl applyProp lattice' props