From 32dd74415fde7ebda69388b8a7570756dba03e93 Mon Sep 17 00:00:00 2001 From: Justin Aquadro Date: Fri, 13 May 2011 06:12:40 +0000 Subject: [PATCH] Adding random 3D maze generator example --- .../SubstrateCS/Examples/Maze/Maze.csproj | 94 +++++ .../SubstrateCS/Examples/Maze/Program.cs | 352 ++++++++++++++++++ .../Examples/Maze/Properties/AssemblyInfo.cs | 36 ++ 3 files changed, 482 insertions(+) create mode 100644 Substrate/SubstrateCS/Examples/Maze/Maze.csproj create mode 100644 Substrate/SubstrateCS/Examples/Maze/Program.cs create mode 100644 Substrate/SubstrateCS/Examples/Maze/Properties/AssemblyInfo.cs diff --git a/Substrate/SubstrateCS/Examples/Maze/Maze.csproj b/Substrate/SubstrateCS/Examples/Maze/Maze.csproj new file mode 100644 index 0000000..27cb739 --- /dev/null +++ b/Substrate/SubstrateCS/Examples/Maze/Maze.csproj @@ -0,0 +1,94 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {62D70576-FE3A-4530-B283-889C14B52E9E} + Exe + Properties + Maze + Maze + v4.0 + 512 + + + + + 3.5 + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + False + ..\..\bin\Release\Substrate.dll + + + + + + + + + + False + Microsoft .NET Framework 4 %28x86 and x64%29 + true + + + False + .NET Framework 3.5 SP1 Client Profile + false + + + False + .NET Framework 3.5 SP1 + false + + + False + Windows Installer 3.1 + true + + + + + \ No newline at end of file diff --git a/Substrate/SubstrateCS/Examples/Maze/Program.cs b/Substrate/SubstrateCS/Examples/Maze/Program.cs new file mode 100644 index 0000000..4d7c40c --- /dev/null +++ b/Substrate/SubstrateCS/Examples/Maze/Program.cs @@ -0,0 +1,352 @@ +using System; +using System.Collections.Generic; +using Substrate; + +namespace Maze +{ + class Program + { + static void Main (string[] args) + { + BetaWorld world = BetaWorld.Open("F:\\Minecraft\\test"); + BlockManager bm = world.GetBlockManager(); + + bm.AutoLight = false; + + Grid grid = new Grid(); + grid.BuildInit(bm); + + Generator gen = new Generator(); + List edges = gen.Generate(); + + foreach (Generator.Edge e in edges) { + int x1; + int y1; + int z1; + gen.UnIndex(e.node1, out x1, out y1, out z1); + + int x2; + int y2; + int z2; + gen.UnIndex(e.node2, out x2, out y2, out z2); + + grid.LinkRooms(bm, x1, y1, z1, x2, y2, z2); + } + + // Entrance Room + grid.BuildRoom(bm, 2, 5, 2); + grid.LinkRooms(bm, 2, 5, 2, 1, 5, 2); + grid.LinkRooms(bm, 2, 5, 2, 3, 5, 2); + grid.LinkRooms(bm, 2, 5, 2, 2, 5, 1); + grid.LinkRooms(bm, 2, 5, 2, 2, 5, 3); + grid.LinkRooms(bm, 2, 4, 2, 2, 5, 2); + + // Exit Room + grid.BuildRoom(bm, 2, -1, 2); + grid.LinkRooms(bm, 2, -1, 2, 2, 0, 2); + grid.AddPrize(bm, 2, -1, 2); + + Console.WriteLine("Relight Chunks"); + + ChunkManager cm = world.GetChunkManager(); + cm.RelightDirtyChunks(); + + world.Save(); + } + + } + + class Grid + { + int originx; + int originy; + int originz; + + int xlen; + int ylen; + int zlen; + + int cellxlen; + int cellylen; + int cellzlen; + int wallxwidth; + int wallywidth; + int wallzwidth; + + public Grid () + { + originx = 0; + originy = 27; + originz = 0; + + xlen = 5; + ylen = 5; + zlen = 5; + + cellxlen = 5; + cellylen = 5; + cellzlen = 5; + wallxwidth = 2; + wallywidth = 2; + wallzwidth = 2; + } + + public void BuildInit (BlockManager bm) + { + for (int xi = 0; xi < xlen; xi++) { + for (int yi = 0; yi < ylen; yi++) { + for (int zi = 0; zi < zlen; zi++) { + BuildRoom(bm, xi, yi, zi); + } + } + } + } + + public void BuildRoom (BlockManager bm, int x, int y, int z) + { + int ox = originx + (cellxlen + wallxwidth) * x; + int oy = originy + (cellylen + wallywidth) * y; + int oz = originz + (cellzlen + wallzwidth) * z; + + // Hollow out room + for (int xi = 0; xi < cellxlen; xi++) { + int xx = ox + wallxwidth + xi; + for (int zi = 0; zi < cellzlen; zi++) { + int zz = oz + wallzwidth + zi; + for (int yi = 0; yi < cellylen; yi++) { + int yy = oy + wallywidth + yi; + bm.SetID(xx, yy, zz, (int)BlockType.AIR); + } + } + } + + // Build walls + for (int xi = 0; xi < cellxlen + 2 * wallxwidth; xi++) { + for (int zi = 0; zi < cellzlen + 2 * wallzwidth; zi++) { + for (int yi = 0; yi < wallywidth; yi++) { + bm.SetID(ox + xi, oy + yi, oz + zi, (int)BlockType.BEDROCK); + bm.SetID(ox + xi, oy + yi + cellylen + wallywidth, oz + zi, (int)BlockType.BEDROCK); + } + } + } + + for (int xi = 0; xi < cellxlen + 2 * wallxwidth; xi++) { + for (int zi = 0; zi < wallzwidth; zi++) { + for (int yi = 0; yi < cellylen + 2 * wallywidth; yi++) { + bm.SetID(ox + xi, oy + yi, oz + zi, (int)BlockType.BEDROCK); + bm.SetID(ox + xi, oy + yi, oz + zi + cellzlen + wallzwidth, (int)BlockType.BEDROCK); + } + } + } + + for (int xi = 0; xi < wallxwidth; xi++) { + for (int zi = 0; zi < cellzlen + 2 * wallzwidth; zi++) { + for (int yi = 0; yi < cellylen + 2 * wallywidth; yi++) { + bm.SetID(ox + xi, oy + yi, oz + zi, (int)BlockType.BEDROCK); + bm.SetID(ox + xi + cellxlen + wallxwidth, oy + yi, oz + zi, (int)BlockType.BEDROCK); + } + } + } + + // Torchlight + bm.SetID(ox + wallxwidth, oy + wallywidth + 2, oz + wallzwidth + 1, (int)BlockType.TORCH); + bm.SetID(ox + wallxwidth, oy + wallywidth + 2, oz + wallzwidth + cellzlen - 2, (int)BlockType.TORCH); + bm.SetID(ox + wallxwidth + cellxlen - 1, oy + wallywidth + 2, oz + wallzwidth + 1, (int)BlockType.TORCH); + bm.SetID(ox + wallxwidth + cellxlen - 1, oy + wallywidth + 2, oz + wallzwidth + cellzlen - 2, (int)BlockType.TORCH); + bm.SetID(ox + wallxwidth + 1, oy + wallywidth + 2, oz + wallzwidth, (int)BlockType.TORCH); + bm.SetID(ox + wallxwidth + cellxlen - 2, oy + wallywidth + 2, oz + wallzwidth, (int)BlockType.TORCH); + bm.SetID(ox + wallxwidth + 1, oy + wallywidth + 2, oz + wallzwidth + cellzlen - 1, (int)BlockType.TORCH); + bm.SetID(ox + wallxwidth + cellxlen - 2, oy + wallywidth + 2, oz + wallzwidth + cellzlen - 1, (int)BlockType.TORCH); + } + + public void LinkRooms (BlockManager bm, int x1, int y1, int z1, int x2, int y2, int z2) + { + int xx = originx + (cellxlen + wallxwidth) * x1; + int yy = originy + (cellylen + wallywidth) * y1; + int zz = originz + (cellzlen + wallzwidth) * z1; + + if (x1 != x2) { + xx = originx + (cellxlen + wallxwidth) * Math.Max(x1, x2); + for (int xi = 0; xi < wallxwidth; xi++) { + int zc = zz + wallzwidth + (cellzlen / 2); + int yb = yy + wallywidth; + bm.SetID(xx + xi, yb, zc - 1, (int)BlockType.AIR); + bm.SetID(xx + xi, yb, zc, (int)BlockType.AIR); + bm.SetID(xx + xi, yb, zc + 1, (int)BlockType.AIR); + bm.SetID(xx + xi, yb + 1, zc - 1, (int)BlockType.AIR); + bm.SetID(xx + xi, yb + 1, zc, (int)BlockType.AIR); + bm.SetID(xx + xi, yb + 1, zc + 1, (int)BlockType.AIR); + bm.SetID(xx + xi, yb + 2, zc, (int)BlockType.AIR); + } + } + else if (z1 != z2) { + zz = originz + (cellzlen + wallzwidth) * Math.Max(z1, z2); + for (int zi = 0; zi < wallxwidth; zi++) { + int xc = xx + wallxwidth + (cellxlen / 2); + int yb = yy + wallywidth; + bm.SetID(xc - 1, yb, zz + zi, (int)BlockType.AIR); + bm.SetID(xc, yb, zz + zi, (int)BlockType.AIR); + bm.SetID(xc + 1, yb, zz + zi, (int)BlockType.AIR); + bm.SetID(xc - 1, yb + 1, zz + zi, (int)BlockType.AIR); + bm.SetID(xc, yb + 1, zz + zi, (int)BlockType.AIR); + bm.SetID(xc + 1, yb + 1, zz + zi, (int)BlockType.AIR); + bm.SetID(xc, yb + 2, zz + zi, (int)BlockType.AIR); + } + } + else if (y1 != y2) { + yy = originy + (cellylen + wallywidth) * Math.Max(y1, y2); + for (int yi = 0 - cellylen + 1; yi < wallywidth + 1; yi++) { + int xc = xx + wallxwidth + (cellxlen / 2); + int zc = zz + wallzwidth + (cellzlen / 2); + + bm.SetID(xc, yy + yi, zc, (int)BlockType.BEDROCK); + bm.SetID(xc - 1, yy + yi, zc, (int)BlockType.LADDER); + bm.SetData(xc - 1, yy + yi, zc, 4); + bm.SetID(xc + 1, yy + yi, zc, (int)BlockType.LADDER); + bm.SetData(xc + 1, yy + yi, zc, 5); + bm.SetID(xc, yy + yi, zc - 1, (int)BlockType.LADDER); + bm.SetData(xc, yy + yi, zc - 1, 2); + bm.SetID(xc, yy + yi, zc + 1, (int)BlockType.LADDER); + bm.SetData(xc, yy + yi, zc + 1, 3); + } + } + } + + public void AddPrize (BlockManager bm, int x, int y, int z) + { + int ox = originx + (cellxlen + wallxwidth) * x + wallxwidth; + int oy = originy + (cellylen + wallywidth) * y + wallywidth; + int oz = originz + (cellzlen + wallzwidth) * z + wallzwidth; + + Random rand = new Random(); + for (int xi = 0; xi < cellxlen; xi++) { + for (int zi = 0; zi < cellzlen; zi++) { + if (rand.NextDouble() < 0.1) { + bm.SetID(ox + xi, oy, oz + zi, (int)BlockType.DIAMOND_BLOCK); + } + } + } + } + } + + class Generator + { + public struct Edge + { + public int node1; + public int node2; + + public Edge (int n1, int n2) + { + node1 = n1; + node2 = n2; + } + } + + int xlen; + int ylen; + int zlen; + + List _edges; + int[] _cells; + + public Generator () + { + xlen = 5; + ylen = 5; + zlen = 5; + + _edges = new List(); + _cells = new int[xlen * zlen * ylen]; + + for (int x = 0; x < xlen; x++) { + for (int z = 0; z < zlen; z++) { + for (int y = 0; y < ylen; y++) { + int n1 = Index(x, y, z); + _cells[n1] = n1; + } + } + } + + for (int x = 0; x < xlen - 1; x++) { + for (int z = 0; z < zlen; z++) { + for (int y = 0; y < ylen; y++) { + int n1 = Index(x, y, z); + int n2 = Index(x + 1, y, z); + _edges.Add(new Edge(n1, n2)); + } + } + } + + for (int x = 0; x < xlen; x++) { + for (int z = 0; z < zlen - 1; z++) { + for (int y = 0; y < ylen; y++) { + int n1 = Index(x, y, z); + int n2 = Index(x, y, z + 1); + _edges.Add(new Edge(n1, n2)); + } + } + } + + for (int x = 0; x < xlen; x++) { + for (int z = 0; z < zlen; z++) { + for (int y = 0; y < ylen - 1; y++) { + int n1 = Index(x, y, z); + int n2 = Index(x, y + 1, z); + _edges.Add(new Edge(n1, n2)); + } + } + } + } + + public List Generate () + { + Random rand = new Random(); + + List passages = new List(); + + // Randomize edges + Queue redges = new Queue(); + while (_edges.Count > 0) { + int index = rand.Next(_edges.Count); + Edge e = _edges[index]; + _edges.RemoveAt(index); + redges.Enqueue(e); + } + + while (redges.Count > 0) { + Edge e = redges.Dequeue(); + + if (_cells[e.node1] == _cells[e.node2]) { + continue; + } + + passages.Add(e); + + int n1 = _cells[e.node2]; + int n2 = _cells[e.node1]; + for (int i = 0; i < _cells.Length; i++) { + if (_cells[i] == n2) { + _cells[i] = n1; + } + } + } + + return passages; + } + + public int Index (int x, int y, int z) + { + return (x * zlen + z) * ylen + y; + } + + public void UnIndex (int index, out int x, out int y, out int z) + { + x = index / (zlen * ylen); + int xstr = index - (x * zlen * ylen); + z = xstr / ylen; + int ystr = xstr - (z * ylen); + y = ystr; + } + } +} diff --git a/Substrate/SubstrateCS/Examples/Maze/Properties/AssemblyInfo.cs b/Substrate/SubstrateCS/Examples/Maze/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..268d7a5 --- /dev/null +++ b/Substrate/SubstrateCS/Examples/Maze/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Maze")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("Microsoft")] +[assembly: AssemblyProduct("Maze")] +[assembly: AssemblyCopyright("Copyright © Microsoft 2011")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("1f8659a6-81aa-4f18-abb6-7e56f8ba9d34")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")]