-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgrid.js
159 lines (141 loc) · 3.89 KB
/
grid.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
class Grid {
constructor(dim, size) {
this.dim = dim;
this.r = (dim - 1) / 2;
this.size = size;
this.slots = [];
// Init the slots
this.initSlots();
}
draw() {
// Rotate to topdown view and Scale to size
translate(0, -(this.r * this.size), -(this.r * this.size));
rotateX(-45);
rotateY(135);
rotateZ(180);
scale(this.size);
// Draw the Grid
for (var slot of this.slots) {
push();
slot.draw();
pop();
}
}
initSlots() {
// Default starting options (all modules)
var options = Object.values(modules);
// Build Slots with initial values
for (var y = -this.r; y <= this.r; y++) {
for (var x = -this.r; x <= this.r; x++) {
for (var z = -this.r; z <= this.r; z++) {
this.slots.push(new Slot(x, y, z, options));
}
}
}
}
setupStartGrid() {
// Calculate Neighbors
for (const slot of this.slots) {
slot.getNeighbours();
slot.setColor();
}
// Setup Starting position
for (const slot of this.slots) {
if (slot.y == -this.r) {
// Just set bottom row to Water and Collapse
slot.options = [modules.water_0];
slot.collapse();
} else {
// Propegate vertical sides to Air
if (abs(slot.x) == this.r || abs(slot.z) == this.r) {
slot.propegate([modules.air_0]);
}
}
}
}
getLeastEntropy() {
// Filter Slots that are not Collapsed
const slots = this.slots.slice().filter((a) => !a.collapsed);
// Stop when there are no slots left
if (slots.length == 0) return;
// Sort slots based on options length
slots.sort((a, b) => {
return a.options.length - b.options.length;
});
// Get Slots with the least entropy
var val = slots[0].options.length;
var stopIndex = 0;
for (const [i, s] of slots.entries()) {
if (s.options.length > val) {
stopIndex = i;
break;
}
}
if (stopIndex > 0) slots.splice(stopIndex);
// Sort slots based on height (in the grid)
slots.sort((a, b) => {
return a.y - b.y;
});
// Get Slots with the lowest position
val = slots[0].y;
stopIndex = 0;
for (const [i, s] of slots.entries()) {
if (s.y > val) {
stopIndex = i;
break;
}
}
if (stopIndex > 0) slots.splice(stopIndex);
// Return a random Slot
return random(slots);
}
startWave() {
// Get slot with the least Entropy
const slot = this.getLeastEntropy();
if (slot !== undefined) {
// Pick a random option
const pickOption = this.pickNewOption(slot);
// Propegate option (to neighbors)
slot.propegate([pickOption]);
} else {
// Done no more picks left
startWave = false;
}
}
pickNewOption(slot) {
var options = slot.options;
var pickList = [];
var weight = 0;
for (const option of options) {
// Trying to give options a weight value to influence picking chance
// TODO: Could be improved? (based on Axis)
if (option.name.startsWith("box")){
if (slot.y <0)
weight = gui.weights.box+5;
else
weight = 0.001;
}
else if (option.name.startsWith("air")) {
if (slot.y <0 || abs(slot.x) <4 || abs(slot.y)<4)
weight = 0.002;
else
weight = 5;//gui.weights.air;
}
else if (option.name.startsWith("slope")) {
if (abs(slot.x) < 3 && abs(slot.z) <3)
weight = 0.002
else
weight = gui.weights.slope;
}
else if (option.name.startsWith("convex")) weight = gui.weights.corner;
else if (option.name.startsWith("concave")) weight = gui.weights.corner;
else weight = 0.002;
weight = ceil(1000 * weight);
var tempList = Array(weight).fill(option);
for (const temp of tempList) {
pickList.push(temp);
}
}
return random(pickList);
}
}