import 'dart:developer'; import 'dart:math' as math; import 'package:dartterm/world/level.dart'; part 'direction.dart'; part 'direction_set.dart'; part 'orientation.dart'; part 'requirement.dart'; part 'vault.dart'; part 'vaults.dart'; class Generator { final math.Random _random; final Vaults _vaults; Generator(this._random, this._vaults); Vault generateBoxed(Requirement req) { var vx = req.vx; var vy = req.vy; var v = Vault.blank(vx, vy, req.smooth, LevelTile.wall); if (req.vx < 2 || req.vy < 2) { return v; } var req2 = Requirement(vx - 2, vy - 2, req.smooth); var inner = generate(req2); v.blitFrom(inner, 1, 1); return v; } Vault generate(Requirement requirement) { // TODO: Pick a relevant vault from the vaults file if possible // First of all: randomize orientation // This way we only have to consider one kind of spilt var orientation = randomOrientation(_random); // Try to make vx the long axis if possible var req2 = unReorientRequirement(requirement, orientation); if (req2.vy > (req2.vx - 2) * 3 / 2) { orientation = (orientation + 2) % 8; // rotate once more } 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); return out1; } Vault _generate(Requirement req) { var vx = req.vx; var vy = req.vy; var v = Vault.blank(vx, vy, req.smooth, LevelTile.wall); if (vx < 5 || vx * vy < 10) { v.clear(LevelTile.floor); } else { // pick a split point var splitVx = _random.nextInt(vx - 4) + 2; 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 vaultLeft = generate(reqLeft); var vaultRight = generate(reqRight); v.blitFrom(vaultLeft, 0, 0); v.blitFrom(vaultRight, splitVx + 1, 0); } return v; } }