Generate ASCII wilderness map

8

4

Generate an ASCII wilderness map.

Example output:

................^^^^
..................^^
...^^^^........o....
.....^^^^...........
....................
........o....TT.....
..TTTT..............
TTTT.TTTT....~~~~~~.
..TT..........~~~~~~
....................

Anti-example (don't do this):

....................
...........T........
...^..........oo....
......^.............
....................
..............TT....
T.T.T.T.T........T..
.................T..
T.T.T.T.T..........T
..............TT...T

Rules:

  1. Must be at least 20x10 characters in size
  2. Must be different each run, i.e. random
  3. Must contain continuous and varying shape areas of trees 'T', hills '^' and water '~', most of which should consist of more than 5 cells
  4. The default, ground character is '.'
  5. Must contain at least 2 villages 'o' that are usually not next to each other
  6. Must not contain obvious patterns, such as rectangles or evenly spaced areas - "natural look" is the key
  7. You don't need to explicitly check that the rules are followed (e.g. no need for anti-rectangle logic), but the great majority of the runs (say, 80%) must produce conforming results
  8. With your submission, include an example output

Scoring:

Winner has lowest score from formula: code character count - votes

Tapio

Posted 2012-07-19T07:28:49.427

Reputation: 231

Question was closed 2015-02-02T23:00:35.603

You mention "conforming results" and "the rules [being] followed", but don't explain what that means, exactly. What are those rules to conform to, and what, exactly, is wrong with your second example? – KSFT – 2015-01-31T20:03:59.217

Answers

5

APL (99 76)

F←⍳S←10 20⋄'.T^~^To'[⊃7⌊1++/(⊂7×F∊{?S}¨⍳2),T×{F∊(?S)∘+¨+\{2-?3 3}¨⍳99}¨T←⍳3]

A bit longer than it needs to be (so that it gives better output) but I'll shorten it when the Golfscript answer comes in.

The GolfScript answer was posted so here's a shorter one. I thought of another (rather obvious, in hindsight) way to shorten it so that the output is not much worse than the original program, and it's even shorter than my original backup plan.

(In the old version, I had five bitfields that I was xor-ing with each other, now I have three that I am adding to each other.)

I have replaced the example output with output of the new version, of course.

Explanation:

  • F←⍳S←10 20: size is 20x10, F is a matrix where each element is its coordinates
  • {F∊(?S)∘+¨+\{2-?3 3}¨⍳99}¨T←⍳5: generate 3 bitfields, by starting at a random coordinate, and taking 99 random steps to a neighbouring field and then setting that bit on. 99 seems high but it often backtracks as it is random. This makes the maps for the areas.
  • (⊂7×F∊{?S}¨⍳2): Add in two villages.
  • ⊃7⌊1++/: sum the areas, giving a matrix where each number represents a certain type. Cap it at 7, because the villages might appear in another area giving high numbers.
  • '.T^~^To'[...]: replace each number with the right character. There are 3 possibly overlapping fields so the highest possible value is 6. (3+3)

Example output:

....TTT.TTT...TTT.^^
...TT....TTT....T..^
....T....TT.......^^
...~..o..T..^^...^^.
...~.........^^^^^^^
...~~~~....^^..^^^..
~..~~~......^.^.^^^^
~~.~~~......^^.^^^..
~.~~~~........o.....
~~~~~~..............

and

.....o........~~..~~
..............~~~~~.
.^T.T..........~~.~.
^T~~TTTTTT.......~~~
~~~~TT.TT.T......~~~
^~^TTT....T.....~~~~
^^^^T.....T...T..~~.
^^^^.......TT.T.....
^^^^.........TT.....
^^^^.........o......

Old version:

F←⍳S←10 20⋄G←{F∊(?S)∘+¨+\{2-?3 3}¨⍳99}¨T←⍳5⋄'.T^~^To'[⊃7⌊1++/(⊂7×F∊{?S}¨⍳2),T×{(⊃⍵⌽G)∧~⊃∨/1↓⍵⌽G}¨T]

marinus

Posted 2012-07-19T07:28:49.427

Reputation: 30 224

The output is almost exactly how I imagined the best possible result would be like! – Tapio – 2012-07-19T14:49:57.163

4

JavaScript - 294 290 characters

To encourage attempts, I took a crack at this myself. You can try a live demo here (you need to open your browser's JS console). Tested with Chrome and IE8.

R=function(a){return Math.random()*a|0};t=["~","T"];t.splice(R(3),0,"^");p=["XXX..","XXXX.","XXXXX"];b="....................";for(i=j=0;10>i;++i)j=i%3?j:R(15),s=b.substr(0,i%3?j+R(2):20),s+=p[R(3)].replace(/X/g,t[i/3|0])+b,k=R(19),console.log(s.substr(0,k)+".o"[i%2*R(2)]+s.substr(k,19-k));​

Example output:

....................
.......~~~..........
........~~~~~.......
...o................
...............TT.TT
..........o....TTTTT
....................
.....^^^.o..........
.....^^^^^..........
..................o.

It's not ideal, as there is always only three areas (one of each kind), their maximum size is 5x2 cells and after a few runs, you start to notice limitations in their (and villages') placement. However, it fulfills the rules.

Tapio

Posted 2012-07-19T07:28:49.427

Reputation: 231

3

GolfScript, 97 characters

"T~^o"1/{:z{[20:s.*:<rand{.[s~)1-1s]4rand=+}z"o"=!9**]}3*++}%2/:x;<,{"."x{)3$\?)!!*+}/\;-1=}%s/n*

