Author Topic: ISO simple ASCII procedural terrain  (Read 8187 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #15 on: November 10, 2021, 10:15:08 pm »
Don't know what DF characters are?

Char Editor is for 8 X16 Font and I was modifying for 8x8 font I think.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #16 on: November 10, 2021, 10:27:56 pm »
Code: QB64: [Select]
  1. _Title "8X16 ASCII Character Editor"
  2. 'started 2018-08-27 by bplus
  3. 'QB64 X 64 version 1.2 20180228/86  from git b301f92
  4. ' 2020-09-18 modified to coexist with the 8X8 Character Editor in the same Folder
  5.  
  6. '========================== Instructions: =================================
  7. '
  8. ' Arrow keys move the highlighter around, spacebar toggles tile on/off
  9. ' or just click with mouse to do the same.
  10.  
  11. ' Click buttons to either
  12. ' 1. Enter an ascii by number to edit.
  13. ' 2. Enter a character by pressing the key(s) from which the ascii number is taken.
  14. ' 3. Save a modified character.
  15. ' 4. Save all edits made to file called "Character Set.DAT".
  16. ' Note: If want to work with more sets, just rename Character Set.DAT
  17. '       If that file isn't found, this app will start from scratch.
  18. '
  19. '==========================================================================
  20. Const cFile$ = "8X16 Character Set.DAT"
  21. Const CW = 8
  22. Const CH = 16
  23. Const SQ = 25
  24. Const XOFF = 60
  25. Const YOFF = 80
  26. Const WW = 800
  27. Const WH = 600
  28. Screen _NewImage(WW, WH, 32)
  29. _ScreenMove (1280 - WW) / 2 + 30, (760 - WH) / 2
  30. Dim Shared AN%, CX, CY, BLK As _Unsigned Long, WHT As _Unsigned Long, SAVED
  31. Dim Shared MAP(CW + 2, CH + 2) As String * 1
  32. Dim Shared CS(256) As String * 128
  33. WHT = _RGB32(255, 255, 255)
  34. BLK = _RGB32(0, 0, 0)
  35.  
  36. '==============================   main
  37.  
  38. 'see if there is a file in the works to load else start from scratch
  39.     Open cFile$ For Input As #1
  40.     For i = 1 To 256
  41.         Input #1, CS(i - 1)
  42.     Next
  43.     Close #1
  44.     SAVED = -1
  45.     For a = 0 To 255
  46.         Cls
  47.         _PrintString (0, 0), Chr$(a)
  48.         b$ = ""
  49.         For y = 0 To CH - 1
  50.             For x = 0 To CW - 1
  51.                 If Point(x, y) <> BLK Then b$ = b$ + "1" Else b$ = b$ + "0"
  52.             Next
  53.         Next
  54.         CS(a) = b$
  55.     Next
  56.     SAVED = 0
  57.  
  58. For i = 1 To 128
  59.     Print Mid$(CS(1), i, 1);
  60.     If i Mod CW = 0 Then Print
  61. 'END
  62. 'sample B for starters
  63. AN% = 66
  64. load AN%
  65. CX = 1: CY = 1
  66.         mx = _MouseX
  67.         my = _MouseY
  68.         _Delay .2
  69.         'ascii #  to edit
  70.         If mx > 500 And mx < 700 And my > 50 And my < 100 Then
  71.             Color WHT, 0
  72.             Line (500, 50)-(700, 100), BLK, BF
  73.             Locate 5, 67: Input "Ascii # "; a%
  74.             If a% >= 0 And a% <= 255 Then AN% = a%: load AN%
  75.         End If
  76.         'chr$  to edit
  77.         If mx > 500 And mx < 700 And my > 110 And my < 160 Then
  78.             Color WHT, 0
  79.             Line (500, 110)-(700, 160), BLK, BF
  80.             Locate 9, 67: Input "Enter Chr$ "; char$
  81.             a% = Asc(char$)
  82.             If a% >= 0 And a% <= 255 Then AN% = a%: load AN%
  83.         End If
  84.         'save character edit
  85.         If mx > 500 And mx < 700 And my > 170 And my < 220 Then
  86.             b$ = ""
  87.             For y = 1 To CH
  88.                 For x = 1 To CW
  89.                     b$ = b$ + MAP(x, y)
  90.                 Next
  91.             Next
  92.             CS(AN%) = b$
  93.             Color WHT, 0
  94.             Line (500, 170)-(700, 220), BLK, BF
  95.             Locate 13, 67: Print " Character recorded. "
  96.             SAVED = 0
  97.             _Display
  98.             _Delay 1.5
  99.         End If
  100.         'file character set
  101.         If mx > 500 And mx < 700 And my > 230 And my < 280 Then
  102.             Color WHT, 0
  103.             Line (500, 230)-(700, 280), BLK, BF
  104.             Open cFile$ For Output As #1
  105.             For a = 0 To 255
  106.                 Print #1, CS(a)
  107.             Next
  108.             Close #1
  109.             Locate 16, 65: Print cFile$
  110.             Locate 17, 71: Print "File Saved"
  111.             SAVED = -1
  112.             _Display
  113.             _Delay 1.5
  114.         End If
  115.  
  116.         'mouse over edit box, toggle tiles and update cursor
  117.         tx = (mx - XOFF) \ SQ: ty = (my - YOFF) \ SQ
  118.         If tx >= 1 And tx <= CW And ty >= 1 And ty <= CH Then
  119.             CX = tx: CY = ty
  120.             If MAP(CX, CY) = "1" Then MAP(CX, CY) = "0" Else MAP(CX, CY) = "1"
  121.         End If
  122.     End If
  123.     KH& = _KeyHit
  124.     Select Case KH&
  125.         Case 32 'space bar
  126.             If MAP(CX, CY) = "1" Then MAP(CX, CY) = "0" Else MAP(CX, CY) = "1"
  127.         Case 18432 'up
  128.             If CY - 1 >= 1 Then CY = CY - 1
  129.         Case 20480 'down
  130.             If CY + 1 <= CH Then CY = CY + 1
  131.         Case 19200 'left
  132.             If CX - 1 >= 1 Then CX = CX - 1
  133.         Case 19712 'right
  134.             If CX + 1 <= CW Then CX = CX + 1
  135.     End Select
  136.  
  137.     If _KeyDown(27) Then End
  138.     update
  139.     _Display
  140.     _Limit 60
  141.  
  142. Sub load (asci)
  143.     For i = 1 To 128
  144.         y = i \ CW + 1
  145.         x = i Mod CW: If x = 0 Then x = 8: y = y - 1
  146.         MAP(x, y) = Mid$(CS(asci), i, 1)
  147.     Next
  148.  
  149. Sub update
  150.     Color WHT, _RGB32(100, 110, 100): Cls
  151.     drwBtn 500, 50, "Load map with Ascii"
  152.     drwBtn 500, 110, "Load map with Chr$"
  153.     drwBtn 500, 170, "Save Character Edit"
  154.     drwBtn 500, 230, "File Character Set"
  155.     Color _RGB32(250, 225, 255), _RGB32(100, 110, 100)
  156.     _PrintString (398, 400), "Current Ascii% =" + Str$(AN%) + " or CHR$(" + LTrim$(Str$(AN%)) + ") = " + Chr$(AN%)
  157.     If SAVED Then s$ = " Saved." Else s$ = " not Saved yet."
  158.     _PrintString (398, 440), "File: " + cFile$ + s$
  159.     Line (XOFF - 1, YOFF - 1)-Step((CW + 2) * SQ + 2, (CH + 2) * SQ + 2), _RGB32(255, 255, 0), B
  160.     Line (XOFF + 1, YOFF + 1)-Step((CW + 2) * SQ, (CH + 2) * SQ), BLK, B
  161.     Line (XOFF, YOFF)-Step((CW + 2) * SQ, (CH + 2) * SQ), _RGB32(255, 80, 0), BF
  162.     For y = 1 To CH
  163.         For x = 1 To CW
  164.             If MAP(x, y) = "1" Then c& = _RGB32(200, 200, 200) Else c& = _RGB32(0, 0, 0)
  165.             Line ((x) * SQ + XOFF, (y) * SQ + YOFF)-Step(SQ - 2, SQ - 2), c&, BF
  166.         Next
  167.     Next
  168.     ' let's see actual size!
  169.     Color _RGB32(255, 255, 0), _RGB32(100, 110, 100)
  170.     For i = 1 To 4
  171.         drwChar XOFF + 16 * (i * 2), .5 * YOFF - (16 * i) / 2, AN%, i
  172.     Next
  173.     'highlight sqr
  174.     Line (CX * SQ - 1 + XOFF, CY * SQ - 1 + YOFF)-Step(SQ, SQ), WHT, B
  175.  
  176.  
  177. Sub drwBtn (x, y, s$)
  178.     th = 16: tw = 8 * Len(s$): gray& = _RGB32(190, 190, 190)
  179.     Line (x, y)-Step(200, 50), _RGB32(0, 0, 0), BF
  180.     Line (x, y)-Step(197, 47), _RGB32(255, 255, 255), BF
  181.     Line (x + 1, y + 1)-Step(197, 47), gray&, BF
  182.     Color _RGB32(0, 0, 0), gray&
  183.     _PrintString (x + 100 - 4 * Len(s$), y + 17), s$
  184.  
  185. Sub drwChar (x0, y0, ascn, size) 'what ever the present color is set at
  186.     For y = 0 To CH - 1
  187.         For x = 0 To CW - 1
  188.             i = i + 1
  189.             If Mid$(CS(ascn), i, 1) = "1" Then Line (x0 + x * size, y0 + y * size)-Step(size - 1, size - 1), , BF
  190.         Next
  191.     Next
  192.  

It will use custom charaacter set in this file: "8X16 Character Set.DAT"
if it finds it in the folder of the .exe otherwise it will start that file and when you slect save file it will make your character set with custom changes.

If you want several custom sets just change name of file, and change it back to "8X16 Character Set.DAT" to edit that one again.

Of course, you will need some routines for using these characters in you game file. I think I have a test demo somewhere.

Also looks like 8 x 8 editor is done too.
  [ You are not allowed to view this attachment ]  

Wow over 3 years ago!
« Last Edit: November 10, 2021, 10:33:02 pm by bplus »

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #17 on: November 10, 2021, 10:50:04 pm »
Don't know what DF characters are?

Char Editor is for 8 X16 Font and I was modifying for 8x8 font I think.

dwarf fortress (one of the hardest games ever created - even has an O'Reilly book on how to play - Im like seriously - ofc I bought it LOL)
https://i.pinimg.com/originals/96/3d/4f/963d4f5d54e5d0e90ee6d7b23d140bff.jpg
https://www.amazon.com/Getting-Started-Dwarf-Fortress-complex/dp/1449314945

I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #18 on: November 10, 2021, 10:51:39 pm »
Yes! I would be interested in that. It is almost like a modern THEDRAW program!
or more precisely TDFONTS program.
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #19 on: November 10, 2021, 10:53:13 pm »
OK end result it actually accpetable. Obviously clean up the code.
will prob add a routine to add a river, maybe one or two lakes. and a range of hardcore mountains!

add color and poof
Code: QB64: [Select]
  1.  
  2.  
  3.  
  4. Dim tile(5) As String
  5. Dim area(75, 20) As Integer
  6.  
  7. tile(1) = "T"
  8. tile(2) = "."
  9. tile(3) = "="
  10. tile(4) = "~"
  11. tile(5) = " "
  12.  
  13. '// Clear the map
  14. For i = 1 To 75: For j = 1 To 20: area(i, j) = 0: Next: Next
  15.  
  16. '// lets try some random squares
  17. For i = 1 To 40 ' <-- bigger number more dense
  18.     x = r(75)
  19.     y = r(20)
  20.     For k = y - 1 To y + 1
  21.         For j = x - 5 To x + 5
  22.             If j > 0 And j < 76 And k > 0 And k < 21 Then
  23.                 area(j, k) = 1
  24.             End If
  25.  
  26.         Next
  27.     Next
  28.  
  29. For i = 1 To 20 ' <-- bigger number more dense
  30.     x = r(72)
  31.     y = r(18)
  32.     For k = y - 1 To y + 1
  33.         For j = x - 5 To x + 5
  34.             If j > 0 And j < 76 And k > 0 And k < 21 Then
  35.                 area(j, k) = 2
  36.             End If
  37.  
  38.         Next
  39.     Next
  40.  
  41. For i = 1 To 10 ' <-- bigger number more dense
  42.     x = r(72)
  43.     y = r(18)
  44.     For k = y - 1 To y + 1
  45.         For j = x - 5 To x + 5
  46.             If j > 0 And j < 76 And k > 0 And k < 21 Then
  47.                 area(j, k) = 3
  48.             End If
  49.  
  50.         Next
  51.     Next
  52.  
  53. For i = 1 To 5 ' <-- bigger number more dense
  54.     x = r(72)
  55.     y = r(18)
  56.     For k = y - 1 To y + 1
  57.         For j = x - 5 To x + 5
  58.             If j > 0 And j < 76 And k > 0 And k < 21 Then
  59.                 area(j, k) = 4
  60.             End If
  61.  
  62.         Next
  63.     Next
  64.  
  65. For y = 1 To 20
  66.     For x = 1 To 75
  67.         If area(x, y) = 0 Then area(x, y) = 247
  68.     Next
  69.  
  70.  
  71.  
  72.  
  73.  
  74.  
  75. For j = 1 To 20
  76.     For i = 1 To 75
  77.  
  78.         Select Case area(i, j)
  79.             Case 0: Print " ";
  80.             Case 1: Print "T";
  81.             Case 2: Print "#";
  82.             Case 3: Print ".";
  83.             Case 4: Print ".";
  84.             Case 247: Print Chr$(area(i, j));
  85.  
  86.         End Select
  87.     Next
  88.  
  89.     Print
  90.  
  91.  
  92.     r = Int(Rnd * num) + 1
  93.  
I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #20 on: November 10, 2021, 11:32:06 pm »
Oh hey, rndRect!
Code: QB64: [Select]
  1. _Title "RndRect - zzz... press any, esc to quit"
  2.     For i = 1 To 250
  3.         rndRect
  4.     Next
  5.     Sleep
  6.  
  7. Sub rndRect
  8.     c$ = Chr$(Int(Rnd * 200) + 32)
  9.     x = Int(Rnd * 80) + 1
  10.     y = Int(Rnd * 25) + 1
  11.     w = Int(Rnd * 30) + 1
  12.     h = Int(Rnd * 8) + 1
  13.     For row = y To y + h
  14.         For col = x To x + w
  15.             If row <= 25 And col <= 80 Then
  16.                 Locate row, col: Print c$;
  17.             End If
  18.         Next
  19.     Next
  20.  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #21 on: November 10, 2021, 11:37:16 pm »
Colorized version
Code: QB64: [Select]
  1. _Title "RndRect - zzz... press any, esc to quit"
  2.     For i = 1 To 250
  3.         rndRect
  4.     Next
  5.     Sleep
  6.  
  7. Sub rndRect
  8.     c$ = Chr$(Int(Rnd * 200) + 32)
  9.     x = Int(Rnd * 80) + 1
  10.     y = Int(Rnd * 25) + 1
  11.     w = Int(Rnd * 30) + 1
  12.     h = Int(Rnd * 8) + 1
  13.     Color Int(Rnd * 15) + 1 '  Int(Rnd * 15) + 1
  14.     For row = y To y + h
  15.         For col = x To x + w
  16.             If row <= 25 And col <= 80 Then
  17.                 Locate row, col: Print c$;
  18.             End If
  19.         Next
  20.     Next
  21.  
« Last Edit: November 10, 2021, 11:44:04 pm by bplus »

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #22 on: November 10, 2021, 11:42:58 pm »
With limited tile() set:
Code: QB64: [Select]
  1. _Title "RndRect - zzz... press any, esc to quit"
  2.  
  3. tile(1) = "T"
  4. tile(2) = "."
  5. tile(3) = "="
  6. tile(4) = "~"
  7. tile(5) = " "
  8.  
  9.     For i = 1 To 250
  10.         rndRect
  11.     Next
  12.     Sleep
  13.  
  14. Sub rndRect
  15.     c$ = tile(Int(Rnd * 5) + 1)
  16.     x = Int(Rnd * 80) + 1
  17.     y = Int(Rnd * 25) + 1
  18.     w = Int(Rnd * 30) + 1
  19.     h = Int(Rnd * 8) + 1
  20.     'Color Int(Rnd * 15) + 1 '  Int(Rnd * 15) + 1   ' Color or Not ?
  21.     For row = y To y + h
  22.         For col = x To x + w
  23.             If row <= 25 And col <= 80 Then
  24.                 Locate row, col: Print c$;
  25.             End If
  26.         Next
  27.     Next
  28.  

Offline xra7en

  • Seasoned Forum Regular
  • Posts: 284
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #23 on: November 11, 2021, 12:12:53 am »
nice - but grouping is off (something I am still struggling with)

trees should be surrounded by bushes, surrounded by maybe grass, and plains, and clearing near body of water.
so far we have random blocks, but not making sense LOL

cept now its late,,, will tackle tomorrow at work (i have my own hours hahhaaha)

I just like re-writing old DOS book games into modern QB64 code - weird hobby, I know!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #24 on: November 11, 2021, 12:28:42 am »
Here is Font 8 so I can add round circles:
Code: QB64: [Select]
  1. _Title "RndRect - zzz... press any, esc to quit"
  2.  
  3. tile(1) = "T"
  4. tile(2) = "."
  5. tile(3) = "="
  6. tile(4) = "~"
  7. tile(5) = "#"
  8.  
  9. Width 80, 80
  10.     For i = 1 To 50
  11.         rndRect
  12.     Next
  13.     Sleep
  14.  
  15. Sub rndRect
  16.     c$ = tile(Int(Rnd * 5) + 1)
  17.     x = Int(Rnd * _Width) + 1
  18.     y = Int(Rnd * _Height) + 1
  19.     w = Int(Rnd * 15) + 1
  20.     h = Int(Rnd * 15) + 1
  21.     'Color Int(Rnd * 15) + 1 '  Int(Rnd * 15) + 1   ' Color or Not ?
  22.  
  23.     If Rnd < .5 Then
  24.         For row = y To y + h
  25.             For col = x To x + w
  26.                 If row <= _Height And col <= _Width Then
  27.                     Locate row, col: Print c$;
  28.                 End If
  29.             Next
  30.         Next
  31.     Else
  32.         For row = y - h To y + h
  33.             For col = x - h To x + h
  34.                 If row >= 1 And row <= _Height Then
  35.                     If col > 1 And col <= _Width Then
  36.                         If Sqr(((col - x) ^ 2) + (row - y) ^ 2) <= h Then
  37.                             Locate row, col: Print c$;
  38.                         End If
  39.                     End If
  40.                 End If
  41.             Next
  42.         Next
  43.  
  44.     End If

Circles look more natural but what we really need is plasma!

Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: ISO simple ASCII procedural terrain
« Reply #25 on: November 11, 2021, 12:49:21 am »
Here's my first shot at this:

Code: QB64: [Select]
  1. Const XSize = 200, YSize = 200
  2. Dim Shared As Long Grid(XSize, YSize)
  3.  
  4. DisplayScreen = MaxScreen
  5. Screen MaxScreen
  6.  
  7.  
  8.     InitializeMap
  9.     Rivers Int(Rnd * 10) + 1, Int(Rnd * 100) - 100, -3
  10.     GenerateTerrain
  11.  
  12.     DrawMap
  13.     Sleep
  14.  
  15. Sub InitializeMap
  16.     For x = 0 To XSize
  17.         For y = 0 To YSize
  18.             Grid(x, y) = -999 'default blank part of map
  19.         Next
  20.     Next
  21.  
  22.  
  23. Sub DrawMap
  24.     Dim kolor As _Unsigned Long
  25.     xscale = _Width / XSize
  26.     yscale = _Height / YSize
  27.     For x = 0 To XSize
  28.         For y = 0 To YSize
  29.             Select Case Grid(x, y)
  30.                 Case -3: kolor = DarkBlue 'Deep Water
  31.                 Case -2: kolor = Blue 'Water
  32.                 Case -1: kolor = SkyBlue 'Shallow Water
  33.                 Case 0: kolor = Tann 'beach/sand
  34.                 Case 1: kolor = Green 'grassland
  35.                 Case 2: kolor = DarkGreen 'forest
  36.                 Case 3: kolor = Pink 'hills
  37.                 Case 4: kolor = Purple 'mountains
  38.                 Case 5 TO 99: kolor = Red
  39.                 Case Else: kolor = Black
  40.             End Select
  41.             Line (x * xscale, y * yscale)-Step(xscale, yscale), kolor, BF
  42.     Next y, x
  43.  
  44.  
  45. Sub GenerateTerrain
  46.     Height = -3
  47.     Do Until finished
  48.         finished = -1
  49.         For x = 0 To XSize
  50.             For y = 0 To YSize
  51.                 If Grid(x, y) = Height Then Fill x, y, Height + 1: finished = 0
  52.             Next
  53.         Next
  54.         Height = Height + 1
  55.     Loop
  56.  
  57.  
  58. Sub Fill (x, y, height)
  59.     Select Case height
  60.         Case Is < 0: RepeatChance = 33 'water repeat
  61.         Case Is = 0: RepeatChance = 25 'beach repeat
  62.         Case Is = 1: RepeatChance = 55 'grassland
  63.         Case Is = 2: RepeatChance = 55 'forest
  64.         Case Is = 3: RepeatChance = 40 ' hills
  65.         Case Is = 4: RepeatChance = 33 'mountains
  66.         Case Else
  67.             RepeatChance = 50 - 3 * height
  68.             If RepeatChance < 10 Then RepeatChance = 10
  69.     End Select
  70.     CurrentX = x
  71.     If CurrentX > 0 Then
  72.         If Grid(CurrentX - 1, y) = -999 Then
  73.             Grid(CurrentX - 1, y) = height
  74.             If Int(Rnd * 100) < RepeatChance Then Fill CurrentX - 1, y, height
  75.         End If
  76.     End If
  77.     CurrentX = x
  78.     If CurrentX < XSize Then
  79.         If Grid(CurrentX + 1, y) = -999 Then
  80.             Grid(CurrentX + 1, y) = height
  81.             If Int(Rnd * 100) < RepeatChance Then Fill CurrentX + 1, y, height
  82.         End If
  83.     End If
  84.     CurrentY = y
  85.     If CurrentY > 0 Then
  86.         If Grid(x, CurrentY - 1) = -999 Then
  87.             Grid(x, CurrentY - 1) = height
  88.             If Int(Rnd * 100) < RepeatChance Then Fill x, CurrentY - 1, height
  89.         End If
  90.     End If
  91.     CurrentY = y
  92.     If CurrentY < YSize Then
  93.         If Grid(x, CurrentY + 1) = -999 Then
  94.             Grid(x, y + 1) = height
  95.             If Int(Rnd * 100) < RepeatChance Then Fill x, CurrentY + 1, height
  96.         End If
  97.     End If
  98.  
  99. Sub Rivers (Number, Meander, Deep)
  100.     For i = 1 To Number
  101.         flip1 = Int(Rnd * 2): flip2 = Int(Rnd * 2)
  102.         If flip1 Then 'entry point is on top
  103.             x1 = Int(Rnd * XSize): y1 = 0
  104.         Else 'entry point is on left
  105.             x1 = 0: y1 = Int(Rnd * YSize)
  106.         End If
  107.         If flip2 Then 'exit point is on bottom
  108.             x2 = Int(Rnd * XSize): y2 = YSize
  109.         Else 'exit point is on right
  110.             x2 = XSize: y2 = Int(Rnd * YSize)
  111.         End If
  112.  
  113.         Grid(x1, y1) = Deep: Grid(x2, y2) = Deep
  114.         StartX = x1: StartY = y1: EndX = x2: EndY = y2 'just to preserve our original values, if needed.
  115.         Do Until StartX = EndX And StartY = EndY
  116.             CoinToss = Int(Rnd * 100) 'Coin toss to move left/right or up/down, to go towards exit, or wander a bit.
  117.             Meander = 10
  118.             If CoinToss Mod 2 Then 'even or odd, so we only walk vertical or hortizontal and not diagional
  119.                 If CoinToss < 100 - Meander Then 'Lower values meander less and go directly to the target.
  120.                     XChange = Sgn(EndX - StartX) '-1,0,1, drawn always towards the mouse
  121.                     Ychange = 0
  122.                 Else
  123.                     XChange = Int(Rnd * 3) - 1 '-1, 0, or 1, drawn in a random direction to let the lightning wander
  124.                     Ychange = 0
  125.                 End If
  126.             Else
  127.                 If CoinToss < 100 - Meander Then 'Lower values meander less and go directly to the target.
  128.                     Ychange = Sgn(EndY - StartY)
  129.                     XChange = 0
  130.                 Else
  131.                     Ychange = Int(Rnd * 3) - 1
  132.                     XChange = 0
  133.                 End If
  134.             End If
  135.             StartX = StartX + XChange
  136.             StartY = StartY + Ychange
  137.             If StartX < 0 Then StartX = 0 'Make certain we move inside the bounds of our map dimensions
  138.             If StartY < 0 Then StartY = 0
  139.             If StartX > XSize Then StartX = XSize
  140.             If StartY > YSize Then StartY = YSize
  141.             Grid(StartX, StartY) = Deep 'place a river where we moved to
  142.         Loop
  143.     Next
  144.  
  145.  
  146.  
  147.  
  148.  
  149. Function MaxScreen
  150.     DH = _DesktopHeight: DW = _DesktopWidth
  151.     TBH = TaskbarHeight: TBW = TaskbarWidth
  152.     TH = TitleBarHeight: BW = BorderWidth
  153.     If TBH = DH Then TBH = 0 'Users taskbar is configured vertical, not hortizonal.
  154.     If TBW = DW Then TBW = 0
  155.     MaxScreen = _NewImage(DW - TBW - 2 * BW, DH - TBH - TH - BW * 2, 32)
  156.  
  157. Sub ScreenMove (x, y)
  158.     Do Until _Width <> 0 And _ScreenExists = -1: Loop
  159.     _ScreenMove x - BorderWidth, y - BorderWidth - TitleBarHeight
  160.  
  161. Sub ScreenMove_Middle
  162.     Do Until _Width <> 0 And _ScreenExists = -1: Loop
  163.     _ScreenMove (_DesktopWidth - _Width - BorderWidth) / 2 + 1, (_DesktopHeight - _Height - BorderWidth) / 2 - TitleBarHeight + 1
  164.  
  165. Function TaskbarHeight
  166.     Do Until _Width <> 0 And _ScreenExists = -1: Loop
  167.  
  168.     $If WIN Then
  169.         $If TASKBARDEC = UNDEFINED Then
  170.             $Let TASKBARDEC = TRUE
  171.             Declare Library "taskbar"
  172.                 Function taskbar_height& ()
  173.                 Function taskbar_width& ()
  174.             End Declare
  175.         $End If
  176.         TaskbarHeight = taskbar_height&
  177.     $Else
  178.         TaskbarHeight = 0 'no function to get the value for Linux/Mac, so return 0 instead of an error
  179.     $End If
  180.  
  181. Function TaskbarWidth
  182.     Do Until _Width <> 0 And _ScreenExists = -1: Loop
  183.     $If WIN Then
  184.         $If TASKBARDEC = UNDEFINED Then
  185.             $Let TASKBARDEC = TRUE
  186.  
  187.             Declare Library "taskbar"
  188.             Function taskbar_height& ()
  189.             Function taskbar_width& ()
  190.             End Declare
  191.         $End If
  192.         TaskbarWidth = taskbar_width&
  193.     $Else
  194.         TaskbarWidth = 0 'no function to get the value for Linux/Mac, so return 0 instead of an error
  195.     $End If
  196.  
  197.  
  198. Function TitleBarHeight
  199.     Do Until _Width <> 0 And _ScreenExists = -1: Loop
  200.     $If BORDERDEC = UNDEFINED Then
  201.         $Let BORDERDEC = TRUE
  202.         Declare Library
  203.             Function glutGet& (ByVal what&)
  204.         End Declare
  205.     $End If
  206.     TitleBarHeight = glutGet(507)
  207.  
  208. Function BorderWidth
  209.     Do Until _Width <> 0 And _ScreenExists = -1: Loop
  210.     $If BORDERDEC = UNDEFINED Then
  211.         $Let BORDERDEC = TRUE
  212.         Declare Library
  213.         Function glutGet& (ByVal what&)
  214.         End Declare
  215.     $End If
  216.     BorderWidth = glutGet(506)

We start by building some rivers across the screen, which would be the lowest point on the map, and then we rise up to build terrain from that point outwards...    beach, plain, forest, hill, mountain, impassable mountains!

Some things to play around with here:

Rivers Int(Rnd * 10) + 1, Int(Rnd * 100) - 100, -3   -- First value is the number of rivers, second is how much they meander across the map, and the third is their starting depth.  Note that I haven't set any colors for a depth < -3.

In the fill sub, there's a section which you can play around with to increase density of various features:

    Select Case height
        Case Is < 0: RepeatChance = 33 'water repeat
        Case Is = 0: RepeatChance = 25 'beach repeat
        Case Is = 1: RepeatChance = 55 'grassland
        Case Is = 2: RepeatChance = 55 'forest
        Case Is = 3: RepeatChance = 40 ' hills
        Case Is = 4: RepeatChance = 33 'mountains
        Case Else
            RepeatChance = 50 - 3 * height
            If RepeatChance < 10 Then RepeatChance = 10
    End Select

The higher the numbers here, the more of the feature your map is going to have...

There's no Ocean on these maps, nor is there any lakes (I think lakes would be a nice addition, rather than just forcing multiple rivers to define the low points of the map), but I think this goes to show how I'd work on generating a map like this.   I'd start at the lowest point and then just expand outwards and upwards to my mountains.  ;)

  [ You are not allowed to view this attachment ]  

NOTE: Grab the taskbar header file for proper sizing from here: https://www.qb64.org/forum/index.php?topic=1020.msg138058#msg138058
« Last Edit: November 11, 2021, 02:51:51 am by SMcNeill »
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #26 on: November 11, 2021, 01:27:44 am »
Here I am building Contours about Random Points:
Code: QB64: [Select]
  1. _Title "Build Contours about Rnd Pts - zzz... press any, esc to quit"
  2. _ScreenMove 400, 60
  3. tile(1) = "."
  4. tile(2) = "~"
  5. tile(3) = "="
  6. tile(4) = "o"
  7. tile(5) = "#"
  8.  
  9. Width 80, 80
  10.  
  11.     Cls
  12.     nP = Rnd * 7 + 3
  13.     ReDim pX(1 To nP), pY(1 To nP)
  14.     For i = 1 To nP
  15.         pX(i) = Rnd * _Width * .9 + .05 * _Width
  16.         pY(i) = Rnd * _Height * .9 + .05 * _Height
  17.     Next
  18.  
  19.     For level = 1 To 5
  20.         For i = 1 To nP
  21.             If Rnd < .5 Then dir = -1 Else dir = 1
  22.             x = pX(i) + dir * (Rnd * (6 - level) * 2)
  23.             If Rnd < .5 Then dir = -1 Else dir = 1
  24.             y = pY(i) + dir * (Rnd * (6 - level) * 2)
  25.             r = (Rnd * (6 - level) * 3) + 5 * (6 - level)
  26.             For row = y - r To y + r
  27.                 For col = x - r To x + r
  28.                     If row >= 1 And row <= _Height Then
  29.                         If col > 1 And col <= _Width Then
  30.                             If Sqr(((col - x) ^ 2) + (row - y) ^ 2) <= r Then
  31.                                 Locate row, col: Print tile(level);
  32.                             End If
  33.                         End If
  34.                     End If
  35.                 Next
  36.             Next
  37.  
  38.         Next
  39.     Next
  40.     Sleep
  41.  
  42.  
  43.  

  [ You are not allowed to view this attachment ]  

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #27 on: November 11, 2021, 01:31:53 am »
Nice job Steve! but where is the Ascii? ;-))

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: ISO simple ASCII procedural terrain
« Reply #28 on: November 11, 2021, 01:57:57 am »
@SMcNeill

Here's feedback on where your screen ended up in my screen, the left side under my taskbar and the right side showing what's underneath about the width of the taskbar, beautiful image, your farm?


Offline SMcNeill

  • QB64 Developer
  • Forum Resident
  • Posts: 3972
    • View Profile
    • Steve’s QB64 Archive Forum
Re: ISO simple ASCII procedural terrain
« Reply #29 on: November 11, 2021, 02:37:40 am »
Nice job Steve! but where is the Ascii? ;-))

It's just a grid of a few various heights.  Map it to whatever ASCII colors/characters you want.  I used graphics so I could display it all.  ;)
https://github.com/SteveMcNeill/Steve64 — A github collection of all things Steve!