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