[HN Gopher] A random dungeon generator that fits on a business c...
       ___________________________________________________________________
        
       A random dungeon generator that fits on a business card (2019)
        
       Author : tosh
       Score  : 150 points
       Date   : 2024-02-18 16:34 UTC (6 hours ago)
        
 (HTM) web link (gist.github.com)
 (TXT) w3m dump (gist.github.com)
        
       | omoikane wrote:
       | https://news.ycombinator.com/item?id=19309378 - A random dungeon
       | generator in C, small enough to fit on a business card (2019) -
       | 42 comments
       | 
       | https://news.ycombinator.com/item?id=19290215 - original post
       | referenced above - 23 comments
        
         | dang wrote:
         | Thanks! Those two threads were just a couple days apart so I've
         | belatedly merged them, yielding:
         | 
         |  _A random dungeon generator that fits on a business card_ -
         | https://news.ycombinator.com/item?id=19290215 - March 2019 (64
         | comments)
        
       | helpfulContrib wrote:
       | Here's a random dungeon generator GAME (get potion, avoid snake,
       | explore dungeon) that fits in 10 lines of BASIC [1] and would
       | probably easily fit on a business card, too:
       | 
       | https://bunsen.itch.io/the-snake-temple-by-rax
       | 
       | ([1] - The 10-line BASIC competition is happening again this
       | year, details here:
       | https://gkanold.wixsite.com/homeputerium/copy-of-rules)
        
         | mysterydip wrote:
         | I love that it includes an explanation too. Thanks for sharing!
        
       | BoppreH wrote:
       | I've always been a fan of generating mazes by randomly printing
       | /, \, or a space. It ends up slanted, and there's obviously no
       | guarantees of solvability, but it's surprisingly good for how
       | simple it is.
       | 
       | Here's a bash version in 50 characters
       | (https://codegolf.stackexchange.com/a/26011/7934):
       | w=(/ \);while :;do echo -n ${w[RANDOM%2]};done
       | 
       | and how it looks like:
       | 
       | https://i.stack.imgur.com/fRX05.png
        
         | heavenlyblue wrote:
         | Surprisingly good for what purpose?
        
           | stevenpetryk wrote:
           | probably fun
        
             | kibwen wrote:
             | It's not much fun to solve because there's no guarantee
             | that a path exists between any given openings on the edge,
             | so it's mostly just "pick a point on the edge at random and
             | see how far you can get". However, it does look very
             | pretty.
        
               | zo1 wrote:
               | It's fast enough that you can just check possible
               | outcomes for whatever criterion you want.
        
         | NelsonMinar wrote:
         | That looks like a variant of Truchet Tiles:
         | https://en.wikipedia.org/wiki/Truchet_tiles
        
         | cbm-vic-20 wrote:
         | This is the modern equivalent of the classic Commodore BASIC
         | 10 PRINT CHR$(205.5+RND(1)); : GOTO 10
        
           | samatman wrote:
           | There's an entire book on this subject: https://10print.org
           | 
           | I can't recommend it without reservation, but if you're
           | curious what a whole book about one line of code is like, you
           | can find out.
        
         | rav wrote:
         | > there's obviously no guarantees of solvability
         | 
         | In fact, as the size of the maze goes to infinity, the
         | probability of solvability goes to zero. Source:
         | https://cstheory.stackexchange.com/a/32381/20581
        
       | ttyyzz wrote:
       | I heard you like javascript so here you go:
       | 
       | const H = 40; const W = 80; let m = new Array(H).fill().map(() =>
       | new Array(W).fill(" "));
       | 
       | function g(x) { return Math.floor(Math.random() * x); }
       | 
       | function cave(s) { const w = g(10) + 5; const h = g(6) + 3; let t
       | = g(W - w - 2) + 1; let u = g(H - h - 2) + 1;                 for
       | (let y = u - 1; y < u + h + 2; y++) {         for (let x = t - 1;
       | x < t + w + 2; x++) {           if (m[y][x] === ".") return;
       | }       }            let d = 0;       let e, f;            if
       | (!s) {         for (let y = u - 1; y < u + h + 2; y++) {
       | for (let x = t - 1; x < t + w + 2; x++) {             const s = x
       | < t || x > t + w;             const v = y < u || y > u + h;
       | if (s ^ v && m[y][x] === "#") {               d++;
       | if (g(d) === 0) {                 e = x;                 f = y;
       | }             }           }         }         if (d === 0)
       | return;       }            for (let y = u - 1; y < u + h + 2;
       | y++) {         for (let x = t - 1; x < t + w + 2; x++) {
       | const s = x < t || x > t + w;           const v = y < u || y > u
       | + h;                m[y][x] = s && v ? "!" : s ^ v ? "#" : ".";
       | }       }            if (d > 0) m[f][e] = g(2) ? "'" : "+";
       | for (let j = 0; j < (s ? 1 : g(6) + 1); j++) {         m[g(h) +
       | u][g(w) + t] = s           ? "@"           : g(4) === 0
       | ? "$"           : String.fromCharCode(65 + g(62));       }
       | 
       | }
       | 
       | function main() { for (let y = 0; y < H; y++) { for (let x = 0; x
       | < W; x++) { m[y][x] = " "; } }                 for (let j = 0; j
       | < 1000; j++) {         cave(j === 0);       }            for (let
       | y = 0; y < H; y++) {         let row = "";         for (let x =
       | 0; x < W; x++) {           const c = m[y][x];           row += c
       | === "!" ? "#" : c;         }         console.log(row);       }
       | 
       | }
       | 
       | main();
        
         | MenhirMike wrote:
         | Your business cards must be huge.
        
         | ammanley wrote:
         | I don't like this business card :( -- me, a JS dev far too
         | often
         | 
         | (but also, thank you for sharing this!)
        
           | actionfromafar wrote:
           | Haha thanks for this laugh!
        
       | swayvil wrote:
       | Suave.
       | 
       | The output reminds me of nethack.
        
       | bartvk wrote:
       | I'd love a random dungeon generator that includes multiple
       | plateaus inside one room. For example, a dungeon with a waterfall
       | or a tree.
       | 
       | Whenever I'd run an adventure, my players would often try me out,
       | and open a door of some sorts. But the 2D maps feel very
       | artificial. Guillaume Tavernier on Patreon makes maps with
       | plateaus and multiple stories:
       | https://www.patreon.com/dearchitecturart
       | 
       | A generator like that, would be awesome.
        
       | skykooler wrote:
       | The comments on that introduced me to cxx, which is also a really
       | neat thing to learn about!
        
       | a1o wrote:
       | Someone deobfuscated it here
       | 
       | https://gist.github.com/Joker-vD/cc5372a349559b9d1a3b220d5ea...
       | 
       | Pretty interesting reading this code. Also nice to see things
       | written in C around here.
        
       | IAmNotACellist wrote:
       | Now also make it a text QR code
        
       | SethMLarson wrote:
       | Love the "on a business card" format, thank you for creating this
       | and sharing!
        
       | bheadmaster wrote:
       | I saw this post about 2 hours ago, and I was fascinated by it and
       | curious how it worked. So I decided to de-obfuscate it and add
       | comments.
       | 
       | The code was too large for a comment, so here's the gist:
       | 
       | https://gist.github.com/paskozdilar/48d7532733ccd11144bb43fe...
       | 
       | The approach is quite interesting - it (ab)uses the preprocessor
       | to shorten the syntax of for loops:                   #define
       | l(a, b, c, d) for (int y = a; y < b; y++) for (int x = c; x < d;
       | x++)
       | 
       | And then it does the heavy lifting by iterating over the whole
       | map thousand times, randomly selecting a rectangle on the map and
       | checking if the selected area is adjacent to an already-generated
       | cave. It's a probabilistic algorithm, so there's a _tiny_ chance
       | that it will just print a single cave in the middle and nothing
       | else.
       | 
       | EDIT: Then I found that many other people also de-obfuscated it
       | in the gist comments. :') This guy did a much better job than me:
       | 
       | https://gist.github.com/Joker-vD/cc5372a349559b9d1a3b220d5ea...
        
       | userbinator wrote:
       | That functionality could probably fit in 1 line of APL... which
       | means a business card could be enough space for a _3D renderer_
       | of the random dungeon.
       | 
       | Related: https://news.ycombinator.com/item?id=6425714
       | 
       | Of course there's the demoscene productions where binary size is
       | the measure (no cheating by using lots of libraries); and in a 1K
       | binary, comparable in size to this source, they've gone much
       | further with what can be generated.
        
       | tanepiper wrote:
       | Love/hate that in 2023 someone is still writing CoffeeScript
        
       ___________________________________________________________________
       (page generated 2024-02-18 23:00 UTC)