using System.Collections;
using System.Collections.Generic;
public static class VectorConstant
public static Vector3 East = new Vector3(1,0,0);
public static Vector3 West = new Vector3(-1,0,0);
public static Vector3 Up = new Vector3(0,1,0);
public static Vector3 Down = new Vector3(0,-1,0);
public static Vector3 North = new Vector3(0,0,1);
public static Vector3 South = new Vector3(0,0,-1);
public static Vector3[] Directions = {East, West, Up, Down, North, South};
public Random rand = new Random();
public void GenerationLoop(Level level)
public Tile ForceCollapseWave(HashSet<Tile> wave)
foreach (Tile tile in wave)
float roll = (float)rand.NextDouble() * cumProb;
foreach (Tile tile in wave)
Console.Write("Collapse Error");
public void Compare(Level level)
for (int i = 0; i < level.Size; i++)
for (int j = 0; j < level.Size; j++)
for (int k = 0; k < level.Size; k++)
foreach (Vector3 direction in VectorConstant.Directions)
Vector3 slot = new Vector3(i, j, k);
if (level.Data.ContainsKey(slot + direction))
int count = level.Data[slot].Count;
level.Data[slot].IntersectWith(GetPossibleSet(level.Data[slot + direction], direction));
if (count > level.Data[slot].Count)
public HashSet<Tile> GetPossibleSet(HashSet<Tile> wave, Vector3 direction)
HashSet<Tile> result = new HashSet<Tile>();
foreach (Tile tile in wave)
result.UnionWith(tile.GetNeighbour(direction));
public void CollapseRandomSlot(Level level)
List<HashSet<Tile>> uncollapsedWaves = new List<HashSet<Tile>>();
foreach (var entry in level.Data)
if (entry.Value.Count > 1)
uncollapsedWaves.Add(entry.Value);
if (uncollapsedWaves.Count == 0){return;}
int index = rand.Next(uncollapsedWaves.Count);
HashSet<Tile> randomWave = uncollapsedWaves[index];
randomWave.IntersectWith(new HashSet<Tile>{ForceCollapseWave(randomWave)});
public static void Main()
Propagator LevelGenerator = new Propagator();
TileBank bank = new TileBank();
bank.Data.Add(0, new Tile(bank, 0, 1f, " "));
bank.Data.Add(1, new Tile(bank, 1, 1f, "."));
bank.Data.Add(2, new Tile(bank, 2, 1f, ","));
bank.Data.Add(3, new Tile(bank, 3, 1f, "*"));
bank.Data.Add(4, new Tile(bank, 4, 1f, "#"));
bank.Data.Add(5, new Tile(bank, 5, 1f, "@"));
Level level = new Level(bank);
LevelGenerator.GenerationLoop(level);
public Dictionary<Vector3, HashSet<Tile>> Data = new Dictionary<Vector3, HashSet<Tile>>();
public Propagator Propagator = new Propagator();
public Level(TileBank tileBank)
for (int i = 0; i < Size; i++)
for (int j = 0; j < Size; j++)
for (int k = 0; k < Size; k++)
Data.Add(new Vector3(i, j, k), new HashSet<Tile>(Bank.GetFullSet()));
Data[new Vector3(5, 0, 5)] = new HashSet<Tile>{Bank.Data[0]};
for (int i = 0; i < Size; i++)
for (int k = 0; k < Size; k++)
Tile[] options = new Tile[Data[new Vector3(i, 0, k)].Count];
Data[new Vector3(i, 0, k)].CopyTo(options);
Console.Write(options[0].Draw);
public string Draw = "@";
public Tile(TileBank bank, int id, float prob, string draw)
public HashSet<Tile> GetNeighbour(Vector3 direction)
HashSet<Tile> result = new HashSet<Tile>();
for (int i = Id - 1; i < Id + 2; i++)
if (Bank.Data.ContainsKey(i))
result.Add(Bank.Data[i]);
public Dictionary<int, Tile> Data = new Dictionary<int, Tile>();
public HashSet<Tile> GetFullSet()
HashSet<Tile> result = new HashSet<Tile>();
foreach (var entry in Data)