Display abstract tree of placement, stout

This commit is contained in:
2021-11-11 18:41:59 +00:00
parent da22d9833a
commit 8c45a02e46
4 changed files with 48 additions and 76 deletions
+23 -4
View File
@@ -105,14 +105,18 @@ initialRoomTree = do
layoutLevelFromSeed :: Int -> IO [Room] layoutLevelFromSeed :: Int -> IO [Room]
layoutLevelFromSeed seed = do layoutLevelFromSeed seed = do
putStrLn $ "Generating level with seed: " ++ show seed putStrLn $ "Generating level with seed " ++ show seed
let g = mkStdGen seed let g = mkStdGen seed
let rmtree = evalState initialRoomTree g let rmtree = inorderNumberTree $ evalState initialRoomTree g
putStrLn "Seed layout: "
putStrLn $ compactDrawTree $ fmap (show . snd) rmtree
mrs <- positionRooms rmtree mrs <- positionRooms rmtree
case mrs of case mrs of
Just rs -> return (fmap setLastLinkToUsed rs) Just rs -> do
putStrLn $ "Successful generation of level with seed " ++ show seed
return (fmap setLastLinkToUsed rs)
Nothing -> do Nothing -> do
putStrLn "Level generation failed" putStr $ "Level generation with seed " ++ show seed ++ " failed: "
let (seed',_) = random g let (seed',_) = random g
layoutLevelFromSeed seed' layoutLevelFromSeed seed'
where where
@@ -121,3 +125,18 @@ layoutLevelFromSeed seed = do
& rmLinks %~ init & rmLinks %~ init
& rmUsedLinks %~ (last (_rmLinks rm) :) & rmUsedLinks %~ (last (_rmLinks rm) :)
_ -> rm _ -> rm
compactDrawTree :: Tree String -> String
compactDrawTree = unlines . compactDraw
compactDraw :: Tree String -> [String]
compactDraw (Node x [Node y ts]) = compactDraw (Node (x++","++y) ts)
compactDraw (Node x ts0) = lines x ++ drawSubTrees ts0
where
drawSubTrees [] = []
drawSubTrees [t] =
"|" : compactDraw t
drawSubTrees (t:ts) =
"|" : shift "+- " "| " (compactDraw t) ++ drawSubTrees ts
shift first other = zipWith (++) (first : repeat other)
+1 -1
View File
@@ -27,7 +27,7 @@ firstWorld = do
-- putStrLn $ "Had to go through "++ show n ++ " random generators" -- putStrLn $ "Had to go through "++ show n ++ " random generators"
roomList <- layoutLevelFromSeed i roomList <- layoutLevelFromSeed i
return $ generateLevelFromRoomList roomList return $ generateLevelFromRoomList roomList
$ initialWorld -- note this uses a random generator defined elsewhere initialWorld -- note this uses a random generator defined elsewhere
initialWorld :: World initialWorld :: World
initialWorld = defaultWorld initialWorld = defaultWorld
+4 -4
View File
@@ -14,7 +14,7 @@ module Dodge.Layout.Tree.Polymorphic
, splitTrunk , splitTrunk
, applyToRandomNode , applyToRandomNode
, addToTrunk , addToTrunk
, bfnumberTree , inorderNumberTree
) )
where where
import Dodge.RandomHelp import Dodge.RandomHelp
@@ -145,8 +145,8 @@ splitTrunk t = do
return $ splitTrunkAt i t return $ splitTrunkAt i t
-- untested -- untested
bfnumberTree :: Tree a -> Tree (a,Int) inorderNumberTree :: Tree a -> Tree (a,Int)
bfnumberTree = fst . f 0 inorderNumberTree = fst . f 0
where where
f i (Node x ts) = f i (Node x ts) =
let (ts',i') = g (i+1) ts let (ts',i') = g (i+1) ts
@@ -154,5 +154,5 @@ bfnumberTree = fst . f 0
g i (t:ts) = g i (t:ts) =
let (t',i') = f i t let (t',i') = f i t
(ts',i'') = g i' ts (ts',i'') = g i' ts
in ((t': ts'), i'') in (t': ts', i'')
g i [] = ([], i) g i [] = ([], i)
+16 -63
View File
@@ -5,19 +5,17 @@ Returns a list; after this step the structure is determined by the actual positi
-} -}
module Dodge.Layout.Tree.Shift module Dodge.Layout.Tree.Shift
( shiftRoomTreeSearchAll ( shiftRoomTreeSearchAll
, shiftExpandTree
, positionRooms , positionRooms
) where ) where
import Dodge.Room.Data import Dodge.Room.Data
import Dodge.Room.Link import Dodge.Room.Link
import Dodge.Layout.Tree.Polymorphic import Dodge.Layout.Tree.Polymorphic
import Geometry.ConvexPoly import Geometry.ConvexPoly
import Geometry
import Data.Tree import Data.Tree
import Data.Sequence hiding (zipWith) import Data.Sequence hiding (zipWith)
import Data.List (delete) import Data.List (delete)
import Data.Maybe (listToMaybe) --import Data.Maybe (listToMaybe)
import Data.Bifunctor import Data.Bifunctor
import Control.Lens hiding (Empty, (<|) , (|>)) import Control.Lens hiding (Empty, (<|) , (|>))
@@ -45,11 +43,8 @@ shiftRoomTreeSearchAll bs (Node r ts :<| tseq)
& rmUsedLinks %~ (l :) & rmUsedLinks %~ (l :)
f l = applyToRoot (shiftRoomToLink l) f l = applyToRoot (shiftRoomToLink l)
positionRooms :: Tree Room -> IO (Maybe [Room]) positionRooms :: Tree RoomInt -> IO (Maybe [Room])
--positionRooms = shiftRoomSearchIO 0 [] . singleton positionRooms (Node (r,i) ts) = posRms (map pointsToPoly $ _rmBound r) (r,i) ts Empty
positionRooms t =
let (Node (r,i) ts) = bfnumberTree t
in posRms (map pointsToPoly $ _rmBound r) (r,i) ts Empty
type RoomInt = (Room,Int) type RoomInt = (Room,Int)
@@ -60,74 +55,32 @@ posRms
-> Seq (Tree RoomInt) -> Seq (Tree RoomInt)
-> IO (Maybe [Room]) -> IO (Maybe [Room])
posRms _ _ [] Empty = return $ Just [] posRms _ _ [] Empty = return $ Just []
posRms bounds (rtoadd,_) [] (Node (r,i) ts :<| tseq) = fmap (fmap (rtoadd:)) $ posRms bounds (r,i) ts tseq posRms bounds (rtoadd,_) [] (Node (r,i) ts :<| tseq) = fmap (setLastLinkToUsed rtoadd:) <$> posRms bounds (r,i) ts tseq
posRms bounds (r,i) (t:ts) tseq = tryLinks' (_rmLinks r) posRms bounds (r,i) (t@(Node (_,i') _):ts) tseq = do
putStr $ "Trying to place room " ++ show i' ++ ": "
tryLinks' (0::Int) (_rmLinks r)
where where
tryLinks' [] = do tryLinks' _ [] = do
putStrLn "All links tried" putStrLn "all links tried"
return Nothing return Nothing
tryLinks' (l:ls) tryLinks' j (l:ls)
| clipping = tryLinks' ls | clipping = tryLinks' (j+1) ls
| otherwise = do | otherwise = do
putStrLn $ "Trying link from " ++ show i ++ " to " ++ show i' putStrLn $ "placing at link " ++ show j
mayrs <- posRms (convexBounds ++ bounds) useLink ts (tseq |> shiftedt) mayrs <- posRms (convexBounds ++ bounds) useLink ts (tseq |> shiftedt)
case mayrs of case mayrs of
Nothing -> do putStrLn ("Backtracking to " ++ show i) >> tryLinks' ls Nothing -> do putStr ("Backtracking to room " ++ show i' ++ ": ") >> tryLinks' (j+1) ls
Just rs -> return (Just rs) Just rs -> return (Just rs)
where where
convexBounds = map pointsToPoly $ _rmBound r' convexBounds = map pointsToPoly $ _rmBound r'
clipping = or (convexPolysOverlap <$> convexBounds <*> bounds) clipping = or (convexPolysOverlap <$> convexBounds <*> bounds)
useLink = (r & rmLinks %~ delete l & rmUsedLinks %~ (l :) useLink = (r & rmLinks %~ delete l & rmUsedLinks %~ (l :)
, i) , i)
shiftedt@(Node (r',i') _) = applyToRoot (first $ shiftRoomToLink l) t shiftedt@(Node (r',_) _) = applyToRoot (first $ shiftRoomToLink l) t
shiftRoomSearchIO setLastLinkToUsed :: Room -> Room
:: Int setLastLinkToUsed rm = case _rmLinks rm of
-> [ConvexPoly]
-> Seq (Tree Room)
-> IO (Maybe [Room])
shiftRoomSearchIO _ _ Empty = return (Just [])
shiftRoomSearchIO i bs (Node r ts :<| tseq)
| roomIsClipping = do
putStrLn $ "Room " ++ show i ++ " clipping"
return Nothing
| otherwise = fmap (fmap (r:)) $ placeLinkedRooms i newBounds r ts tseq
where
convexBounds = map pointsToPoly $ _rmBound r
newBounds = convexBounds ++ bs
roomIsClipping = or (convexPolysOverlap <$> convexBounds <*> bs)
placeLinkedRooms :: Int -> [ConvexPoly] -> Room -> [Tree Room] -> (Seq (Tree Room)) -> IO (Maybe [Room])
placeLinkedRooms i bs _ [] tseq
= shiftRoomSearchIO (i+1) bs tseq
placeLinkedRooms i bs r (t:ts) tseq
= tryLinks i ls bs r t ts tseq
where
ls = init $ _rmLinks r
tryLinks :: Int
-> [(Point2,Float)] -> [ConvexPoly] -> Room -> Tree Room -> [Tree Room] -> (Seq (Tree Room))
-> IO (Maybe [Room])
tryLinks i [] _ _ _ _ _ = do
putStrLn $ "Tried all links for room " ++ show i
return Nothing
tryLinks i (l:ls) bs r t ts tseq = do
branch <- placeLinkedRooms i bs useLink ts (tseq |> shiftedt)
case branch of
Nothing -> tryLinks i ls bs r t ts tseq
Just rs -> return $ Just rs
where
useLink = r & rmLinks %~ delete l
& rmUsedLinks %~ (l :)
shiftedt = applyToRoot (shiftRoomToLink l) t
{- |
Depth first search of trees of rooms, maybe produces a list rooms that are not clipping.
-}
shiftExpandTree :: Tree Room -> Maybe [Room]
shiftExpandTree = fmap (map setLastLinkToUsed) . listToMaybe . shiftRoomTreeSearchAll [] . singleton
where
setLastLinkToUsed rm = case _rmLinks rm of
(_:_) -> rm (_:_) -> rm
& rmLinks %~ init & rmLinks %~ init
& rmUsedLinks %~ (last (_rmLinks rm) :) & rmUsedLinks %~ (last (_rmLinks rm) :)