private void GenerateTree(MT19337 rng) { root = new BSPMapNode(0, 0, MapRequirements.Width, MapRequirements.Height); all_nodes = new List <BSPMapNode> { root }; leaf_nodes = new HashSet <BSPMapNode> { root }; while (true) { var new_leafs = new List <BSPMapNode>(); foreach (var split_leaf in leaf_nodes.ToList(). Where(l => l.Width > MAX_LEAF_SIZE || l.Height > MAX_LEAF_SIZE || rng.Between(0, 3) < 3). // always split if too big, or on a 3/4 chance. Where(l => l.Split(rng))) // only select leafs that actually successfully split { // if we did split, add the new leafs to the list new_leafs.Add(split_leaf.LeftChild); new_leafs.Add(split_leaf.RightChild); leaf_nodes.Remove(split_leaf); } if (new_leafs.Count == 0) { break; } all_nodes.AddRange(new_leafs); leaf_nodes.UnionWith(new_leafs); } }
public bool Split(MT19337 rng) { // begin splitting the leaf into two children if (LeftChild != null || RightChild != null) { return(false); // we're already split! Abort! } // determine direction of split // if the width is >25% larger than height, we split vertically // if the height is >25% larger than the width, we split horizontally // otherwise we split randomly bool split_horizontally; if (Width > Height && Width / Height >= 1.25) { split_horizontally = false; } else if (Height > Width && Height / Width >= 1.25) { split_horizontally = true; } else { split_horizontally = rng.Between(0, 1) == 0; } int max = (split_horizontally ? Height : Width) - BSPTreeEngine.MIN_LEAF_SIZE; // determine the maximum height or width if (max <= BSPTreeEngine.MIN_LEAF_SIZE) { return(false); // the area is too small to split any more... } int split = rng.Between(BSPTreeEngine.MIN_LEAF_SIZE, max); // determine where we're going to split // create our left and right children based on the direction of the split if (split_horizontally) { LeftChild = new BSPMapNode(X, Y, Width, split); RightChild = new BSPMapNode(X, Y + split, Width, Height - split); } else { LeftChild = new BSPMapNode(X, Y, split, Height); RightChild = new BSPMapNode(X + split, Y, Width - split, Height); } return(true); // split successful! }