Example outputs:

.............~......
...........~.~~.....
........~~~~~~......
........~~~.........
.......~~~..........
.......~............
..^^..............T.
^^^^...........o..T.
...^....TTT...^...T^
^........TT.o.^^^.^^
^.......TT.....^^.T.
........T......^.TT.
................TT..
....................
....~~~.............
....~.~.............
..~o~...............
..~.....TTTT........
.......TT..TT.......
....................

and

.............~......
.............~......
....TTT.....~~TT....
....T.T.....~~TT....
....TT......~~~TT...
.....T.....~~~~T....
.......^^.~~~~......
......^^^..~~.......
......^.^...........
....................
..^^^^..............
..^..^^.............
....^^^^^...........
.......o........TT..
................TT..
....................
......o.............
.............o......
....................
....................

Howard

Posted 2012-07-19T07:28:49.427

Reputation: 23 109

2

Ruby 1.9 (127 116 112 107)

m=?.*o=W=200
29.times{|i|o+=i%9-i/28>0?[-1,1,20].sample: rand(W);m[o%W]='T~^'[i/9]||?o}
puts m.scan /.{20}/

The output is a bit plain, but I think it mostly meets the spec!

Some example outputs:

....................
........TTTTTTT.....
........T^^^........
.........^..........
.........^..........
.........^^^.o......
....................
.....~.o............
...~~~..............
...~~~~~............

Another:

.....^^.............
......^^............
.......^^...........
...........o........
....................
..............T~~~..
.............TT~~...
.............T.~....
.............T.~....
.o..^^.......TT~....

And again:

.....TT.............
..............~.....
..............~.....
..............~~....
..............~~~...
........^^^.........
....o.T...^.........
......TT..^^^.......
..o..TT....^^.......
.....T..............

Due to the way it's coded, there's almost always a lone tree. I like to imagine it's the Deku tree.

Paul Prestidge

Posted 2012-07-19T07:28:49.427

Reputation: 2 390

1

Q (116 107 char)

Here's one in Q

(-1')20 cut@[199{.[t!`s#'(0 20 20 20;0 0 20 20;0 0 0 20;0 1 2 3)!\:t:"T^~.";(x;rand 30)]}\".";2?200;:;"o"];

Sample output

...........o........
...~~....TTTT..~~o..
......TTTTTTTTT....T
T...................
......^^^........TTT
...~~~~.............
....................
............^^......
..~~~..^^^^^^.......
....~..............T

and

..........^^^..^...o
....................
........^.T.........
.......~~...^.......
....................
....TTTTTTTT....^...
..~.................
.o.....^^^^^.......T
............~~~~~~~~
~~~~~....TTT........

and

....................
...~~~~~~~~~~.....~.
................TT..
....TTTTT..~.TT.TTTT
T................TTT
TTT..........TTTTTTT
TTT....T............
........T.......TToT
TTT..............^^.
...TTT..^.~~~~.o....

I can tweak the stochastic matrix to affect the output but I think the above conforms what you're looking for.

/edit: tweaked output

/edit: reduced char count by only adding 2 villages

skeevey

Posted 2012-07-19T07:28:49.427

Reputation: 4 139

It violates rule 3: Must contain continuous and varying shape areas of trees 'T', hills '^' and water '~', most of which should consist of more than 5 cells - most of your areas are of size 1. – Tapio – 2012-07-19T13:11:08.073

I'm terrible for reading rules...I've tweaked the distribution, I think it's more conformant now. – skeevey – 2012-07-19T13:13:26.420

Aesthetically some of them are bit too noisy for my taste (too many one character areas), but it follows the rules now (I didn't really do counting, but visually it's close enough), is definitely more random than my solution, very compact etc. Well done! – Tapio – 2012-07-19T13:26:39.700

1

K, 84

f:{,/{x+!y}'[5?200;5?10]};m::200#".";{@[`m;x;:;y]}'[(f`;f`;f`;2?200);"~T^o"];10 20#m

Output:

"...................T"
"TTTTT~....TTT...^^^."
"...................^"
"^^..............^^^^"
"^^^..~~~~.......^^o."
".........TTTTT......"
"..~~~~~~........TTTT"
"TTT.~..............."
".........o.....^^^^."
"..........TTTTT....."

and

"...............~~~.."
".......~~~~~......TT"
"TTTT.^^^^^^^^......."
"....TT......~~......"
"..........^........."
"...........oTTT..^^^"
"^^^^^^..........^^^^"
"^^...TTTTTTT........"
"................o.~~"
"~~~.............T..."

tmartin

Posted 2012-07-19T07:28:49.427

Reputation: 3 917