parent
cb2505e8a6
commit
17c860ec45
@ -0,0 +1,18 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class RoomsGen : MonoBehaviour
|
||||
{
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6006dd3e743a0134591611bd775fe454
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,37 +1,360 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Tilemaps;
|
||||
using System.Threading;
|
||||
|
||||
public class WFCGenerator : MonoBehaviour
|
||||
{
|
||||
public Tiles[] tiles;
|
||||
public TileBase Rules;
|
||||
public Vector2Int maxsize;
|
||||
public Tilemap ForeGround;
|
||||
public Tilemap BackGround;
|
||||
public bool gen;
|
||||
public float TimeToDraw;
|
||||
private Vector2Int yeat;
|
||||
private wave[,] waves;
|
||||
[SerializeField][ReadOnly]private float timer;
|
||||
private Thread genthread;
|
||||
private bool done;
|
||||
|
||||
// Start is called before the first frame update
|
||||
void Start()
|
||||
{
|
||||
for(int i = 0; i < maxsize.x; i++)
|
||||
waves = new wave[maxsize.x, maxsize.y];
|
||||
for (int i = 0; i < waves.GetLength(0); i++)
|
||||
{
|
||||
for(int k = 0; k < maxsize.y; k++)
|
||||
for (int k = 0; k < waves.GetLength(1); k++)
|
||||
{
|
||||
ForeGround.SetTile(new Vector3Int(i, k, 0), Rules);
|
||||
waves[i, k].possible = new List<Tiles>(tiles);
|
||||
}
|
||||
}
|
||||
timer = TimeToDraw;
|
||||
}
|
||||
ForeGround.SetTile(new Vector3Int(5, 5, 0), tiles[0].tile);
|
||||
void OnDisable()
|
||||
{
|
||||
genthread.Interrupt();
|
||||
genthread.Abort();
|
||||
}
|
||||
// Update is called once per frame
|
||||
void Update()
|
||||
{
|
||||
|
||||
if(timer <= 0)
|
||||
{
|
||||
draw();
|
||||
timer = TimeToDraw;
|
||||
}
|
||||
if (gen)
|
||||
{
|
||||
gen = false;
|
||||
genthread = new Thread(new ThreadStart(Generate));
|
||||
genthread.Start();
|
||||
}
|
||||
if(done)
|
||||
{
|
||||
draw();
|
||||
done = false;
|
||||
}
|
||||
timer -= Time.deltaTime;
|
||||
}
|
||||
private void draw()
|
||||
{
|
||||
for (int i = 0; i < waves.GetLength(0); i++)
|
||||
{
|
||||
for (int k = 0; k < waves.GetLength(1); k++)
|
||||
{
|
||||
if (waves[i, k].possible.Count == 0)
|
||||
{
|
||||
ForeGround.SetTile(new Vector3Int(-i, -k, 0), waves[i, k].selected.tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private void Generate()
|
||||
{
|
||||
//get all
|
||||
waves = new wave[maxsize.x, maxsize.y];
|
||||
for (int i = 0; i < waves.GetLength(0); i++)
|
||||
{
|
||||
for (int k = 0; k < waves.GetLength(1); k++)
|
||||
{
|
||||
waves[i, k].possible = new List<Tiles>(tiles);
|
||||
}
|
||||
}
|
||||
while (true)
|
||||
{
|
||||
//select with low ent
|
||||
Debug.Log("getting with low entropy");
|
||||
Vector2Int wav = new Vector2Int(0, 0);
|
||||
int smallestent = 1000;
|
||||
for (int i = 0; i < waves.GetLength(0); i++)
|
||||
{
|
||||
for (int k = 0; k < waves.GetLength(1); k++)
|
||||
{
|
||||
if (waves[i, k].possible.Count < smallestent && waves[i, k].possible.Count != 0)
|
||||
{
|
||||
smallestent = waves[i, k].possible.Count;
|
||||
wav = new Vector2Int(i, k);
|
||||
}
|
||||
}
|
||||
}
|
||||
//set down
|
||||
Debug.Log("selecting random low entropy");
|
||||
System.Random r = new System.Random();
|
||||
waves[wav.x, wav.y].selected = waves[wav.x, wav.y].possible[r.Next(0, smallestent)];
|
||||
waves[wav.x, wav.y].possible.Clear();
|
||||
//propagate
|
||||
Debug.Log("started propagation");
|
||||
List<Vector2Int> Pos = new List<Vector2Int>();
|
||||
Pos.Add(wav);
|
||||
while (true)
|
||||
{
|
||||
if (Pos.Count == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
propagate(Pos);
|
||||
}
|
||||
int check = 0;
|
||||
foreach (var item in waves)
|
||||
{
|
||||
check += item.possible.Count;
|
||||
}
|
||||
if (check == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
//draw
|
||||
done = true;
|
||||
}
|
||||
private bool propagate(List<Vector2Int> Pos)
|
||||
{
|
||||
bool change = false;
|
||||
//get working
|
||||
List<Tiles> t = new List<Tiles>();
|
||||
if (waves[Pos[0].x, Pos[0].y].possible.Count > 0)
|
||||
{
|
||||
t = waves[Pos[0].x, Pos[0].y].possible;
|
||||
}
|
||||
else
|
||||
{
|
||||
t.Add(waves[Pos[0].x, Pos[0].y].selected);
|
||||
}
|
||||
//checking the one to the left
|
||||
if (Pos[0].x - 1 >= 0)
|
||||
{
|
||||
if (waves[Pos[0].x - 1, Pos[0].y].possible.Count > 0)
|
||||
{
|
||||
List<Tiles> yeat = new List<Tiles>();
|
||||
bool gChange = false;
|
||||
foreach (var item in waves[Pos[0].x - 1, Pos[0].y].possible)
|
||||
{
|
||||
bool nomatch = true;
|
||||
foreach (var it in t)
|
||||
{
|
||||
if (item.TopRight == it.TopLeft && item.BottomRight == it.BottomLeft)
|
||||
{
|
||||
nomatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nomatch)
|
||||
{
|
||||
yeat.Add(item);
|
||||
}
|
||||
}
|
||||
foreach (var item in yeat)
|
||||
{
|
||||
waves[Pos[0].x - 1, Pos[0].y].possible.Remove(item);
|
||||
change = true;
|
||||
gChange = true;
|
||||
}
|
||||
if (waves[Pos[0].x - 1, Pos[0].y].possible.Count == 1)
|
||||
{
|
||||
waves[Pos[0].x - 1, Pos[0].y].selected = waves[Pos[0].x - 1, Pos[0].y].possible[0];
|
||||
waves[Pos[0].x - 1, Pos[0].y].possible.Clear();
|
||||
}
|
||||
if (gChange)
|
||||
{
|
||||
Pos.Add(new Vector2Int(Pos[0].x - 1, Pos[0].y));
|
||||
}
|
||||
}
|
||||
}
|
||||
//checking the one above
|
||||
if (Pos[0].y - 1 >= 0)
|
||||
{
|
||||
if (waves[Pos[0].x, Pos[0].y - 1].possible.Count > 0)
|
||||
{
|
||||
List<Tiles> yeat = new List<Tiles>();
|
||||
bool gChange = false;
|
||||
foreach (var item in waves[Pos[0].x, Pos[0].y - 1].possible)
|
||||
{
|
||||
bool nomatch = true;
|
||||
foreach (var it in t)
|
||||
{
|
||||
if (item.BottomRight == it.TopRight && item.BottomLeft == it.TopLeft)
|
||||
{
|
||||
nomatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nomatch)
|
||||
{
|
||||
yeat.Add(item);
|
||||
}
|
||||
}
|
||||
foreach (var item in yeat)
|
||||
{
|
||||
waves[Pos[0].x, Pos[0].y - 1].possible.Remove(item);
|
||||
change = true;
|
||||
gChange = true;
|
||||
}
|
||||
if (waves[Pos[0].x, Pos[0].y - 1].possible.Count == 1)
|
||||
{
|
||||
waves[Pos[0].x, Pos[0].y - 1].selected = waves[Pos[0].x, Pos[0].y - 1].possible[0];
|
||||
waves[Pos[0].x, Pos[0].y - 1].possible.Clear();
|
||||
}
|
||||
if(gChange)
|
||||
{
|
||||
Pos.Add(new Vector2Int(Pos[0].x, Pos[0].y - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
//checking the one to the right
|
||||
if (Pos[0].x + 1 < waves.GetLength(0))
|
||||
{
|
||||
if (waves[Pos[0].x + 1, Pos[0].y].possible.Count > 0)
|
||||
{
|
||||
List<Tiles> yeat = new List<Tiles>();
|
||||
bool gChange = false;
|
||||
foreach (var item in waves[Pos[0].x + 1, Pos[0].y].possible)
|
||||
{
|
||||
bool nomatch = true;
|
||||
foreach (var it in t)
|
||||
{
|
||||
if (item.TopRight == it.TopLeft && item.BottomRight == it.BottomLeft)
|
||||
{
|
||||
nomatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nomatch)
|
||||
{
|
||||
yeat.Add(item);
|
||||
}
|
||||
}
|
||||
foreach (var item in yeat)
|
||||
{
|
||||
waves[Pos[0].x + 1, Pos[0].y].possible.Remove(item);
|
||||
change = true;
|
||||
gChange = true;
|
||||
}
|
||||
if (waves[Pos[0].x + 1, Pos[0].y].possible.Count == 1)
|
||||
{
|
||||
waves[Pos[0].x + 1, Pos[0].y].selected = waves[Pos[0].x + 1, Pos[0].y].possible[0];
|
||||
waves[Pos[0].x + 1, Pos[0].y].possible.Clear();
|
||||
}
|
||||
if(gChange)
|
||||
{
|
||||
Pos.Add(new Vector2Int(Pos[0].x + 1, Pos[0].y));
|
||||
}
|
||||
}
|
||||
}
|
||||
//checking the one under
|
||||
if (Pos[0].y + 1 < waves.GetLength(1))
|
||||
{
|
||||
if (waves[Pos[0].x, Pos[0].y + 1].possible.Count > 0)
|
||||
{
|
||||
List<Tiles> yeat = new List<Tiles>();
|
||||
bool gChange = false;
|
||||
foreach (var item in waves[Pos[0].x, Pos[0].y + 1].possible)
|
||||
{
|
||||
bool nomatch = true;
|
||||
foreach (var it in t)
|
||||
{
|
||||
if (item.TopRight == it.BottomRight && item.TopLeft == it.BottomLeft)
|
||||
{
|
||||
nomatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (nomatch)
|
||||
{
|
||||
yeat.Add(item);
|
||||
}
|
||||
}
|
||||
foreach (var item in yeat)
|
||||
{
|
||||
waves[Pos[0].x, Pos[0].y + 1].possible.Remove(item);
|
||||
change = true;
|
||||
gChange = true;
|
||||
}
|
||||
if (waves[Pos[0].x, Pos[0].y + 1].possible.Count == 1)
|
||||
{
|
||||
waves[Pos[0].x, Pos[0].y + 1].selected = waves[Pos[0].x, Pos[0].y + 1].possible[0];
|
||||
waves[Pos[0].x, Pos[0].y + 1].possible.Clear();
|
||||
}
|
||||
if(gChange)
|
||||
{
|
||||
Pos.Add(new Vector2Int(Pos[0].x, Pos[0].y + 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
Pos.Remove(Pos[0]);
|
||||
/*foreach(var item in Pos)
|
||||
{
|
||||
Debug.Log(item.ToString());
|
||||
}
|
||||
Thread.Sleep(1000);
|
||||
if(Pos.Count <= 100)
|
||||
{
|
||||
Debug.Log("finnished a run: " + Pos.Count);
|
||||
}
|
||||
else if(Pos.Count % 100 == 0)
|
||||
{
|
||||
Debug.Log("finnished a run: " + Pos.Count);
|
||||
}*/
|
||||
return change;
|
||||
}
|
||||
private struct wave
|
||||
{
|
||||
public List<Tiles> possible;
|
||||
public Tiles selected;
|
||||
}
|
||||
|
||||
[System.Serializable]
|
||||
public struct Tiles
|
||||
{
|
||||
public TileBase tile;
|
||||
public int index;
|
||||
[Header("False Black / True White")]
|
||||
public bool TopLeft;
|
||||
public bool TopRight;
|
||||
public bool BottomLeft;
|
||||
public bool BottomRight;
|
||||
}
|
||||
}
|
||||
public class ReadOnlyAttribute : PropertyAttribute
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
[CustomPropertyDrawer(typeof(ReadOnlyAttribute))]
|
||||
public class ReadOnlyDrawer : PropertyDrawer
|
||||
{
|
||||
public override float GetPropertyHeight(SerializedProperty property,
|
||||
GUIContent label)
|
||||
{
|
||||
return EditorGUI.GetPropertyHeight(property, label, true);
|
||||
}
|
||||
|
||||
public override void OnGUI(Rect position,
|
||||
SerializedProperty property,
|
||||
GUIContent label)
|
||||
{
|
||||
GUI.enabled = false;
|
||||
EditorGUI.PropertyField(position, property, label, true);
|
||||
GUI.enabled = true;
|
||||
}
|
||||
}
|
Loading…
Reference in new issue