module Server.Map where import qualified Data.Matrix as M import System.Random import Library.Types import Server.Map.Snippets -- | This function procedurally generates the Arena for the game generateArena :: Int -- ^ Map's width -> Int -- ^ Map's height -> Float -- ^ Probability for a tile to be an item spawner -> IO Arena -- ^ resulting Arena generateArena arenaWidth arenaHeight spawnerChance = do undefined -- | Generate basic Map of Air and Walls generateMap :: Int -- ^ Map's width -> Int -- ^ Map's height -> IO Map -- ^ resulting Map generateMap mapWidth mapHeight = do let initMap = M.matrix mapHeight mapWidth (const Air) divide 0 0 mapHeight mapWidth initMap where divide :: Int -> Int -> Int -> Int -> Map -> IO Map divide rowOffset colOffset rowSize colSize tilemap | rowSize <= 3 || colSize <= 3 = pure tilemap | otherwise = do -- position wall intersection at random crossRow <- randomRIO (2, rowSize - 1) crossCol <- randomRIO (2, colSize - 1) -- position wall passages at random wall tiles rowHole1 <- randomRIO (1, crossRow - 1) rowHole2 <- randomRIO (crossRow + 1, rowSize - 1) colHole1 <- randomRIO (1, crossCol - 1) colHole2 <- randomRIO (crossCol + 1, colSize - 1) -- determine all possible passages let allHoles = [ (rowHole1, crossCol) , (rowHole2, crossCol) , (crossRow, colHole1) , (crossRow, colHole2) ] -- drop one of the passages randomly randomDropIndex <- randomRIO (0, length allHoles - 1) let randomDrop = allHoles !! randomDropIndex holes = filter (/= randomDrop) allHoles crossedMap = M.mapPos (\(r, c) tile -> if (r - rowOffset == crossRow && c - colOffset > 0 && c - colOffset <= colSize) || (c - colOffset == crossCol && r - rowOffset > 0 && r - rowOffset <= rowSize) then if (r - rowOffset, c - colOffset) `elem` holes then Air else Wall else tile ) tilemap divide rowOffset colOffset (crossRow - 1) (crossCol - 1) =<< divide rowOffset (colOffset + crossCol + 1) (crossRow - 1) (colSize - crossCol - 1) =<< divide (rowOffset + crossRow + 1) colOffset (rowSize - crossRow - 1) (crossCol - 1) =<< divide (rowOffset + crossRow + 1) (colOffset + crossCol + 1) (rowSize - crossRow - 1) (colSize - crossCol - 1) crossedMap