forked from mirrors/NBTExplorer
Adding random 3D maze generator example
This commit is contained in:
parent
46387e28b4
commit
32dd74415f
3 changed files with 482 additions and 0 deletions
94
Substrate/SubstrateCS/Examples/Maze/Maze.csproj
Normal file
94
Substrate/SubstrateCS/Examples/Maze/Maze.csproj
Normal file
|
@ -0,0 +1,94 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>9.0.30729</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{62D70576-FE3A-4530-B283-889C14B52E9E}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Maze</RootNamespace>
|
||||
<AssemblyName>Maze</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<FileUpgradeFlags>
|
||||
</FileUpgradeFlags>
|
||||
<UpgradeBackupLocation>
|
||||
</UpgradeBackupLocation>
|
||||
<OldToolsVersion>3.5</OldToolsVersion>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Substrate, Version=0.4.1.0, Culture=neutral, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\bin\Release\Substrate.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include=".NETFramework,Version=v4.0">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Microsoft .NET Framework 4 %28x86 and x64%29</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
<BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>Windows Installer 3.1</ProductName>
|
||||
<Install>true</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
352
Substrate/SubstrateCS/Examples/Maze/Program.cs
Normal file
352
Substrate/SubstrateCS/Examples/Maze/Program.cs
Normal file
|
@ -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<Generator.Edge> 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<Edge> _edges;
|
||||
int[] _cells;
|
||||
|
||||
public Generator ()
|
||||
{
|
||||
xlen = 5;
|
||||
ylen = 5;
|
||||
zlen = 5;
|
||||
|
||||
_edges = new List<Edge>();
|
||||
_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<Edge> Generate ()
|
||||
{
|
||||
Random rand = new Random();
|
||||
|
||||
List<Edge> passages = new List<Edge>();
|
||||
|
||||
// Randomize edges
|
||||
Queue<Edge> redges = new Queue<Edge>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")]
|
Loading…
Reference in a new issue