From 01e316d979a2c4f24718b0102a29ba8d7b1f1586 Mon Sep 17 00:00:00 2001 From: Nyeogmi Date: Thu, 21 Sep 2023 17:33:48 -0700 Subject: [PATCH] Add arches, which demand to be collapsed --- assets/images/vaults/house1.png | Bin 737 -> 867 bytes assets/images/vaults/warehouse_1x1.png | Bin 0 -> 820 bytes assets/images/vaults/warehouse_2x2.png | Bin 0 -> 792 bytes lib/bitmap.dart | 18 +++++- lib/game.dart | 7 ++- lib/gen/generator.dart | 82 ++++++++++++++++++++----- lib/gen/vault.dart | 20 +++++- lib/gen/vaults.dart | 7 +++ 8 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 assets/images/vaults/warehouse_1x1.png create mode 100644 assets/images/vaults/warehouse_2x2.png diff --git a/assets/images/vaults/house1.png b/assets/images/vaults/house1.png index f16ab362dc7bc0ec75c27a6c586bff872b335907..c7b4c07295a5be8dfe726d5584035f2352be97a9 100644 GIT binary patch delta 411 zcmaFJ`j}0zGr-TCmrII^fq{Y7)59eQNIQTq2OE%Fm05Uiqv9q;4lxD=u2aj@L?+*6 zRIg|B_H=O!skrraW+2}o1p!w1W6fXF4xFvp{B`lwOKh5^h7#r53>CNh;o0z6sCki3 zHr9W4*nGJwcF2Laj5-Rb^_qUSQ=*PPAt?JJ3J#+{P~5{#90r_{SOq?Y?n3p`Ln%4=0a8G)5+VPg`SK5xow-C z@0^DF98SAWdE0vw8=C6x;>vt^=eX>fpJnMMUz(dph@{SGa2CjFTj+M8Qo75k>Eeop z5}_77wmHfE&KD0fxCpOdRrF8nP$;=IrO#jaNzJCT5{E_XduoF@ozoSUi*;2s19d#H j(R7l6|R?7~`FWn)e+XGvljj+Sz)54vI1!oFHynt^vr8T_kYEYMs?` z(N$j^OGY*Lj?=CX_qAvuI2LsHv7{~uTw_y5nE&lTnkis!M!T1cJ&;T7NVlq58aQ~t z^Ne&HrH*Sluuvo|j43u#@e3HGVrWN4BVC5pM0%&)|8i2i0004oX+uL$Nkc;* zaB^>EX>4Tx04R}tl08VnKp2MKrb@L`9PA+C5TQC*5EXHhDi*;)X)CnqU~=gnG-*gu zTpR`0f`dPcRRo3h_DdxIqOHKXP4m`HgeYVS#6cjZA8uI7}=SJ6P^uRx(uLY2t{YYLqWz zT~;`6aaJoe)~b`=FqGF;(p;xGj5wB%KoTNk)KEqR7NWFjq?kz2e$2x^PFL_LKB_ zTZL(Py{?f@^NyTKhPC05a68+Jvl010qNS#tmYE+YT{E+YYWr9XB6000Mc zNliru=Lr@79W-Gta{&MV02y>eSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{ z00A6HL_t(&-tCw{4ul{O1bd7R^Jfe{<7cynbp;Hv9+YIXiHQPpumW8P2m)NU831B2 z;EiYczRb+bJg&e5JYWj}BH|Q47-EL_giKKw$p2gm5Ri=XkFat0Jf>q0MC?)I77G)tx9JT@y@=qI_ z9c!L=pfT9`#C1b&BmLR3Oqa15%`J+i-)8~>L=lo~5%0|AY%k+N{5Xv^Oxn`r-lxY( zy<4nJjpDy6Px|zJvFRzL~8zle% y2tWV=5P$##AOHafKmY;|fB*y_009W_Mt~3GN372sQEd7E00000004oX+uL$Nkc;* zaB^>EX>4Tx04R}tl08VnKp2MKrb@L`9PA+C5TQC*5EXHhDi*;)X)CnqU~=gnG-*gu zTpR`0f`dPcRRo3h_DdxIqOHKXP4m`HgeYVS#6cjZA8uI7}=SJ6P^uRx(uLY2t{YYLqWz zT~;`6aaJoe)~b`=FqGF;(p;xGj5wB%KoTNk)KEqR7NWFjq?kz2e$2x^PFL_LKB_ zTZL(Py{?f@^NyTKhPC05a68+Jvl010qNS#tmYE+YT{E+YYWr9XB6000Mc zNliru=Lr=TBOPgk>I(n>02y>eSad^gZEa<4bO1wgWnpw>WFU8GbZ8()Nlj2!fese{ z0096=L_t(&-tCyd4ul{K1zWTKt^4KO1DjP5gbQmPna0G#^fFTBp>C_$+xA*btCn<& zh=?%3T1>p;0bc3m?xFxLw`)r)@IF6V1xM(oAh}t>LRbh3T`eT#qTE7q6NQDa5EiOg zNW?{D3kl5?7Q#YUsA!?%mfp;^6LO;=>m01I%2~*&6O}q|8uHG;!#T$$j{S{>iT$6O zGzY>WUEhWA!;@A+*2xO=S*UsbY0BiOD4h5>oz3tyt-P;oaI{sA)6J;rPqd-YHeHa( zW!bzRG^a=^rB!F!=xCcR$nGuCDUg4LntYJ)R{{V400000000000000000000c&0uu WFMjJJTgm?b0000 { } void set(int x, int y, T value) { - assert(x < 0 || y < 0 || x >= size.dx || y >= size.dy); + assert(!(x < 0 || y < 0 || x >= size.dx || y >= size.dy)); data[y * size.dx + x] = value; } @@ -101,6 +101,22 @@ class Bitmap { } } + void blitFromWith(Bitmap other, int dx, int dy, T Function(T, T) merge) { + assert(rect.containsRect(geo.Rect(dx, dy, other.size.dx, other.size.dy))); + var x0 = other.rect.x0; + var y0 = other.rect.x0; + var x1 = other.rect.x1; + var y1 = other.rect.y1; + var myW = size.dx; + var otW = other.size.dx; + for (var x = x0; x < x1; x++) { + for (var y = y0; y < y1; y++) { + data[(y + dy) * myW + (x + dx)] = + merge(data[(y + dy) * myW + (x + dx)], other.data[y * otW + x]); + } + } + } + Bitmap flip() { var geo.Size(:dx, :dy) = size; diff --git a/lib/game.dart b/lib/game.dart index 4fd7d7f..6a396ae 100644 --- a/lib/game.dart +++ b/lib/game.dart @@ -31,7 +31,7 @@ void main() async { while (true) { clear(); Vault output = Generator(math.Random(seed), vaults) - .generate(Requirement(16, 32, 16, 24, DirectionSet({})), false); + .generate(Requirement(16, 32, 16, 24, DirectionSet({}))); var geo.Size(dx: w, dy: h) = output.size; for (var y = 0; y < h; y++) { for (var x = 0; x < w; x++) { @@ -44,7 +44,12 @@ void main() async { case VaultTile.door: cursor.puts("d"); case VaultTile.wall: + case VaultTile.defaultwall: cursor.puts("#"); + case VaultTile.archpronewall: + cursor.puts("%"); + case VaultTile.archwall: + cursor.puts("\$"); case VaultTile.exit: cursor.puts("X"); case VaultTile.meta0: diff --git a/lib/gen/generator.dart b/lib/gen/generator.dart index e331c54..1a886c8 100644 --- a/lib/gen/generator.dart +++ b/lib/gen/generator.dart @@ -12,7 +12,7 @@ part 'requirement.dart'; part 'vault.dart'; part 'vaults.dart'; -const vaultTries = 10; +const vaultTries = 30; class Generator { final math.Random _random; @@ -21,7 +21,12 @@ class Generator { Generator(this._random, this._vaults); - Vault generate(Requirement requirement, bool canBeVault) { + Vault generate(Requirement requirement) { + var out = _generateOriented(requirement, false); + return _finalize(out); + } + + Vault _generateOriented(Requirement requirement, bool canBeVault) { if (canBeVault) { Vault? suggested = _suggest(vaultTries, requirement); if (suggested != null) { @@ -47,7 +52,7 @@ class Generator { } req2 = unReorientRequirement(requirement, orientation); - var out2 = _generate(req2); + var out2 = _generateBsp(req2); var out1 = reorientVault(out2, orientation); // log("$orientation ${requirement.vx} ${requirement.vy} ${req2.vx} ${req2.vy} ${out2.vx} ${out2.vy} ${out1.vx} ${out1.vy}"); @@ -58,7 +63,7 @@ class Generator { return out1; } - Vault _generate(Requirement req) { + Vault _generateBsp(Requirement req) { var vxMin = req.vxMin; var vyMin = req.vyMin; var vxMax = req.vxMax; @@ -72,7 +77,7 @@ class Generator { var vyRand = _random.nextInt(vyMax + 1 - vyMin) + vyMin; if (vxMax < 2 || vyMax < 2) { - return Vault.blank(vxMax, vyRand, VaultTile.wall, req.smooth); + return Vault.blank(vxMax, vyRand, VaultTile.defaultwall, req.smooth); } else if (vxMax < 9 || (vxMax - 2) * (vyMax - 2) < 12) { var v2 = Vault.blank( vxMax - 2, vyMax - 2, VaultTile.bspfloor, req.smooth.clone()); @@ -83,7 +88,7 @@ class Generator { 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 leftChild = _generateOriented(leftReq, true); var vyMinRight = vyMin; var vyMaxRight = vyMax; @@ -100,21 +105,21 @@ class Generator { req.smooth.clone(), ); rightReq.smooth.directions.add(Direction.left); - var rightChild = generate(rightReq, true); + var rightChild = _generateOriented(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, VaultTile.wall, req.smooth.clone()); + var v = Vault.blank( + vxTotal, vyTotal, VaultTile.defaultwall, req.smooth.clone()); v.blitFrom(leftChild, 0, 0); v.blitFrom(rightChild, leftChild.vx - 1, 0); return v; } if (smoothDown) { - var v = - Vault.blank(vxTotal, vyTotal, VaultTile.wall, req.smooth.clone()); + var v = Vault.blank( + vxTotal, vyTotal, VaultTile.defaultwall, req.smooth.clone()); v.blitFrom(leftChild, 0, vyTotal - leftChild.vy); v.blitFrom(rightChild, leftChild.vx - 1, vyTotal - rightChild.vy); return v; @@ -126,7 +131,8 @@ class Generator { if (vyTMax > vyTotal) { vyTotal += _random.nextInt(vyTMax - vyTotal); } - var v = Vault.blank(vxTotal, vyTotal, VaultTile.wall, req.smooth.clone()); + var v = Vault.blank( + vxTotal, vyTotal, VaultTile.defaultwall, req.smooth.clone()); if (_random.nextBool()) { v.blitFrom(leftChild, 0, 0); v.blitFrom(rightChild, leftChild.vx - 1, vyTotal - rightChild.vy); @@ -230,8 +236,8 @@ class Generator { sz.dy, DirectionSet( {Direction.up, Direction.left, Direction.down, Direction.right})); - var inner = generate(metaRequirement, true); - var dest = Vault(Bitmap.blank(vault.vx, vault.vy, VaultTile.wall), + var inner = _generateOriented(metaRequirement, true); + var dest = Vault(Bitmap.blank(vault.vx, vault.vy, VaultTile.defaultwall), vault.smooth.clone()); dest.blitFrom(vault, 0, 0); dest.blitFrom(inner, i.rect.x0, i.rect.y0); @@ -240,4 +246,52 @@ class Generator { return vault; } + + Vault _finalize(Vault subj) { + var vx = subj.vx, vy = subj.vy; + subj = Vault.blankWith(vx, vy, (x, y) { + var bed = VaultTile.defaultwall; + if (x == 0 || x == vx - 1 || y == 0 || y == vy - 1) { + bed = VaultTile.wall; + } + var tile = mergeVaultTile(bed, subj.tiles.get(x, y)!); + return tile; + }, subj.smooth.clone()); + + bool canSupportArch(VaultTile? tile) { + return tile == VaultTile.bspfloor || + tile == VaultTile.floor || + tile == VaultTile.exit; + } + + var orthoOffsets = [(0, -1), (0, 1), (-1, 0), (1, 0)]; + List<(int, int)> newArches = []; + for (int x = 0; x < vx; x++) { + for (int y = 0; y < vy; y++) { + var t = subj.tiles.get(x, y); + if (t == VaultTile.archwall) { + var supporters = 0; + for (var (dx, dy) in orthoOffsets) { + VaultTile? neighbor = subj.tiles.get(x + dx, y + dy); + if (canSupportArch(neighbor)) { + supporters++; + } + } + + if (supporters == 2) { + newArches.add((x, y)); + } + subj.tiles.set(x, y, VaultTile.wall); + } + if (t == VaultTile.archpronewall || t == VaultTile.defaultwall) { + subj.tiles.set(x, y, VaultTile.wall); + } + } + } + + for (var (ax, ay) in newArches) { + subj.tiles.set(ax, ay, VaultTile.floor); + } + return subj; + } } diff --git a/lib/gen/vault.dart b/lib/gen/vault.dart index ed21ec8..215d472 100644 --- a/lib/gen/vault.dart +++ b/lib/gen/vault.dart @@ -14,12 +14,17 @@ class Vault { return Vault(Bitmap.blank(vx, vy, lt), smooth); } + static Vault blankWith( + int vx, int vy, VaultTile Function(int, int) lt, DirectionSet smooth) { + return Vault(Bitmap.blankWith(vx, vy, lt), smooth); + } + void clear(VaultTile lt) { tiles.clear(lt); } void blitFrom(Vault other, int dx, int dy) { - tiles.blitFrom(other.tiles, dx, dy); + tiles.blitFromWith(other.tiles, dx, dy, mergeVaultTile); } Vault flip() { @@ -34,3 +39,16 @@ class Vault { return Vault(tiles.rotateLeft(), smooth.rotateLeft()); } } + +VaultTile mergeVaultTile(VaultTile bottom, VaultTile top) { + if (bottom == VaultTile.wall && top == VaultTile.archpronewall) { + return VaultTile.wall; + } + if (bottom == VaultTile.wall && top == VaultTile.archwall) { + return VaultTile.wall; + } + if (bottom == VaultTile.archwall && top == VaultTile.archpronewall) { + return VaultTile.archwall; + } + return top; +} diff --git a/lib/gen/vaults.dart b/lib/gen/vaults.dart index 620aa6c..f7b9bc5 100644 --- a/lib/gen/vaults.dart +++ b/lib/gen/vaults.dart @@ -73,6 +73,9 @@ enum VaultTile { door, bspfloor, floor, + defaultwall, // defaultwall is in generated rooms and is overwritten by anything + archpronewall, // archpronewall cannot overwrite wall or archwall + archwall, // archwall cannot overwrite wall. wall, } @@ -91,6 +94,10 @@ VaultTile? colorToVaultTile(int c) { case 0x000000: case 0x707070: return VaultTile.wall; + case 0xFF8000: + return VaultTile.archwall; + case 0x7F4000: + return VaultTile.archpronewall; case 0xFFFFFF: case 0xFFFF00: case 0xFF00FF: