Allow for random composition of trees

This commit is contained in:
2022-06-09 11:24:13 +01:00
parent 1f05c74abc
commit 1789a3785d
17 changed files with 103 additions and 88 deletions
-1
View File
@@ -11,7 +11,6 @@ import Dodge.Data
import Dodge.Annotation.Data
--import LensHelp
import Data.Tree
import Control.Monad.State
import System.Random
--import Control.Lens
+21
View File
@@ -0,0 +1,21 @@
module Dodge.Default.Prop where
import Dodge.Data
import Geometry
defaultProp :: Prop
defaultProp = Projectile
{ _prPos = V2 0 0
, _pjStartPos = V2 0 0
, _pjVel = V2 0 0
, _prDraw = const mempty
, _pjID = 0
, _pjUpdate = const id
}
defaultShapeProp :: Prop
defaultShapeProp = ShapeProp
{ _prPos = 0
, _pjID = 0
, _pjRot = 0
, _pjUpdate = const id
, _prDraw = const mempty
, _prToggle = True
}
-1
View File
@@ -25,7 +25,6 @@ import Dodge.Data
--import Dodge.RoomPos
--import Dodge.Room.RunPast
--import MonadHelp
import Data.Tree
import LensHelp
import Dodge.RandomHelp
--import Color
-1
View File
@@ -12,7 +12,6 @@ import Dodge.Tree
import Geometry.ConvexPoly
--import Dodge.LevelGen.LevelStructure
import Data.Tree
import System.Random
import Control.Lens
import Control.Monad.State
-1
View File
@@ -18,7 +18,6 @@ import Dodge.LevelGen.StaticWalls
import Geometry
import LensHelp
import Data.Tree
import Control.Monad.State
import System.Random
roomGlassOctogon
+2 -3
View File
@@ -14,15 +14,14 @@ import Dodge.Tree
import Control.Monad.State
import System.Random
import Data.Tree
branchRectWith :: RandomGen g => State g (SubCompTree Room) -> State g (SubCompTree Room)
branchRectWith t = do
x <- state $ randomR (100,200)
y <- state $ randomR (100,200)
b <- t
root <- shuffleLinks $ roomRectAutoLinks x y
return $ Node (PassDown root)
rt <- shuffleLinks $ roomRectAutoLinks x y
return $ Node (PassDown rt)
[ Node (UseAll door) []
, changeToPassDown <$> treeFromTrunk [PassDown door] b
]
-1
View File
@@ -20,7 +20,6 @@ import qualified Data.Set as S
import Control.Monad.State
--import Control.Monad.Loops
import System.Random
import Data.Tree
glassLesson :: RandomGen g => State g (SubCompTree Room)
glassLesson = do
i <- takeOne [1,2,3]
-1
View File
@@ -30,7 +30,6 @@ import Dodge.RandomHelp
import qualified Data.Set as S
import Data.Maybe
import Data.Tree
import Control.Monad.State
import System.Random
-1
View File
@@ -26,7 +26,6 @@ import LensHelp
--import Shape
import qualified Data.Set as S
import Data.Tree
import System.Random
import Control.Monad.State
import Data.Maybe
-2
View File
@@ -24,10 +24,8 @@ import LensHelp
import Data.Tile
import qualified Data.Set as S
import Data.Tree
import System.Random
import Control.Monad.State
--import Data.Tree
--import qualified Data.IntMap as IM
longRoom :: RandomGen g => State g Room
-1
View File
@@ -31,7 +31,6 @@ import LensHelp
import qualified Data.Set as S
--import Data.Maybe
import Data.Tree
import Control.Monad.State
import System.Random
+2 -3
View File
@@ -30,7 +30,6 @@ import qualified Data.Set as S
import Control.Monad.State
--import Control.Monad.Loops
import System.Random
import Data.Tree
import Data.Bifunctor
roomC :: RandomGen g => Float -> Float -> State g Room
@@ -278,7 +277,7 @@ weaponBetweenPillars = do
weaponLongCorridor :: RandomGen g => State g (SubCompTree Room)
weaponLongCorridor = do
root <- takeOne [tEast, tWest]
rt <- takeOne [tEast, tWest]
connectingRoom <- takeOne
[tEast & rmPmnts .~ [spanLightI (V2 (-30) 40) (V2 (-30) 80)]
]
@@ -286,7 +285,7 @@ weaponLongCorridor = do
i2 <- state $ randomR (2,5)
let branch1 = treeFromTrunk (replicate i1 $ PassDown corridorN) (singleUseAll $ putCrs connectingRoom)
let branch2 = treeFromTrunk (replicate i2 $ PassDown corridorN) (singleUseNone $ putWp corridor)
return $ Node (PassDown root) [branch1,branch2]
return $ Node (PassDown rt) [branch1,branch2]
where
putCrs = over rmPmnts (++ [sPS (V2 10 40) (-pi/2) randC1 ,sPS (V2 (-10) 40) (-pi/2) randC1 ])
putWp = set rmPmnts [sPS (V2 20 60) 0 $ RandPS randFirstWeapon ,spanLightI (V2 0 40) (V2 40 40)]
-1
View File
@@ -26,7 +26,6 @@ import Color
import LensHelp
import qualified Data.Set as S
import Data.Tree
import Control.Monad.State
import System.Random
--import qualified Data.IntMap.Strict as IM
+2 -2
View File
@@ -2,12 +2,12 @@
module Dodge.Tree
( module Dodge.Tree.Shift
, module Dodge.Tree.GenerateStructure
, module Dodge.Tree.Polymorphic
, module TreeHelp
, module Dodge.Tree.Compose
, module Dodge.Tree.Compose.Data
) where
import Dodge.Tree.Shift
import Dodge.Tree.GenerateStructure
import Dodge.Tree.Polymorphic
import TreeHelp
import Dodge.Tree.Compose
import Dodge.Tree.Compose.Data
+48 -35
View File
@@ -10,16 +10,19 @@ module Dodge.Tree.Compose
, changeToPassDown
, overwriteLabel
, applyToCompRoot
, composeTree
, composeTreeRand
-- , compTree
) where
import Dodge.Tree.Compose.Data
import Dodge.Tree.Polymorphic
import TreeHelp
import Dodge.Base
import LensHelp
import Control.Monad.State
import Data.Foldable
import System.Random
import Data.Maybe
import Data.Tree
import Data.Tree.Lens
--import Data.Bifunctor
expandTree :: CompTree a -> Tree a
expandTree (Node rt extChildren) = case rt of
@@ -32,11 +35,11 @@ expandTree (Node rt extChildren) = case rt of
$ map (:[]) extChildren ++ repeat []
applyToCompRoot :: (a -> a) -> SubCompTree a -> SubCompTree a
applyToCompRoot f = applyToRoot (unCompose %~ f)
applyToCompRoot f = over root (unCompose %~ f)
overwriteLabel :: Int -> (a -> ComposingNode a) -> SubCompTree a -> [SubCompTree a] -> SubCompTree a
overwriteLabel i f t ts = errorHead ("tried to overwriteLabel " ++ show i)
$ updateSingleNode islabel update t
$ updateSingleNodes islabel update t
where
islabel (UseLabel j _) | i == j = True
islabel _ = False
@@ -65,17 +68,27 @@ singleUseNone x = Node (UseNone x) []
changeToPassDown :: ComposingNode a -> ComposingNode a
changeToPassDown x = PassDown (_unCompose x)
--cTree :: Tree (a -> Maybe a, Tree a) -> Tree a
--cTree (Node (_,t) ch) = shiftChildren $ foldr g' (fdsa t) (map cTree ch)
composeTreeRand :: RandomGen g => Tree (a -> Maybe a, Tree a) -> State g (Tree a)
composeTreeRand (Node (_,t) ts) = attachListR t ts
cTree' :: Tree (a -> Maybe a, Tree a) -> Tree a
cTree' (Node (_,t) ts) = cTree t ts
attachListR :: RandomGen g => Tree a -> [Tree (a -> Maybe a, Tree a)] -> State g (Tree a)
attachListR t xs = fmap shiftChildren $ foldrM newfRand (fmap ([],) t) xs
cTree :: Tree a -> [Tree (a -> Maybe a, Tree a)] -> Tree a
cTree t xs = shiftChildren $ foldr newf (fmap ([],) t) xs
newfRand :: RandomGen g => Tree (a -> Maybe a,Tree a) -> Tree ([Tree a],a)
-> State g (Tree ([Tree a],a))
newfRand t = updateRandNode (isJust . upf . snd) ( (root . _2 %~ g) . (root . _1 .:~ composeTree t ) )
where
upf = (t ^?! root . _1)
g x = fromMaybe x (upf x)
composeTree :: Tree (a -> Maybe a, Tree a) -> Tree a
composeTree (Node (_,t) ts) = attachList t ts
attachList :: Tree a -> [Tree (a -> Maybe a, Tree a)] -> Tree a
attachList t xs = shiftChildren $ foldr newf (fmap ([],) t) xs
newf :: Tree (a -> Maybe a,Tree a) -> Tree ([Tree a],a) -> Tree ([Tree a],a)
newf t = safeUpdateSingleNode (isJust . upf . snd) ( (root . _2 %~ g) . (root . _1 .:~ cTree' t ) )
newf t = safeUpdateSingleNode (isJust . upf . snd) ( (root . _2 %~ g) . (root . _1 .:~ composeTree t ) )
where
upf = (t ^?! root . _1)
g x = fromMaybe x (upf x)
@@ -83,25 +96,25 @@ newf t = safeUpdateSingleNode (isJust . upf . snd) ( (root . _2 %~ g) . (root .
shiftChildren :: Tree ([Tree a],a) -> Tree a
shiftChildren (Node (ts,x) ts') = Node x (ts ++ map shiftChildren ts')
-- hideous, but it should work
-- the idea is that the fst argument selects (and edits) a node to which all the
-- children are attached
-- the tree is thus built up recursively
compTree :: Tree (a -> Maybe a, Tree (a,b)) -> Tree b
compTree (Node (_,t) ch) = attachChildren t $ map (\t' -> (fst $ rootLabel t',compTree t')) ch
chooseAttachNodes :: (a -> Maybe a,c) -> Tree (a,b,[c]) -> [Tree (a,b,[c])]
chooseAttachNodes (t,z) (Node (x,y,zs) ch) = case t x of
Just x' -> Node (x',y,(z:zs)) ch : concatMap (chooseAttachNodes (t,z)) ch
Nothing -> concatMap (chooseAttachNodes (t,z)) ch
mAttachToNode :: (a -> Maybe a,c) -> Tree (a,b,[c]) -> Tree (a,b,[c])
mAttachToNode p t = fromMaybe t $ listToMaybe $ chooseAttachNodes p t
moveToChildren :: Tree (a,b,[Tree b]) -> Tree b
moveToChildren (Node (_,x,ts) ts') = Node x (map moveToChildren ts' ++ ts)
attachChildren :: Tree (a,b) -> [(a->Maybe a,Tree b)] -> Tree b
attachChildren t = moveToChildren . foldr mAttachToNode t'
where
t' = fmap (\(x,y) -> (x,y,[])) t
---- hideous, but it should work
---- the idea is that the fst argument selects (and edits) a node to which all the
---- children are attached
---- the tree is thus built up recursively
--compTree :: Tree (a -> Maybe a, Tree (a,b)) -> Tree b
--compTree (Node (_,t) ch) = attachChildren t $ map (\t' -> (fst $ rootLabel t',compTree t')) ch
--
--chooseAttachNodes :: (a -> Maybe a,c) -> Tree (a,b,[c]) -> [Tree (a,b,[c])]
--chooseAttachNodes (t,z) (Node (x,y,zs) ch) = case t x of
-- Just x' -> Node (x',y,(z:zs)) ch : concatMap (chooseAttachNodes (t,z)) ch
-- Nothing -> concatMap (chooseAttachNodes (t,z)) ch
--
--mAttachToNode :: (a -> Maybe a,c) -> Tree (a,b,[c]) -> Tree (a,b,[c])
--mAttachToNode p t = fromMaybe t $ listToMaybe $ chooseAttachNodes p t
--
--moveToChildren :: Tree (a,b,[Tree b]) -> Tree b
--moveToChildren (Node (_,x,ts) ts') = Node x (map moveToChildren ts' ++ ts)
--
--attachChildren :: Tree (a,b) -> [(a->Maybe a,Tree b)] -> Tree b
--attachChildren t = moveToChildren . foldr mAttachToNode t'
-- where
-- t' = fmap (\(x,y) -> (x,y,[])) t
+2 -3
View File
@@ -10,7 +10,7 @@ module Dodge.Tree.Shift
--import Dodge.LevelGen.Data
import Dodge.Data
import Dodge.Room.Link
import Dodge.Tree.Polymorphic
import TreeHelp
import Dodge.RoomLink
import Geometry.ConvexPoly
--import Geometry.Data
@@ -19,7 +19,6 @@ import LensHelp hiding (Empty, (<|) , (|>))
--import Control.Lens hiding (Empty, (<|) , (|>))
import qualified Data.Set as S
import Data.Tree
import qualified Data.Sequence as Seq
import Data.List (delete)
import Data.Bifunctor
@@ -100,7 +99,7 @@ posRms prs parenti@(parent,_) ( (numChild,t@(Node childi _) ):its) tseq = do
, _rpLinkStatus = UsedInLink (_rlType il) (snd parenti)
, _rpPlacementUse = 0
}
shiftedt = applyToRoot
shiftedt = over root
(first $ updatechild . shiftRoomShiftToLink (lnkPosDir shiftedoutlink) (lnkPosDir il))
t
@@ -5,10 +5,11 @@ For example, in the tree
> Node a [ Node b [], Node c [Node d []] ]
the nodes in the trunk are [a,b] (note that d is not the first child of b).
the nodes in the trunk are [a,b].
-}
module Dodge.Tree.Polymorphic
( applyToRoot
module TreeHelp
( module Data.Tree
, module Data.Tree.Lens
, applyToSubtree
, applyToSubforest
, treeFromPost
@@ -17,7 +18,8 @@ module Dodge.Tree.Polymorphic
, applyToRandomNode
, addToTrunk
, inorderNumberTree
, updateSingleNode
, updateSingleNodes
, updateRandNode
, safeUpdateSingleNode
) where
import Dodge.RandomHelp
@@ -32,8 +34,7 @@ import Control.Lens
{- | Creates a linear tree.
Safe. -}
treeFromPost :: [a] -> a -> Tree a
treeFromPost [] y = Node y []
treeFromPost (x:xs) y = Node x [treeFromPost xs y]
treeFromPost xs = treeFromTrunk xs . pure
{- | Creates a tree with one trunk branch,
input as a list, that ends in another tree. -}
@@ -41,12 +42,9 @@ treeFromTrunk
:: [a] -- ^ The trunk
-> Tree a -- ^ The end of the tree
-> Tree a
treeFromTrunk [] t = t
treeFromTrunk (x:xs) t = Node x [treeFromTrunk xs t]
{- | Applies a function to the root of a tree. -}
applyToRoot :: (a -> a) -> Tree a -> Tree a
applyToRoot f (Node t ts) = Node (f t) ts
treeFromTrunk = flip $ foldr f
where
f x t = Node x [t]
-- find use for?
---- | Consider defining this using generalised recursion patterns
@@ -56,26 +54,22 @@ applyToRoot f (Node t ts) = Node (f t) ts
{- | Applies a function to a specific node determined by a list of indices.
Unsafe (partial function). -}
applyToNode :: [Int] -> (a -> a) -> Tree a -> Tree a
applyToNode [] f t = applyToRoot f t
applyToNode (i:is) f (Node x xs) = Node x (ys ++ [applyToNode is f z] ++ zs)
where
(ys, z:zs) = splitAt i xs
applyToNode is = applyToSubtree is . over root
{- | Applies a function to a specific subtree determined by a list of indices.
Unsafe (partial function). -}
applyToSubtree :: [Int] -> (Tree a -> Tree a) -> Tree a -> Tree a
applyToSubtree [] f t = f t
applyToSubtree (i:is) f (Node x xs) = Node x (ys ++ [applyToSubtree is f z] ++ zs)
where
(ys, z:zs) = splitAt i xs
applyToSubtree (i:is) f (Node x xs) = Node x (xs & ix i %~ applyToSubtree is f)
{- | Applies a function to a specific subforest determined by a list of indices.
Unsafe (partial function). -}
applyToSubforest :: [Int] -> ([Tree a] -> [Tree a]) -> Tree a -> Tree a
applyToSubforest [] f (Node p cs) = Node p (f cs)
applyToSubforest (i:is) f (Node x xs) = Node x (ys ++ [applyToSubforest is f z] ++ zs)
where
(ys, z:zs) = splitAt i xs
applyToSubforest is = applyToSubtree is . over branches
--applyToSubforest [] f (Node p cs) = Node p (f cs)
--applyToSubforest (i:is) f (Node x xs) = Node x (ys ++ [applyToSubforest is f z] ++ zs)
-- where
-- (ys, z:zs) = splitAt i xs
-- do not delete: find use for
--{- |
@@ -88,24 +82,25 @@ applyToSubforest (i:is) f (Node x xs) = Node x (ys ++ [applyToSubforest is f z]
--applyToSubTrunkBy _ _ t = t
-- gives the list of all updates to a single node
updateSingleNode :: (a -> Bool) -> (Tree a -> Tree a) -> Tree a -> [Tree a]
updateSingleNode f update t@(Node x ts)
-- there must be a better way of doing something like this
updateSingleNodes :: (a -> Bool) -> (Tree a -> Tree a) -> Tree a -> [Tree a]
updateSingleNodes f update t@(Node x ts)
| f x = update t : updateChildren
| otherwise = updateChildren
where
updateChildren = map (Node x) (subMap (updateSingleNode f update) ts)
updateChildren = map (Node x) (subMap (updateSingleNodes f update) ts)
updateRandNode :: RandomGen g => (a -> Bool) -> (Tree a -> Tree a) -> Tree a -> State g (Tree a)
updateRandNode t f = takeOne . updateSingleNodes t f
safeUpdateSingleNode :: (a -> Bool) -> (Tree a -> Tree a) -> Tree a -> Tree a
safeUpdateSingleNode f g t = fromMaybe t $ listToMaybe $ updateSingleNode f g t
safeUpdateSingleNode f g t = fromMaybe t $ listToMaybe $ updateSingleNodes f g t
subMap :: (a -> [a]) -> [a] -> [[a]]
subMap f (x:xs) = (f x <&> (: xs)) ++ ( (x :) <$> subMap f xs )
subMap _ [] = []
--subMap' :: Monad m => (a -> m a) -> [a] -> m [a]
--subMap' f (x:xs) = (f x <&> (: xs)) ++ ( (x :) <$> (subMap f xs) )
--subMap' f [] =
-- find use for?
--zipTree :: Tree a -> Tree b -> Tree (a,b)
--zipTree (Node x xs) (Node y ys) = Node (x,y) $ zipWith zipTree xs ys