Holy shit! It works
This commit is contained in:
parent
757cca1392
commit
5de409515e
@ -1,4 +1,3 @@
|
||||
import 'dart:developer';
|
||||
import 'dart:math' as math;
|
||||
import 'package:dartterm/assets.dart';
|
||||
import 'package:dartterm/gen/generator.dart';
|
||||
@ -29,11 +28,9 @@ void main() async {
|
||||
int seed = 0;
|
||||
|
||||
while (true) {
|
||||
Vault output = Generator(math.Random(seed), vaults).generate(Requirement(
|
||||
32,
|
||||
24,
|
||||
DirectionSet(
|
||||
{Direction.up, Direction.left, Direction.right, Direction.down})));
|
||||
clear();
|
||||
Vault output = Generator(math.Random(seed), vaults)
|
||||
.generate(Requirement(16, 32, 16, 24, DirectionSet({})), false);
|
||||
var w = output.vx;
|
||||
var h = output.vy;
|
||||
for (var y = 0; y < h; y++) {
|
||||
@ -55,7 +52,7 @@ void main() async {
|
||||
}
|
||||
inpLoop:
|
||||
await for (var inp in rawInput()) {
|
||||
print(inp);
|
||||
skreek("$inp");
|
||||
switch (inp) {
|
||||
case Keystroke(text: "a"):
|
||||
seed -= 1;
|
||||
|
@ -20,11 +20,13 @@ class Generator {
|
||||
|
||||
Generator(this._random, this._vaults);
|
||||
|
||||
Vault generate(Requirement requirement) {
|
||||
Vault generate(Requirement requirement, bool canBeVault) {
|
||||
if (canBeVault) {
|
||||
Vault? suggested = _suggest(vaultTries, requirement);
|
||||
if (suggested != null) {
|
||||
return suggested;
|
||||
}
|
||||
}
|
||||
|
||||
// First of all: randomize orientation
|
||||
// This way we only have to consider one kind of spilt
|
||||
@ -32,46 +34,108 @@ class Generator {
|
||||
|
||||
// Try to make vx the long axis if possible
|
||||
var req2 = unReorientRequirement(requirement, orientation);
|
||||
if (req2.vy > (req2.vx - 2) * 3 / 2) {
|
||||
if (req2.vyMax > (req2.vxMax - 2) * 3 / 2) {
|
||||
orientation = (orientation + 2) % 8; // rotate once more
|
||||
}
|
||||
// if only one of "left" and "right" needs to be smooth, prioritize right
|
||||
// as left is generated first
|
||||
req2 = unReorientRequirement(requirement, orientation);
|
||||
if (req2.smooth.directions.contains(Direction.left) &&
|
||||
req2.smooth.directions.contains(Direction.right)) {
|
||||
orientation = (orientation + 4) % 8;
|
||||
}
|
||||
|
||||
req2 = unReorientRequirement(requirement, orientation);
|
||||
var out2 = _generate(req2);
|
||||
var out1 = reorientVault(out2, orientation);
|
||||
|
||||
// log("$orientation ${requirement.vx} ${requirement.vy} ${req2.vx} ${req2.vy} ${out2.vx} ${out2.vy} ${out1.vx} ${out1.vy}");
|
||||
assert(out1.vx == requirement.vx);
|
||||
assert(out1.vy == requirement.vy);
|
||||
assert(out1.vx >= requirement.vxMin && out1.vx <= requirement.vxMax);
|
||||
assert(out1.vy >= requirement.vyMin && out1.vy <= requirement.vyMax);
|
||||
assert(out1.smooth.directions.containsAll(requirement.smooth.directions));
|
||||
return out1;
|
||||
}
|
||||
|
||||
Vault _generate(Requirement req) {
|
||||
var vx = req.vx;
|
||||
var vy = req.vy;
|
||||
var v = Vault.blank(vx, vy, req.smooth, VaultTile.wall);
|
||||
var vxMin = req.vxMin;
|
||||
var vyMin = req.vyMin;
|
||||
var vxMax = req.vxMax;
|
||||
var vyMax = req.vyMax;
|
||||
|
||||
if (vx < 2 || vy < 2) {
|
||||
} else if (vx < 9 || (vx - 2) * (vy - 2) < 12) {
|
||||
var v2 = Vault.blank(vx - 2, vy - 2, req.smooth, VaultTile.bspfloor);
|
||||
var smoothUp = req.smooth.directions.contains(Direction.up);
|
||||
var smoothDown = req.smooth.directions.contains(Direction.down);
|
||||
var smoothUpDown = smoothUp && smoothDown;
|
||||
|
||||
// var vxRand = _random.nextInt(vxMax - vxMin) + vxMin;
|
||||
var vyRand = _random.nextInt(vyMax + 1 - vyMin) + vyMin;
|
||||
|
||||
if (vxMax < 2 || vyMax < 2) {
|
||||
return Vault.blank(vxMax, vyRand, req.smooth, VaultTile.wall);
|
||||
} else if (vxMax < 9 || (vxMax - 2) * (vyMax - 2) < 12) {
|
||||
var v2 =
|
||||
Vault.blank(vxMax - 2, vyMax - 2, req.smooth, VaultTile.bspfloor);
|
||||
var v = Vault.blank(vxMax, vyMax, req.smooth, VaultTile.wall);
|
||||
v.blitFrom(v2, 1, 1);
|
||||
return v;
|
||||
} else {
|
||||
// pick a split point
|
||||
var splitVx = _random.nextInt(vx - 8) + 4;
|
||||
var leftReq = Requirement(
|
||||
math.max(vxMin - 4, 2), vxMax - 4, vyMin, vyMax, req.smooth.clone());
|
||||
leftReq.smooth.directions.add(Direction.right);
|
||||
var leftChild = generate(leftReq, true);
|
||||
|
||||
var reqLeft = Requirement(splitVx, vy, req.smooth.clone());
|
||||
reqLeft.smooth.directions.add(Direction.right);
|
||||
var reqRight = Requirement((vx - splitVx + 1), vy, req.smooth.clone());
|
||||
reqRight.smooth.directions.add(Direction.left);
|
||||
var vyMinRight = vyMin;
|
||||
var vyMaxRight = vyMax;
|
||||
|
||||
var vaultLeft = generate(reqLeft);
|
||||
var vaultRight = generate(reqRight);
|
||||
v.blitFrom(vaultLeft, 0, 0);
|
||||
v.blitFrom(vaultRight, splitVx - 1, 0);
|
||||
if (smoothUpDown) {
|
||||
vyMinRight = leftChild.vy;
|
||||
vyMaxRight = leftChild.vy;
|
||||
}
|
||||
|
||||
var rightReq = Requirement(
|
||||
vxMin - (leftChild.vx - 1),
|
||||
vxMax - (leftChild.vx - 1),
|
||||
vyMinRight,
|
||||
vyMaxRight,
|
||||
req.smooth.clone(),
|
||||
);
|
||||
rightReq.smooth.directions.add(Direction.left);
|
||||
var rightChild = generate(rightReq, true);
|
||||
|
||||
var vxTotal = leftChild.vx + rightChild.vx - 1;
|
||||
var vyTotal = math.max(leftChild.vy, rightChild.vy);
|
||||
|
||||
if (smoothUp) {
|
||||
var v =
|
||||
Vault.blank(vxTotal, vyTotal, req.smooth.clone(), VaultTile.wall);
|
||||
v.blitFrom(leftChild, 0, 0);
|
||||
v.blitFrom(rightChild, leftChild.vx - 1, 0);
|
||||
return v;
|
||||
}
|
||||
if (smoothDown) {
|
||||
var v =
|
||||
Vault.blank(vxTotal, vyTotal, req.smooth.clone(), VaultTile.wall);
|
||||
v.blitFrom(leftChild, 0, vyTotal - leftChild.vy);
|
||||
v.blitFrom(rightChild, leftChild.vx - 1, vyTotal - rightChild.vy);
|
||||
return v;
|
||||
}
|
||||
|
||||
// no smoothing reqs
|
||||
// min: ensure some overlap
|
||||
var vyTMax = math.min(vyMax, leftChild.vy + rightChild.vy - 3);
|
||||
if (vyTMax > vyTotal) {
|
||||
vyTotal += _random.nextInt(vyTMax - vyTotal);
|
||||
}
|
||||
var v = Vault.blank(vxTotal, vyTotal, req.smooth.clone(), VaultTile.wall);
|
||||
if (_random.nextBool()) {
|
||||
v.blitFrom(leftChild, 0, 0);
|
||||
v.blitFrom(rightChild, leftChild.vx - 1, vyTotal - rightChild.vy);
|
||||
} else {
|
||||
v.blitFrom(leftChild, 0, vyTotal - leftChild.vy);
|
||||
v.blitFrom(rightChild, leftChild.vx - 1, 0);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
Vault? _suggest(int tries, Requirement req) {
|
||||
for (var i = 0; i < tries; i++) {
|
||||
@ -100,27 +164,19 @@ class Generator {
|
||||
}
|
||||
|
||||
Vault? _tidy(Vault vault, Requirement req) {
|
||||
if (vault.vx > req.vx || vault.vy > req.vy) {
|
||||
if (vault.vx > req.vxMax || vault.vy > req.vyMax) {
|
||||
return null;
|
||||
}
|
||||
if (vault.vx < req.vx / 2 || vault.vy < req.vy / 2) {
|
||||
if (vault.vx < req.vxMin || vault.vy < req.vyMin) {
|
||||
return null;
|
||||
}
|
||||
if (!vault.smooth.directions.containsAll(req.smooth.directions)) {
|
||||
return null;
|
||||
}
|
||||
return vault;
|
||||
|
||||
/*
|
||||
var rsd = req.smooth.directions;
|
||||
bool mustFillX =
|
||||
rsd.contains(Direction.left) && rsd.contains(Direction.right);
|
||||
if (vault.vx != req.vx && mustFillX) {
|
||||
return null;
|
||||
}
|
||||
bool mustFillY = rsd.contains(Direction.up) && rsd.contains(Direction.down);
|
||||
if (vault.vy != req.vy && mustFillY) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Vault full = Vault.blank(req.vx, req.vy, req.smooth, VaultTile.wall);
|
||||
int vx = vault.vx;
|
||||
int dx;
|
||||
@ -143,5 +199,6 @@ class Generator {
|
||||
}
|
||||
full.blitFrom(vault, dx, dy);
|
||||
return full;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,25 @@
|
||||
part of 'generator.dart';
|
||||
|
||||
class Requirement {
|
||||
final int vx, vy;
|
||||
final int vxMin, vxMax, vyMin, vyMax;
|
||||
final DirectionSet smooth;
|
||||
|
||||
Requirement(this.vx, this.vy, this.smooth);
|
||||
Requirement(this.vxMin, this.vxMax, this.vyMin, this.vyMax, this.smooth) {
|
||||
assert(vxMin <= vxMax);
|
||||
assert(vyMin <= vyMax);
|
||||
assert(vxMax > 2);
|
||||
assert(vyMax > 2);
|
||||
}
|
||||
|
||||
Requirement flip() {
|
||||
return Requirement(vx, vy, smooth.flip());
|
||||
return Requirement(vxMin, vxMax, vyMin, vyMax, smooth.flip());
|
||||
}
|
||||
|
||||
Requirement rotateLeft() {
|
||||
return Requirement(vy, vx, smooth.rotateLeft());
|
||||
return Requirement(vyMin, vyMax, vxMin, vxMax, smooth.rotateLeft());
|
||||
}
|
||||
|
||||
Requirement rotateRight() {
|
||||
return Requirement(vy, vx, smooth.rotateRight());
|
||||
return Requirement(vyMin, vyMax, vxMin, vxMax, smooth.rotateRight());
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,9 @@ class Vaults {
|
||||
var tiles = [
|
||||
for (var y = r.rect.top; y < r.rect.bottom; y++)
|
||||
for (var x = r.rect.left; x < r.rect.right; x++)
|
||||
b.get(x, y) ?? VaultTile.wall
|
||||
r.points.contains((x, y))
|
||||
? (b.get(x, y) ?? VaultTile.wall)
|
||||
: VaultTile.wall
|
||||
];
|
||||
DirectionSet smooth = DirectionSet(
|
||||
{Direction.up, Direction.left, Direction.right, Direction.down});
|
||||
|
@ -1,4 +1,6 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
|
||||
void skreek(String msg) {
|
||||
// ignore: avoid_print
|
||||
print("[skreek] $msg");
|
||||
debugPrint("[skreek] $msg");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user