Files
ants/maps/maps.js
2026-03-26 18:43:01 +01:00

1066 lines
36 KiB
JavaScript
Executable File

#!/usr/bin/env nodejs
const fs = require("fs");
let CellType = {
EMPTY: 0,
WALL: 1,
FOOD: 2,
NEST: 3,
};
class C {
state;
constructor(e) {
((this.state = 0 | e), 0 === this.state && (this.state = 1));
}
next() {
let e = 0 | (this.state += 0x9e3779b9);
return (
(((e = Math.imul(
(e = Math.imul(e ^ (e >>> 16), 0x85ebca6b)) ^ (e >>> 13),
0xc2b2ae35,
)) ^
(e >>> 16)) >>>
0) /
0x100000000
);
}
nextInt(e) {
return (this.next() * e) | 0;
}
nextIntRange(e, t) {
return e + this.nextInt(t - e);
}
shuffle(e) {
for (let t = e.length - 1; t > 0; t--) {
let r = this.nextInt(t + 1);
[e[t], e[r]] = [e[r], e[t]];
}
return e;
}
}
function P(e, t, r, l) {
let a = e * t;
return {
width: e,
height: t,
cells: new Uint8Array(a),
food: new Uint16Array(a),
pheromones: new Uint16Array(a * 4),
visitCounts: new Uint32Array(a),
nestX: Math.floor(e / 2),
nestY: Math.floor(t / 2),
totalFood: 0,
seed: r,
name: l,
};
}
function H(e) {
for (let t = 0; t < e.width; t++)
(_(e, t, 0, CellType.WALL), _(e, t, e.height - 1, CellType.WALL));
for (let t = 0; t < e.height; t++)
(_(e, 0, t, CellType.WALL), _(e, e.width - 1, t, CellType.WALL));
}
let V = {
open: function (e, t, r) {
let n = P(e, t, r, `open-${r}`),
l = new C(r),
a = e / 128;
(H(n), J(n, l), $(n));
let s = 5 + l.nextInt(4);
for (let r = 0; r < s; r++) {
let r = 4 + l.nextInt(e - 8),
s = 4 + l.nextInt(t - 8);
if (W(r, s, n.nestX, n.nestY) < 15 * a) continue;
let o = 3 + l.nextInt(3),
i = 2 + l.nextInt(3);
for (let e = -o; e <= o; e++)
for (let t = -o; t <= o; t++) {
if (t * t + e * e > o * o) continue;
let l = r + t,
a = s + e;
G(n, l, a) && F(n, l, a, i);
}
}
return n;
},
maze: function (e, t, r) {
let l = P(e, t, r, `maze-${r}`),
a = new C(r),
s = e / 128;
H(l);
for (let r = 1; r < t - 1; r++)
for (let t = 1; t < e - 1; t++) _(l, t, r, CellType.WALL);
let o = Math.floor((e - 2) / 4),
i = Math.floor((t - 2) / 4),
c = new Uint8Array(o * i),
d = [];
function u(e, t) {
return [1 + 4 * e + 1, 1 + 4 * t + 1];
}
function h(r, a) {
let [s, i] = u(r, a);
for (let r = 0; r < 2; r++)
for (let a = 0; a < 2; a++)
s + a < e - 1 &&
i + r < t - 1 &&
_(l, s + a, i + r, CellType.EMPTY);
c[a * o + r] = 1;
}
function p(r, a, s, o) {
let [i, c] = u(r, a),
[d, h] = u(s, o),
p = Math.min(i, d),
f = Math.min(c, h),
m = Math.max(i, d) + 1,
x = Math.max(c, h) + 1;
for (let r = f; r <= x; r++)
for (let a = p; a <= m; a++)
a > 0 &&
a < e - 1 &&
r > 0 &&
r < t - 1 &&
_(l, a, r, CellType.EMPTY);
}
let f = Math.floor(o / 2),
m = Math.floor(i / 2);
(h(f, m), d.push(f, m));
let x = [
[0, -1],
[1, 0],
[0, 1],
[-1, 0],
];
for (; d.length > 0; ) {
let e = d[d.length - 1],
t = d[d.length - 2],
r = [];
for (let n = 0; n < 4; n++) {
let l = t + x[n][0],
a = e + x[n][1];
l >= 0 &&
l < o &&
a >= 0 &&
a < i &&
!c[a * o + l] &&
r.push(n);
}
if (0 === r.length) {
d.length -= 2;
continue;
}
let n = r[a.nextInt(r.length)],
l = t + x[n][0],
s = e + x[n][1];
(p(t, e, l, s), h(l, s), d.push(l, s));
}
for (let e = 0; e < i; e++)
for (let t = 0; t < o; t++)
if (c[e * o + t])
for (let [r, n] of [
[1, 0],
[0, 1],
]) {
let l = t + r,
s = e + n;
!(l >= o) &&
!(s >= i) &&
c[s * o + l] &&
0.25 > a.next() &&
p(t, e, l, s);
}
for (let r = 0; r < 100; r++) {
let r = 4 + a.nextInt(e - 8),
s = 4 + a.nextInt(t - 8);
if (l.cells[U(l, r, s)] === CellType.EMPTY) {
((l.nestX = r), (l.nestY = s));
break;
}
}
$(l);
let g = 16 + a.nextInt(7);
for (let r = 0; r < g; r++)
for (let r = 0; r < 50; r++) {
let r = 2 + a.nextInt(e - 4),
o = 2 + a.nextInt(t - 4);
if (
l.cells[U(l, r, o)] === CellType.EMPTY &&
W(r, o, l.nestX, l.nestY) > 12 * s
) {
let e = 1 + a.nextInt(3),
t = 3 + a.nextInt(6);
for (let a = -e; a <= e; a++)
for (let s = -e; s <= e; s++)
!(s * s + a * a > e * e) &&
G(l, r + s, o + a) &&
l.cells[U(l, r + s, o + a)] ===
CellType.EMPTY &&
F(l, r + s, o + a, t);
break;
}
}
return (Y(l), l);
},
spiral: function (e, t, r) {
let l = P(e, t, r, `spiral-${r}`),
a = new C(r);
(H(l), $(l));
let s = e / 2,
o = t / 2,
i = Math.min(e, t) / 2 - 2,
c = Math.max(5, Math.floor(0.06 * e));
for (let e = c + 2; e < i; e += c) {
let t = a.next() * Math.PI * 2,
r = 0.6 + 0.4 * a.next(),
i = 2 + a.nextInt(3),
c = 1 + 1.5 * a.next(),
d = a.next() * Math.PI * 2;
for (let a = 0; a < 2 * Math.PI; a += 0.02) {
let u = Math.abs(
((a - t + 3 * Math.PI) % (2 * Math.PI)) - Math.PI,
);
if (u < r) continue;
let h =
e +
c * Math.min(1, (u - r) / 0.5) * Math.sin(a * i + d),
p = Math.floor(s + Math.cos(a) * h),
f = Math.floor(o + Math.sin(a) * h);
G(l, p, f) && _(l, p, f, CellType.WALL);
}
}
for (let e = c; e < i; e += c) {
let t = e + c / 2,
r = 3 + a.nextInt(3);
for (let e = 0; e < r; e++) {
let e = a.next() * Math.PI * 2,
r = t + (a.next() - 0.5) * (0.3 * c),
n = Math.floor(s + Math.cos(e) * r),
i = Math.floor(o + Math.sin(e) * r),
d = 1 + a.nextInt(2),
u = 3 + a.nextInt(3);
for (let e = -d; e <= d; e++)
for (let t = -d; t <= d; t++) {
if (t * t + e * e > d * d) continue;
let r = n + t,
a = i + e;
G(l, r, a) && F(l, r, a, u);
}
}
}
return (Y(l), l);
},
field: function (e, t, r) {
let l = P(e, t, r, `field-${r}`),
a = new C(r),
s = e / 128;
(H(l),
J(l, a),
$(l),
(function (e, t, r, l) {
for (let a = 0; a < r; a++) {
let r = 4 + t.nextInt(e.width - 8),
a = 4 + t.nextInt(e.height - 8);
if (8 > W(r, a, e.nestX, e.nestY)) continue;
let s = l[0] + t.nextInt(l[1] - l[0]),
o = t.next() * Math.PI * 2,
i = 0,
c = !1;
for (
let l = 0;
l < s &&
((o += (t.next() - 0.5) * 1),
G(
e,
(r += Math.round(Math.cos(o))),
(a += Math.round(Math.sin(o))),
));
l++
)
!(5 > W(r, a, e.nestX, e.nestY)) &&
(i++,
!c && i > 8 + t.nextInt(12)
? ((c = !0), (i = 0))
: c &&
i > 2 + t.nextInt(3) &&
((c = !1), (i = 0)),
c || _(e, r, a, CellType.WALL));
}
})(l, a, 3 + a.nextInt(3), [70, 130]));
let o = 6 + a.nextInt(3);
for (let r = 0; r < o; r++) {
let r = 4 + a.nextInt(e - 8),
n = 4 + a.nextInt(t - 8);
if (W(r, n, l.nestX, l.nestY) < 12 * s) continue;
let o = 2 + a.nextInt(4),
i = 2 + a.nextInt(4);
for (let e = -o; e <= o; e++)
for (let t = -o; t <= o; t++) {
if (t * t + e * e > o * o) continue;
let a = r + t,
s = n + e;
G(l, a, s) && F(l, a, s, i);
}
}
return (Y(l), l);
},
bridge: function (e, t, r) {
let l = P(e, t, r, `bridge-${r}`),
a = new C(r);
H(l);
let s = Math.floor(e / 2),
o = Math.floor(0.1 * e),
i = new Int32Array(t),
c = s;
for (let r = 1; r < t - 1; r++) {
(0.3 > a.next() && (c += a.nextInt(3) - 1),
(c = Math.max(s - o, Math.min(s + o, c))),
(i[r] = c));
for (let t = -1; t <= 1; t++) {
let a = c + t;
a > 0 && a < e - 1 && _(l, a, r, CellType.WALL);
}
}
let d = 2 + a.nextInt(3),
u = Math.floor(t / (d + 1));
for (let r = 0; r < d; r++) {
let s = u * (r + 1),
o = 2 + a.nextInt(2);
for (let r = -o; r <= o; r++) {
let a = s + r;
if (a > 0 && a < t - 1)
for (let t = -1; t <= 1; t++) {
let r = i[a] + t;
r > 0 && r < e - 1 && _(l, r, a, CellType.EMPTY);
}
}
}
((l.nestX = Math.floor(e / 4)), (l.nestY = Math.floor(t / 2)), $(l));
let h = 6 + a.nextInt(4);
for (let r = 0; r < h; r++) {
let r = s + 4 + a.nextInt(Math.floor(e / 2) - 6),
o = 4 + a.nextInt(t - 8),
i = 2 + a.nextInt(3),
c = 3 + a.nextInt(4);
for (let e = -i; e <= i; e++)
for (let t = -i; t <= i; t++) {
if (t * t + e * e > i * i) continue;
let a = r + t,
s = o + e;
G(l, a, s) &&
l.cells[U(l, a, s)] !== CellType.WALL &&
F(l, a, s, c);
}
}
return (B(l, a), l);
},
gauntlet: function (e, t, r) {
let l = P(e, t, r, `gauntlet-${r}`),
a = new C(r);
(H(l), (l.nestX = 5), (l.nestY = Math.floor(t / 2)), $(l));
let s = 3 + a.nextInt(2),
o = Math.floor((e - 20) / (s + 1));
for (let r = 0; r < s; r++) {
let s = 12 + o * (r + 1),
i =
r % 2 == 0
? 4 + a.nextInt(Math.floor(t / 3))
: Math.floor((2 * t) / 3) +
a.nextInt(Math.floor(t / 3) - 4),
c = 4 + a.nextInt(4);
for (let r = 1; r < t - 1; r++)
!(Math.abs(r - i) < c) &&
s > 0 &&
s < e - 1 &&
_(l, s, r, CellType.WALL);
}
for (let r = 1; r <= s; r++) {
let n = 12 + r * o + 4,
i = r < s ? 12 + (r + 1) * o - 4 : e - 6;
if (i <= n) continue;
let c = (r - 1) / Math.max(1, s - 1),
d = 2 + a.nextInt(2) + Math.round(2 * c),
u = 1 + Math.round(2 * c),
h = 2 + a.nextInt(2) + Math.round(3 * c);
for (let e = 0; e < d; e++) {
let e = n + a.nextInt(Math.max(1, i - n)),
r = 4 + a.nextInt(t - 8);
for (let t = -u; t <= u; t++)
for (let n = -u; n <= u; n++) {
if (n * n + t * t > u * u) continue;
let a = e + n,
s = r + t;
G(l, a, s) && F(l, a, s, h);
}
}
}
return (B(l, a), l);
},
pockets: function (e, t, r) {
let l = P(e, t, r, `pockets-${r}`),
a = new C(r);
(H(l), J(l, a), $(l));
let s = [],
o = 7 + a.nextInt(4);
for (let r = 0; r < 300 && s.length < o; r++) {
let r = 7 + a.nextInt(6),
o = r + 4 + a.nextInt(e - 2 * r - 8),
i = r + 4 + a.nextInt(t - 2 * r - 8);
if (W(o, i, l.nestX, l.nestY) < r + 8) continue;
let c = !1;
for (let e of s)
if (W(o, i, e.cx, e.cy) < r + e.r + 5) {
c = !0;
break;
}
if (c) continue;
s.push({ cx: o, cy: i, r });
let d = a.next() * Math.PI * 2,
u = 0.2 + 0.1 * a.next();
for (let e = 0; e < 2 * Math.PI; e += 0.025) {
if (
Math.abs(
((e - d + 3 * Math.PI) % (2 * Math.PI)) - Math.PI,
) < u
)
continue;
let t = Math.round(o + Math.cos(e) * r),
a = Math.round(i + Math.sin(e) * r);
G(l, t, a) && _(l, t, a, CellType.WALL);
}
let h = 3 + a.nextInt(2),
p = 2 + a.nextInt(3);
for (let e = -h; e <= h; e++)
for (let t = -h; t <= h; t++) {
if (t * t + e * e > h * h) continue;
let r = o + t,
a = i + e;
G(l, r, a) &&
l.cells[U(l, r, a)] === CellType.EMPTY &&
F(l, r, a, p);
}
}
return (Y(l), l);
},
fortress: function (e, t, r) {
let l = P(e, t, r, `fortress-${r}`),
a = new C(r);
H(l);
let s = Math.floor(e / 2),
o = Math.floor(t / 2),
i = 3 + a.nextInt(2),
c = Math.max(4, Math.floor(Math.min(e, t) / (2 * i + 4)));
((l.nestX = 4), (l.nestY = 4), $(l));
for (let e = 1; e <= i; e++) {
let t = e * c,
r = a.next() * Math.PI * 2,
i = 0.35 + 0.2 * a.next(),
d = 3 + a.nextInt(3),
u = 1.5 + 2 * a.next(),
h = a.next() * Math.PI * 2;
for (let e = 0; e < 2 * Math.PI; e += 0.015) {
if (
Math.abs(
((e - r + 3 * Math.PI) % (2 * Math.PI)) - Math.PI,
) < i
)
continue;
let a = t + Math.sin(e * d + h) * u,
c = Math.floor(s + Math.cos(e) * a),
p = Math.floor(o + Math.sin(e) * a);
G(l, c, p) && _(l, c, p, CellType.WALL);
}
}
let d = c - 2;
for (let e = -d; e <= d; e++)
for (let t = -d; t <= d; t++) {
if (t * t + e * e > d * d) continue;
let r = s + t,
n = o + e;
G(l, r, n) && F(l, r, n, 3 + a.nextInt(3));
}
for (let r = 1; r < i; r++) {
let i = r * c + Math.floor(c / 2),
d = 4 + a.nextInt(4);
for (let r = 0; r < d; r++) {
let r = a.next() * Math.PI * 2,
c = Math.floor(s + Math.cos(r) * i),
d = Math.floor(o + Math.sin(r) * i);
c > 1 &&
c < e - 2 &&
d > 1 &&
d < t - 2 &&
l.cells[U(l, c, d)] === CellType.EMPTY &&
F(l, c, d, 2 + a.nextInt(4));
}
}
return (Y(l), l);
},
islands: function (e, t, r) {
let l = P(e, t, r, `islands-${r}`),
a = new C(r);
for (let r = 0; r < t; r++)
for (let t = 0; t < e; t++) _(l, t, r, CellType.WALL);
let s = Math.floor((e - 2) / 4),
o = Math.floor((t - 2) / 4),
i = [];
for (let e = 0; e < 4; e++)
for (let t = 0; t < 4; t++) {
let r = 1 + t * s + 2,
a = 1 + e * o + 2,
c = 1 + (t + 1) * s - 2,
d = 1 + (e + 1) * o - 2,
u = Math.floor((r + c) / 2),
h = Math.floor((a + d) / 2);
i.push({ cx: u, cy: h, ri: e, ci: t });
for (let e = a; e <= d; e++)
for (let t = r; t <= c; t++)
G(l, t, e) && _(l, t, e, CellType.EMPTY);
}
let c = i.map(() => []),
d = 2 + a.nextInt(2);
for (let e = 0; e < 4; e++)
for (let t = 0; t < 4; t++) {
let r = 4 * e + t;
if (t < 3) {
let i = 1 + (t + 1) * s,
u = 1 + e * o + 2 + a.nextInt(Math.max(1, o - 4 - d)),
h = u + Math.floor(d / 2);
(c[r].push({ x: i, y: h }), c[r + 1].push({ x: i, y: h }));
for (let e = 0; e < d; e++)
for (let t = -2; t <= 2; t++)
G(l, i + t, u + e) &&
_(l, i + t, u + e, CellType.EMPTY);
}
if (e < 3) {
let i = 1 + (e + 1) * o,
u = 1 + t * s + 2 + a.nextInt(Math.max(1, s - 4 - d)),
h = u + Math.floor(d / 2);
(c[r].push({ x: h, y: i }), c[r + 4].push({ x: h, y: i }));
for (let e = 0; e < d; e++)
for (let t = -2; t <= 2; t++)
G(l, u + e, i + t) &&
_(l, u + e, i + t, CellType.EMPTY);
}
}
let u = i[a.nextInt(i.length)];
((l.nestX = u.cx), (l.nestY = u.cy), $(l));
let h = s - 4,
p = o - 4,
f = ["empty", "blob", "walls", "diffuse", "corners"],
m = [],
x = d + 5;
for (let e = 0; e < i.length; e++) {
let t = i[e];
if (t === u) continue;
0 === m.length && (m.push(...f), a.shuffle(m));
let r = m.pop(),
n = t.cx - Math.floor(h / 2),
s = t.cy - Math.floor(p / 2),
o = c[e];
if ("empty" !== r) {
if ("blob" === r) {
let e = Math.max(1, Math.floor(Math.min(h, p) / 8)),
r = t.cx + a.nextInt(5) - 2,
n = t.cy + a.nextInt(5) - 2,
s = 1 + a.nextInt(2);
for (let t = -e; t <= e; t++)
for (let a = -e; a <= e; a++)
!(a * a + t * t > e * e) &&
G(l, r + a, n + t) &&
F(l, r + a, n + t, s);
} else if ("walls" === r) {
let e = n + h - 1,
t = s + p - 1,
r = (e, t) =>
o.some(
(r) =>
Math.abs(e - r.x) + Math.abs(t - r.y) < x,
);
for (let o = n; o <= e; o++)
(0.5 > a.next() &&
G(l, o, s) &&
!r(o, s) &&
F(l, o, s, 1),
0.5 > a.next() &&
G(l, o, t) &&
!r(o, t) &&
F(l, o, t, 1));
for (let o = s + 1; o < t; o++)
(0.5 > a.next() &&
G(l, n, o) &&
!r(n, o) &&
F(l, n, o, 1),
0.5 > a.next() &&
G(l, e, o) &&
!r(e, o) &&
F(l, e, o, 1));
} else if ("diffuse" === r)
for (let e = s; e < s + p; e++)
for (let t = n; t < n + h; t++)
0.12 > a.next() && G(l, t, e) && F(l, t, e, 1);
else if ("corners" === r) {
let e = Math.max(1, Math.floor(Math.min(h, p) / 7));
for (let [t, r] of [
[n + e + 1, s + e + 1],
[n + h - e - 2, s + e + 1],
[n + e + 1, s + p - e - 2],
[n + h - e - 2, s + p - e - 2],
]) {
if (0.3 > a.next()) continue;
let n = 1 + a.nextInt(3);
for (let a = -e; a <= e; a++)
for (let s = -e; s <= e; s++)
!(s * s + a * a > e * e) &&
G(l, t + s, r + a) &&
F(l, t + s, r + a, n);
}
}
}
}
return l;
},
chambers: function (e, t, r) {
let l = P(e, t, r, `chambers-${r}`),
a = new C(r);
for (let r = 0; r < t; r++)
for (let t = 0; t < e; t++) _(l, t, r, CellType.WALL);
let s = [],
o = 11 + a.nextInt(3);
for (let r = 0; r < o; r++) {
let r = 4 + a.nextInt(4),
o = 4 + a.nextInt(4),
i = r + 2 + a.nextInt(Math.max(1, e - 2 * r - 4)),
c = o + 2 + a.nextInt(Math.max(1, t - 2 * o - 4)),
d = !1;
for (let e of s)
if (
Math.abs(i - e.cx) < r + e.hw + 2 &&
Math.abs(c - e.cy) < o + e.hh + 2
) {
d = !0;
break;
}
if (!d) {
s.push({ cx: i, cy: c, hw: r, hh: o });
for (let e = c - o; e <= c + o; e++)
for (let t = i - r; t <= i + r; t++)
G(l, t, e) && _(l, t, e, CellType.EMPTY);
}
}
for (let e = 1; e < s.length; e++) {
let t = s[e - 1],
r = s[e],
a = t.cx,
o = t.cy;
for (; a !== r.cx; ) {
for (let e = -1; e <= 1; e++)
G(l, a, o + e) && _(l, a, o + e, CellType.EMPTY);
a += a < r.cx ? 1 : -1;
}
for (; o !== r.cy; ) {
for (let e = -1; e <= 1; e++)
G(l, a + e, o) && _(l, a + e, o, CellType.EMPTY);
o += o < r.cy ? 1 : -1;
}
}
{
let e = s[s.length - 1],
t = s[0],
r = e.cx,
a = e.cy;
for (; r !== t.cx; ) {
for (let e = -1; e <= 1; e++)
G(l, r, a + e) && _(l, r, a + e, CellType.EMPTY);
r += r < t.cx ? 1 : -1;
}
for (; a !== t.cy; ) {
for (let e = -1; e <= 1; e++)
G(l, r + e, a) && _(l, r + e, a, CellType.EMPTY);
a += a < t.cy ? 1 : -1;
}
}
let i = s.reduce(
(r, n) => {
let l = W(n.cx, n.cy, e / 2, t / 2);
return l < r.d ? { c: n, d: l } : r;
},
{ c: s[0], d: 1 / 0 },
);
for (let e of ((l.nestX = i.c.cx), (l.nestY = i.c.cy), $(l), s)) {
if (e === i.c) continue;
let t = Math.min(Math.min(e.hw, e.hh) - 1, 3);
if (t < 1) continue;
let r = 3 + a.nextInt(3);
for (let n = -t; n <= t; n++)
for (let a = -t; a <= t; a++) {
if (a * a + n * n > t * t) continue;
let s = e.cx + a,
o = e.cy + n;
G(l, s, o) && F(l, s, o, r);
}
}
return l;
},
prairie: function (e, t, r) {
let n = P(e, t, r, `prairie-${r}`),
l = new C(r);
(H(n), J(n, l), $(n));
let a = 6 + l.nextInt(4),
s = [];
for (let r = 0; r < a; r++)
s.push({
x: 4 + l.nextInt(e - 8),
y: 4 + l.nextInt(t - 8),
strength: 0.25 + 0.3 * l.next(),
radius: 6 + l.nextInt(10),
});
for (let r = 2; r < t - 2; r++)
for (let t = 2; t < e - 2; t++) {
if (5 > W(t, r, n.nestX, n.nestY)) continue;
let e = 0.016;
for (let n of s) {
let l = W(t, r, n.x, n.y);
l < n.radius && (e += n.strength * (1 - l / n.radius));
}
((e = Math.min(e, 0.25)),
l.next() < e &&
F(
n,
t,
r,
e > 0.12 ? 1 + l.nextInt(3) : 1 + l.nextInt(2),
));
}
return n;
},
brush: function (e, t, r) {
let l = P(e, t, r, `brush-${r}`),
a = new C(r),
s = e / 128;
(H(l), J(l, a), $(l));
for (let r = 2; r < t - 2; r++)
for (let t = 2; t < e - 2; t++)
!(5 > W(t, r, l.nestX, l.nestY)) &&
0.28 > a.next() &&
_(l, t, r, CellType.WALL);
for (let e = -3; e <= 3; e++)
for (let t = -3; t <= 3; t++) {
let r = l.nestX + t,
a = l.nestY + e;
G(l, r, a) &&
l.cells[U(l, r, a)] === CellType.WALL &&
_(l, r, a, CellType.EMPTY);
}
let o = 10 + a.nextInt(3);
for (let r = 0; r < o; r++)
for (let r = 0; r < 80; r++) {
let r = 4 + a.nextInt(e - 8),
o = 4 + a.nextInt(t - 8);
if (
W(r, o, l.nestX, l.nestY) < 10 * s ||
l.cells[U(l, r, o)] !== CellType.EMPTY
)
continue;
let i = 2 + a.nextInt(3),
c = 3 + a.nextInt(3);
for (let e = -i; e <= i; e++)
for (let t = -i; t <= i; t++) {
if (t * t + e * e > i * i) continue;
let n = r + t,
a = o + e;
G(l, n, a) && F(l, n, a, c);
}
break;
}
return (Y(l), l);
},
};
function Y(e) {
let t = new Uint8Array(e.width * e.height),
r = [e.nestX, e.nestY];
t[e.nestY * e.width + e.nestX] = 1;
let l = 0;
for (; l < r.length; ) {
let a = r[l++],
s = r[l++];
for (let [l, o] of [
[0, -1],
[1, 0],
[0, 1],
[-1, 0],
]) {
let i = a + l,
c = s + o;
if (i < 0 || i >= e.width || c < 0 || c >= e.height) continue;
let d = c * e.width + i;
t[d] || e.cells[d] === CellType.WALL || ((t[d] = 1), r.push(i, c));
}
}
for (let r = 0; r < e.width * e.height; r++)
if (e.cells[r] === CellType.FOOD && !t[r]) {
let l = Math.floor(r / e.width),
a = r % e.width,
s = new Uint8Array(e.width * e.height),
o = new Int32Array(e.width * e.height).fill(-1),
i = [a, l];
s[r] = 1;
let c = -1,
d = 0;
for (; d < i.length && c < 0; ) {
let r = i[d++],
n = i[d++];
for (let [l, a] of [
[0, -1],
[1, 0],
[0, 1],
[-1, 0],
]) {
let d = r + l,
u = n + a;
if (d < 1 || d >= e.width - 1 || u < 1 || u >= e.height - 1)
continue;
let h = u * e.width + d;
if (!s[h]) {
if (((s[h] = 1), (o[h] = n * e.width + r), t[h])) {
c = h;
break;
}
i.push(d, u);
}
}
}
if (c >= 0) {
let r = c;
for (; r >= 0; )
(e.cells[r] === CellType.WALL &&
(e.cells[r] = CellType.EMPTY),
(t[r] = 1),
(r = o[r]));
}
}
}
function W(e, t, r, n) {
return Math.sqrt((e - r) ** 2 + (t - n) ** 2);
}
function G(e, t, r) {
return t > 0 && t < e.width - 1 && r > 0 && r < e.height - 1;
}
function J(e, t, r) {
let n = r ?? Math.floor(0.15 * Math.min(e.width, e.height));
((e.nestX = n + t.nextInt(e.width - 2 * n)),
(e.nestY = n + t.nextInt(e.height - 2 * n)));
}
function $(e) {
let t = e.nestX,
r = e.nestY;
for (let l = -1; l <= 1; l++)
for (let a = -1; a <= 1; a++) {
let s = t + a,
o = r + l;
s >= 0 &&
s < e.width &&
o >= 0 &&
o < e.height &&
_(e, s, o, CellType.NEST);
}
}
function U(e, t, r) {
return r * e.width + t;
}
function _(e, t, r, n) {
e.cells[U(e, t, r)] = n;
}
function X(e, t, r) {
return e.cells[U(e, t, r)];
}
function G(e, t, r) {
return t > 0 && t < e.width - 1 && r > 0 && r < e.height - 1;
}
function F(e, t, r, l) {
let a = U(e, t, r);
e.cells[a] === CellType.EMPTY &&
((e.cells[a] = CellType.FOOD), (e.food[a] = l), (e.totalFood += l));
}
function B(e, t) {
if (e.width !== e.height) return;
let r = e.width,
n = 1 === t.nextInt(2),
l = 1 === t.nextInt(2),
a = 1 === t.nextInt(2);
if (!n && !l && !a) return;
let s = new Uint8Array(r * r),
o = new Uint16Array(r * r);
for (let t = 0; t < r; t++)
for (let i = 0; i < r; i++) {
let c = n ? r - 1 - i : i,
d = l ? r - 1 - t : t;
if (a) {
let e = c;
((c = d), (d = e));
}
((s[d * r + c] = e.cells[t * r + i]),
(o[d * r + c] = e.food[t * r + i]));
}
(e.cells.set(s), e.food.set(o));
let i = n ? r - 1 - e.nestX : e.nestX,
c = l ? r - 1 - e.nestY : e.nestY;
if (a) {
let e = i;
((i = c), (c = e));
}
((e.nestX = i), (e.nestY = c));
}
function renderMapASCII(map) {
const symbols = {
0: " ", // EMPTY
1: "#", // WALL
2: "o", // FOOD
3: "S", // NEST
};
let output = "";
for (let y = 0; y < map.height; y++) {
let row = "";
for (let x = 0; x < map.width; x++) {
const cell = X(map, x, y);
if (symbols[cell] !== undefined) {
row += symbols[cell];
}
}
output += row + "\n";
}
console.log(output);
}
function randomize_r(r, n) {
return (
0xfffffff &
Math.imul(
(l =
Math.imul(0x45d9f3b ^ r, 0x9e3779b9) ^
Math.imul(n + 1, 0x6c62272e)) ^
(l >>> 16),
0x85ebca6b,
) || 1
);
}
function generate_random_maps(e, t, r, n) {
let l = [];
for (let a = 0; a < n; a++)
l.push(
(function (e, t, r, n) {
let l,
a = new C(0x5a5a5a5a ^ r),
s = Object.entries(V);
a.shuffle(s);
let [o, i] = s[n % s.length],
c = randomize_r(r, n);
d = i(e, t, c);
return ((d.name = `${o}-${c.toString(36)}`), d);
})(e, t, r, a),
);
return l;
}
function generate_maps(e, t, r, n, typ) {
let l = [];
for (let a = 0; a < n; a++)
l.push(
(function (e, t, r, n) {
let a = new C(0x5a5a5a5a ^ r);
let i = V[typ];
let c = randomize_r(r, n);
d = i(e, t, c);
return ((d.name = `${typ}-${c.toString(36)}`), d);
})(e, t, r, a),
);
return l;
}
function map_from_name(name) {
let parts = name.split("-");
let generator = parts[0];
let code = parts[1];
let c = Number.parseInt(code, 36);
return V[generator](WIDTH, HEIGHT, c);
}
const WIDTH = 128;
const HEIGHT = 128;
r = 42;
n = 120;
const { program } = require("commander");
program.name("maps").description("Generate and view maps").version("1.0.0");
program.command("view <name>").action((name, options) => {
console.log(`Viewing ${name}`);
let map = map_from_name(name);
renderMapASCII(map);
});
program
.command("generate")
.option("-s, --seed <seed>", "Define seed", Number, 42)
.option("-n, --number <number>", "Amount of maps", Number, 120)
.option("-o, --output <output>", "Output file", "generated.maps")
.option("-t, --type <type>", "Map type", "random")
.action((options) => {
let maps = null;
if (options.type == "random") {
maps = generate_random_maps(
WIDTH,
HEIGHT,
options.seed,
options.number,
);
} else {
maps = generate_maps(
WIDTH,
HEIGHT,
options.seed,
options.number,
options.type,
);
}
const ws = fs.createWriteStream(options.output);
let header = Buffer.alloc(4);
header.writeInt32LE(maps.length);
ws.write(header);
const MAX_NAME_LENGTH = 31;
for (var i = 0; i < maps.length; i++) {
let header = Buffer.alloc(MAX_NAME_LENGTH + 3);
let name = maps[i].name;
let cells = Buffer.from(maps[i].cells);
let nest_cell = maps[i].nestY * WIDTH + maps[i].nestX;
header.fill(0);
header.write(name, 0, MAX_NAME_LENGTH);
header.writeInt16LE(nest_cell, MAX_NAME_LENGTH + 1);
ws.write(header);
ws.write(cells);
}
ws.end();
});
program.parse();
//let map = map_from_name("gauntlet-41jczs");
//renderMapASCII(map);