Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Topics - bplus

Pages: 1 [2] 3 4 ... 21
16
QB64 Discussion / February Number Challenge
« on: February 11, 2022, 02:14:18 pm »
I found this at Liberty Basic Forum (Feb 8) and so far nobody there has figured it out.

I just did but let's see if someone else can here at this forum:

tsh73
Quote

It is high-school test problem my kid got yesterday
I jumped in - but after getting something working... I Googled and it happened that I solved quite anoter task (Doh).

So here is it (Google-translated text, original is in Russian)
Let's call a nontrivial divisor of a natural number its divisor, which is not equal to one and the number itself. For example, the number 6 has two nontrivial divisors: 2 and 3. Find all natural numbers belonging to the segment [123456789; 223456789] and having exactly three nontrivial divisors. For each found number, write down its largest nontrivial divisor in the answer. Arrange the answers in ascending order.


Could you solve it without Google?

I couldn't solve it with Google only learned that non trivial divisor is not the same as a proper divisor.

I tried brute force but that was going to take hours, no there is a little thing you have to discover then easy as pie.

It's fine if your list the three divisors and the number between 123456789 and 223456789 more than one but not many.

17
Programs / p5js
« on: February 02, 2022, 03:04:32 pm »
Here is really nice set of tools Ashish and Fellippe setup some time ago. p5js is referred to allot and so I thought it would be good to post an updated set that works for QB64 v2+

@Qwerkey I recommend this QB64 Classic for the library.


18
Programs / Split Versus Tokenize
« on: February 01, 2022, 11:33:24 am »
https://qb64forum.alephc.xyz/index.php?topic=4618.msg140260#msg140260
Quote
I think my way of splitting a string into an array is slightly better:

I say Split has at least two advantages!
1. Less LOC
2. Preserves blank lines from a .bas file.

And I am pretty sure for small files there is no significant time differences, not even sure if Tokenize is faster and how big a file you need to see it. I leave that to believers of Tokenize. ;-))
Code: QB64: [Select]
  1. _Title "Split versus Tokenize" ' b+ 2022-02-01
  2.  
  3. ' Is Tokenize really worth the extra LOC compared to Split?
  4. ' No! if you want to preserve blank lines.
  5.  
  6. '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  7.  
  8. '            save this file as "Split versus Tokenize.bas"
  9.  
  10. '!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  11.  
  12. Open "Split versus Tokenize.bas" For Binary As #1
  13. buf$ = Space$(LOF(1))
  14.  
  15. Get #1, , buf$
  16.  
  17.  
  18. deli$ = Chr$(13) + Chr$(10)
  19.  
  20. ReDim LoadMe$(1 To 1)
  21.  
  22. startSplit = Timer(.001)
  23. Split buf$, deli$, LoadMe$()
  24. splitTime = Timer(.001) - startSplit
  25.  
  26. For i = LBound(LoadMe$) To 10
  27.     Print i, LoadMe$(i)
  28. 'For i = UBound(LoadMe$) - 5 To UBound(LoadMe$)
  29. '    Print i, LoadMe$(i)
  30. 'Next
  31. Print "Time for Split was:"; splitTime
  32.  
  33. ' reset for tokenize
  34. ReDim LoadMe$(1 To 1)
  35. startTokenize = Timer(.001)
  36. tokenize buf$, deli$, LoadMe$()
  37. TokenizeTime = Timer(.001) - startTokenize
  38. For i = LBound(LoadMe$) To 10
  39.     Print i, LoadMe$(i)
  40. 'For i = UBound(LoadMe$) - 5 To UBound(LoadMe$)
  41. '    Print i, LoadMe$(i)
  42. 'Next
  43. Print "Time for Tokenize was:"; TokenizeTime  ' << edit: had wrong variable in here
  44.  
  45.  
  46.  
  47. ' note: I buggered this twice now, FOR base 1 array REDIM MyArray (1 to 1) AS ... the (1 to 1) is not same as (1) which was the Blunder!!!
  48. 'notes: REDIM the array(0) to be loaded before calling Split '<<<< IMPORTANT dynamic array and empty, can use any lbound though
  49. 'This SUB will take a given N delimited string, and delimiter$ and create an array of N+1 strings using the LBOUND of the given dynamic array to load.
  50. 'notes: the loadMeArray() needs to be dynamic string array and will not change the LBOUND of the array it is given.  rev 2019-08-27
  51. Sub Split (SplitMeString As String, delim As String, loadMeArray() As String)
  52.     Dim curpos As Long, arrpos As Long, LD As Long, dpos As Long 'fix use the Lbound the array already has
  53.     curpos = 1: arrpos = LBound(loadMeArray): LD = Len(delim)
  54.     dpos = InStr(curpos, SplitMeString, delim)
  55.     Do Until dpos = 0
  56.         loadMeArray(arrpos) = Mid$(SplitMeString, curpos, dpos - curpos)
  57.         arrpos = arrpos + 1
  58.         If arrpos > UBound(loadMeArray) Then ReDim _Preserve loadMeArray(LBound(loadMeArray) To UBound(loadMeArray) + 1000) As String
  59.         curpos = dpos + LD
  60.         dpos = InStr(curpos, SplitMeString, delim)
  61.     Loop
  62.     loadMeArray(arrpos) = Mid$(SplitMeString, curpos)
  63.     ReDim _Preserve loadMeArray(LBound(loadMeArray) To arrpos) As String 'get the ubound correct
  64.  
  65. Sub tokenize (toTokenize As String, delimiters As String, StorageArray() As String)
  66.         Function strtok%& (ByVal str As _Offset, delimiters As String)
  67.     End Declare
  68.     Dim As _Offset tokenized
  69.     Dim As String tokCopy: tokCopy = toTokenize + Chr$(0)
  70.     Dim As String delCopy: delCopy = delimiters + Chr$(0)
  71.     Dim As _Unsigned Long lowerbound: lowerbound = LBound(StorageArray)
  72.     Dim As _Unsigned Long i: i = lowerbound
  73.     tokenized = strtok(_Offset(tokCopy), delCopy)
  74.     While tokenized <> 0
  75.         ReDim _Preserve StorageArray(lowerbound To UBound(StorageArray) + 1)
  76.         StorageArray(i) = pointerToString(tokenized)
  77.         tokenized = strtok(0, delCopy)
  78.         i = i + 1
  79.     Wend
  80.     ReDim _Preserve StorageArray(UBound(StorageArray) - 1)
  81.  
  82. Function pointerToString$ (pointer As _Offset)
  83.         Function strlen%& (ByVal ptr As _Unsigned _Offset)
  84.     End Declare
  85.     Dim As _Offset length: length = strlen(pointer)
  86.     If length Then
  87.         Dim As _MEM pString: pString = _Mem(pointer, length)
  88.         Dim As String ret: ret = Space$(length)
  89.         _MemGet pString, pString.OFFSET, ret
  90.         _MemFree pString
  91.     End If
  92.     pointerToString = ret
  93.  
  94.  
  95.  

Edit: had wrong Time variable in showing Tokenize Time. Ha! I was wondering how they were coming exactly the same each time tested.

19
Programs / Quick Directory Files Listing for Windows Only
« on: January 31, 2022, 02:22:45 pm »
I thought I posted this already here at forum, maybe just Discord. I remember Spriggsy's help with Console use:
Code: QB64: [Select]
  1. _Title "Quick Dir Listing Windows only" ' b+ 2022-01-19
  2.  
  3. Dim Shared tmpDir As String '  establish a permanent spot for temp files
  4. If Environ$("TEMP") <> "" Then 'Thanks to Steve McNeill use user temp files directory
  5.     tmpDir = Environ$("TEMP")
  6. ElseIf Environ$("TMP") <> "" Then
  7.     tmpDir = Environ$("TMP")
  8. Else 'Thanks to Steve McNeill this should be very unlikely
  9.     If _DirExists("C:\temp") Then Else MkDir "C:\temp"
  10.     tmpDir = "C:\temp"
  11.  
  12. ' thanks Spriggsy  
  13. '$ScreenHide
  14. '_Console On
  15. '_Dest _Console
  16.  
  17.  
  18. ' assuming in th edirectory of interest otherwise chdir
  19. ChDir ".." ' the above directory
  20.  
  21. ReDim fileList$(0) ' setup Dynamic Array to load into
  22. loadFiles fileList$() ' get the files
  23.  
  24. ' see what we caught
  25. For i = 0 To UBound(fileList$) ' 0 item is always nothing so ubound of FileList$ = number of real files
  26.     Print i, fileList$(i)
  27.  
  28.     ' from here you can weed out the files you dont want
  29.  
  30.  
  31. ' nice simple little file catcher for Windows
  32. Sub loadFiles (fa() As String)
  33.     Dim tmpFile As String, Index%
  34.     tmpFile = tmpDir + "\FILE$INF0.INF" 'aha!, not a fully pathed file to user directory but here is good!
  35.  
  36.     ' this sorts first by file extention then by filename
  37.     Shell _Hide "DIR *.* /a:-d /b /o:-gen > " + tmpFile
  38.     '*.* any name and extension
  39.     '/b is bare list
  40.     '/a:-d nodirectories
  41.     '/o:-gen no directories, sort by extension then name
  42.  
  43.     Open tmpFile$ For Input As #1
  44.     Do While Not EOF(1)
  45.         Index% = Index% + 1
  46.         ReDim _Preserve fa(Index%) As String
  47.         Line Input #1, fa(Index%)
  48.     Loop
  49.     Close #1
  50.     Kill tmpFile$
  51.  
  52.  

No you don't have to use this code in Console, I just did because it scrolls back so you can read longer lists.
You just need the first block that sets up TempDir variable and the Sub LoadFiles. You can mod that for particular use, say just looking for .bas files change *.* to *.bas :)

EDIT: sorry I posted old copy before Spriggsy help

20
Programs / A Replacement Method for Data Statements
« on: January 31, 2022, 01:30:22 pm »
Welcome @MrGW454

I saw you difficulty on Discord, here is alternate to DATA statements

Code: QB64: [Select]
  1. _Title "Replacement Method for Data statements" 'b+ 2022-01-31
  2.  
  3. 'our Data as string(s)
  4. dat$ = "bplus,SMcNeill,FellippeHeitor,vince,"
  5. dat$ = dat$ + "Qwerkey,Ashish,Luke,RCcola87,MrGW454"
  6.  
  7. 'Load into this array
  8. ReDim members$(1 To 1) ' use REDIM for dynamic array that we can change size of
  9. Split dat$, ",", members$() ' Load data into members$()
  10.  
  11. 'Show it worked
  12. For i = 1 To UBound(members$)
  13.     Print members$(i)
  14.  
  15. ' note: I buggered this twice now, FOR base 1 array REDIM MyArray (1 to 1) AS ... the (1 to 1) is not same as (1) which was the Blunder!!!
  16. 'notes: REDIM the array(0) to be loaded before calling Split '<<<< IMPORTANT dynamic array and empty, can use any lbound though
  17. 'This SUB will take a given N delimited string, and delimiter$ and create an array of N+1 strings using the LBOUND of the given dynamic array to load.
  18. 'notes: the loadMeArray() needs to be dynamic string array and will not change the LBOUND of the array it is given.  rev 2019-08-27
  19. Sub Split (SplitMeString As String, delim As String, loadMeArray() As String)
  20.     Dim curpos As Long, arrpos As Long, LD As Long, dpos As Long 'fix use the Lbound the array already has
  21.     curpos = 1: arrpos = LBound(loadMeArray): LD = Len(delim)
  22.     dpos = InStr(curpos, SplitMeString, delim)
  23.     Do Until dpos = 0
  24.         loadMeArray(arrpos) = Mid$(SplitMeString, curpos, dpos - curpos)
  25.         arrpos = arrpos + 1
  26.         If arrpos > UBound(loadMeArray) Then ReDim _Preserve loadMeArray(LBound(loadMeArray) To UBound(loadMeArray) + 1000) As String
  27.         curpos = dpos + LD
  28.         dpos = InStr(curpos, SplitMeString, delim)
  29.     Loop
  30.     loadMeArray(arrpos) = Mid$(SplitMeString, curpos)
  31.     ReDim _Preserve loadMeArray(LBound(loadMeArray) To arrpos) As String 'get the ubound correct
  32.  
  33.  

21
QB64 Discussion / How about dictating your QB64 Program?
« on: January 26, 2022, 02:33:51 pm »
I ran into this while looking for a sample of Text to Speech Sounds for Johnno.
https://www.google.com/search?client=opera&q=speech+to+text+windows+10+youtube&sourceid=opera&ie=UTF-8&oe=UTF-8#kpvalbx=_e6DxYYGYAcLB0PEP18ab4A013

Be cool if we could do this for coding!  Then we might not need SpellChecker, but probably be likely we would be turning it off.

22
Programs / Passing Time
« on: January 23, 2022, 05:10:52 pm »
More fun with RotoZoom3
Code: QB64: [Select]
  1. _Title "Does anyone really know what time it is?" ' b+ 2022-01-23
  2. Type obj
  3.     As Single X, Y, ScaleX, ScaleY, RotXY, DScaleX, DScaleY, DRotXY, ScaleLimit
  4.  
  5. Const SW = 1025, SH = 721, NClocks = 40
  6. Screen _NewImage(SW, SH, 32)
  7. _ScreenMove 150, 10
  8. Dim midP, i
  9. c& = _NewImage(313, 313, 32)
  10. midP = Int((313 - 1) / 2)
  11. clock midP, midP, 149
  12. 'Line (0, 0)-(311, 311), , B ' check centering
  13. _ClearColor &HFF000000, c&
  14. Dim Shared Clocks(1 To NClocks) As obj
  15. For i = 1 To NClocks
  16.     newClock i, 1
  17.     Cls
  18.     _Title "Does anyone really know what time it is? Sure " + Time$
  19.     _Dest c&
  20.     Line (0, 0)-(311, 311), &HFF000000, BF ' blank out fro redraw
  21.     midP = Int((313 - 1) / 2)
  22.     clock midP, midP, 149
  23.     _Dest 0
  24.     _ClearColor &HFF000000, c&
  25.     For i = 1 To NClocks
  26.         RotoZoom3 Clocks(i).X, Clocks(i).Y, c&, Clocks(i).ScaleX, Clocks(i).ScaleY, Clocks(i).RotXY
  27.         Clocks(i).Y = Clocks(i).Y + 1
  28.         If Clocks(i).Y > _Height + 150 Then
  29.             newClock i, 0
  30.         Else
  31.             'updates
  32.             Clocks(i).ScaleX = Clocks(i).ScaleX + Clocks(i).DScaleX
  33.             If Clocks(i).ScaleX < -Clocks(i).ScaleLimit Then Clocks(i).DScaleX = -Clocks(i).DScaleX: Clocks(i).ScaleX = -Clocks(i).ScaleLimit
  34.             If Clocks(i).ScaleX > Clocks(i).ScaleLimit Then Clocks(i).DScaleX = -Clocks(i).DScaleX: Clocks(i).ScaleX = Clocks(i).ScaleLimit
  35.             Clocks(i).ScaleY = Clocks(i).ScaleY + Clocks(i).DScaleY
  36.             If Clocks(i).ScaleY < -Clocks(i).ScaleLimit Then Clocks(i).DScaleY = -Clocks(i).DScaleY: Clocks(i).ScaleY = -Clocks(i).ScaleLimit
  37.             If Clocks(i).ScaleY > Clocks(i).ScaleLimit Then Clocks(i).DScaleY = -Clocks(i).DScaleY: Clocks(i).ScaleY = Clocks(i).ScaleLimit
  38.             Clocks(i).RotXY = Clocks(i).RotXY + Clocks(i).DRotXY
  39.         End If
  40.     Next
  41.     _Display
  42.     _Limit 60
  43.  
  44. Sub newClock (i, initTF)
  45.     Clocks(i).X = Rnd * SW
  46.     If initTF Then Clocks(i).Y = rrnd(-150, SH) Else Clocks(i).Y = -150
  47.     Clocks(i).ScaleLimit = 1
  48.     Clocks(i).ScaleX = rrnd(-Clocks(i).ScaleLimit, Clocks(i).ScaleLimit)
  49.     Clocks(i).ScaleY = rrnd(-Clocks(i).ScaleLimit, Clocks(i).ScaleLimit)
  50.     Clocks(i).DScaleX = rrnd(-.005 * Clocks(i).ScaleLimit, .005 * Clocks(i).ScaleLimit)
  51.     Clocks(i).DScaleY = rrnd(-.005 * Clocks(i).ScaleLimit, .005 * Clocks(i).ScaleLimit)
  52.     Clocks(i).RotXY = _Pi(2) * Rnd
  53.     Clocks(i).DRotXY = rrnd(-.005 * _Pi, .005 * _Pi)
  54.  
  55. Sub clock (x, y, r)
  56.     Dim a, r1, hrs
  57.     For a = 0 To 359 Step 6
  58.         If a Mod 30 = 0 Then r1 = 1 / 30 * r Else r1 = 1 / 75 * r
  59.         Circle (x + r * Cos(_D2R(a)), y + r * Sin(_D2R(a))), r1
  60.         Paint (x + r * Cos(_D2R(a)), y + r * Sin(_D2R(a))), _RGB32(100, 100, 100), _RGB32(255, 255, 255)
  61.     Next
  62.     If Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60) >= 12 Then hrs = Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60) - 12 Else hrs = Val(Left$(Time$, 2)) + (Val(Mid$(Time$, 4, 2)) / 60)
  63.     ftri0 x + 1 / 15 * r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) + _Pi(1 / 2)), y + 1 / 15 * r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) + _Pi(1 / 2)), x + 1 / 15 * r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) - _Pi(1 / 2)), y + 1 / 15 * r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2) - _Pi(1 / 2)), x + r * Cos(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), y + r * Sin(Val(Mid$(Time$, 4, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), _RGB32(255, 0, 0)
  64.     ftri0 x + 1 / 10 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2) + _Pi(1 / 2)), y + 1 / 10 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2) + _Pi(1 / 2)), x + 1 / 10 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2) - _Pi(1 / 2)), y + 1 / 10 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2) - _Pi(1 / 2)), x + 2 / 3 * r * Cos(hrs * _Pi(1 / 6) - _Pi(1 / 2)), y + 2 / 3 * r * Sin(hrs * _Pi(1 / 6) - _Pi(1 / 2)), _RGB32(0, 0, 255)
  65.     Line (x, y)-(x + r * Cos(Val(Right$(Time$, 2)) * _Pi(1 / 30) - _Pi(1 / 2)), y + r * Sin(Val(Right$(Time$, 2)) * _Pi(1 / 30) - _Pi(1 / 2))), _RGB32(255, 255, 0)
  66.     Circle (x, y), 1 / 10 * r, _RGB32(255, 255, 255)
  67.     Paint (x + 1 / 75 * r, y + 1 / 75 * r), _RGB32(100, 100, 100), _RGB32(255, 255, 255)
  68.     Circle (x, y), 1 / 30 * r, _RGB32(0, 0, 0)
  69.  
  70. Sub ftri0 (x1, y1, x2, y2, x3, y3, K As _Unsigned Long)
  71.     Dim D As Long, a&
  72.     D = _Dest
  73.     a& = _NewImage(1, 1, 32)
  74.     _Dest a&
  75.     PSet (0, 0), K
  76.     _Dest D
  77.     _MapTriangle _Seamless(0, 0)-(0, 0)-(0, 0), a& To(x1, y1)-(x2, y2)-(x3, y3)
  78.     _FreeImage a& '<<< this is important!
  79.  
  80. Sub RotoZoom3 (X As Long, Y As Long, Image As Long, xScale As Single, yScale As Single, radianRotation As Single) ' 0 at end means no scaling of x or y
  81.     Dim px(3) As Single: Dim py(3) As Single
  82.     Dim W&, H&, sinr!, cosr!, i&, x2&, y2&
  83.     W& = _Width(Image&): H& = _Height(Image&)
  84.     px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
  85.     px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
  86.     sinr! = Sin(-radianRotation): cosr! = Cos(-radianRotation)
  87.     For i& = 0 To 3
  88.         x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
  89.         px(i&) = x2&: py(i&) = y2&
  90.     Next
  91.     _MapTriangle _Seamless(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  92.     _MapTriangle _Seamless(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  93.  
  94. Function rrnd (n1, n2) 'return real number (_single, double, _float depending on default / define setup)
  95.     rrnd = (n2 - n1) * Rnd + n1
  96.  
  97.  

23
Programs / Playing with fire (again)
« on: January 17, 2022, 10:31:44 pm »
Quote
bplus is into letters now instead of graphics, sad times

OK @_vince maybe this will cheer your up. ;-))
Code: QB64: [Select]
  1. _Title "Jolly Roger on Fire" 'b+ 2022-01-17
  2.  
  3. Const xmax = 500, ymax = 400
  4. Screen _NewImage(xmax, ymax, 32)
  5. _ScreenMove 360, 160
  6.  
  7. Dim p&(300) 'pallette
  8. For i = 1 To 100
  9.     fr = 240 * i / 100 + 15
  10.     p&(i) = _RGB(fr, 0, 0)
  11.     p&(i + 100) = _RGB(255, fr, 0)
  12.     p&(i + 200) = _RGB(255, 255, fr)
  13. w~& = _RGB32(255)
  14. jr& = _LoadImage("Jolly Roger.png") '
  15. _PutImage , jr&, 0
  16. xxmax = 500: yymax = 200 'pixels too slow
  17. xstep = xmax / xxmax: ystep = ymax / yymax
  18. Dim f(xxmax, yymax), ff(xxmax, yymax) 'fire array and seed
  19. For y = 0 To yymax - 1
  20.     For x = 0 To xxmax - 1
  21.         If Point(x * xstep, y * ystep) = w~& Then f(x, y) = 300: ff(x, y) = 300
  22.     Next
  23.  
  24. While 1 'main fire
  25.     Cls
  26.     For y = 1 To yymax - 1
  27.         For x = 1 To xxmax - 1 'shift fire seed a bit
  28.             r = Rnd
  29.             If r > .9 Then f(x, y) = ff(x, y)
  30.         Next
  31.     Next
  32.     For y = 0 To yymax - 2 'fire based literally on 4 pixels below it like cellular automata
  33.         For x = 1 To xxmax - 1
  34.             f(x, y) = max((f(x - 1, y + 1) + f(x, y + 1) + f(x + 1, y + 1) + f(x - 1, y + 2)) / 4 - 5, 0)
  35.             Line (x * xstep, y * ystep)-Step(xstep, ystep), p&(f(x, y)), BF
  36.         Next
  37.     Next
  38.     _Display
  39.     _Limit 30
  40.  
  41. Function max (a, b)
  42.     If a > b Then max = a Else max = b
  43.  
  44.  
JR on Fire.PNG


And this might look familiar:
Code: QB64: [Select]
  1. _Title "Jolly Roger on Fire: try spacebar" 'b+ 2022-01-17
  2. DefLng A-Z
  3. Const sw = 700, sh = 500, fw = 600, fh = 400
  4. Screen _NewImage(sw, sh, 32)
  5. _ScreenMove 230, 60
  6. Dim i, fr, w~&, jr, img, xxmax, yymax, xstep, ystep, x, y, a, x0, y0, r!
  7. Dim p(300) 'pallette
  8. For i = 1 To 100
  9.     fr = 240 * i / 100 + 15
  10.     p(i) = _RGB(fr, 0, 0)
  11.     p(i + 100) = _RGB(255, fr, 0)
  12.     p(i + 200) = _RGB(255, 255, fr)
  13. w~& = _RGB32(255)
  14. jr = _LoadImage("Jolly Roger.png")
  15.  
  16. img = _NewImage(fw, fh, 32)
  17. _PutImage , jr&, img
  18. xxmax = fh: yymax = 200
  19. xstep = fw / xxmax: ystep = fh / yymax
  20. Dim f(xxmax, yymax), ff(xxmax, yymax) 'fire array and seed
  21. For y = 0 To yymax - 1
  22.     For x = 0 To xxmax - 1
  23.         If Point(x * xstep, y * ystep) = w~& Then f(x, y) = 300: ff(x, y) = 300
  24.     Next
  25.  
  26. ' from _vince flag wave
  27. a = fh / 20
  28. x0 = (sw - fw) / 2 'center flag on screen top left corner
  29. y0 = (sh - fh) / 2
  30.  
  31. Dim r, g, b, toggle
  32. Dim As Double t, z, xx, yy, dx, dy, dz
  33. Dim As _Unsigned Long tl, tr, bl, br
  34. Color , &HFF9999BB
  35.     If InKey$ = " " Then toggle = 1 - toggle
  36.     ' update the img
  37.     _Dest img
  38.     If toggle Then Line (0, 0)-(fw, fh), &HFF000000, BF Else _PutImage , jr&, img ' blank out image or not either way is interesting
  39.     For y = 1 To yymax - 1
  40.         For x = 1 To xxmax - 1 'refuel fire seed
  41.             r! = Rnd
  42.             If r! > .7 Then f(x, y) = ff(x, y)
  43.         Next
  44.     Next
  45.     For y = 0 To yymax - 2 'fire based literally on 4 pixels below it like cellular automata
  46.         For x = 1 To xxmax - 1
  47.             f(x, y) = max((f(x - 1, y + 1) + f(x, y + 1) + f(x + 1, y + 1) + f(x - 1, y + 2)) / 4 - 5, 0)
  48.             Line (x * xstep, y * ystep)-Step(xstep, ystep), p&(f(x, y)), BF
  49.         Next
  50.     Next
  51.     _Dest 0
  52.     'source is still img
  53.     t = t + 0.2
  54.     Cls
  55.     For y = 0 To fh + a * 0.707 Step 1
  56.         For x = 0 To fw + a * 0.707 Step 1
  57.             z = (0.1 + 0.4 * (x / fw)) * a * Sin(x / 35 - y / 70 - t) + 0.5 * a
  58.             dz = 50 * a * Cos(x / 35 - y / 70 - t) / 35
  59.  
  60.             xx = x + z * 0.707 - a * 0.707
  61.             yy = y - z * 0.707
  62.  
  63.             If (Int(xx) >= 0 And Int(xx) < fw - 1 And Int(yy) >= 0 And Int(yy) < fh - 1) Then
  64.                 tl = Point(Int(xx), Int(yy))
  65.                 tr = Point(Int(xx) + 1, Int(yy))
  66.                 bl = Point(Int(xx), Int(yy) + 1)
  67.                 br = Point(Int(xx) + 1, Int(yy) + 1)
  68.  
  69.                 dx = xx - Int(xx)
  70.                 dy = yy - Int(yy)
  71.  
  72.                 r = _Round((1 - dy) * ((1 - dx) * _Red(tl) + dx * _Red(tr)) + dy * ((1 - dx) * _Red(bl) + dx * _Red(br)))
  73.                 g = _Round((1 - dy) * ((1 - dx) * _Green(tl) + dx * _Green(tr)) + dy * ((1 - dx) * _Green(bl) + dx * _Green(br)))
  74.                 b = _Round((1 - dy) * ((1 - dx) * _Blue(tl) + dx * _Blue(tr)) + dy * ((1 - dx) * _Blue(bl) + dx * _Blue(br)))
  75.  
  76.                 r = r + dz
  77.                 g = g + dz
  78.                 b = b + dz
  79.  
  80.                 If r < 0 Then r = 0
  81.                 If r > 255 Then r = 255
  82.                 If g < 0 Then g = 0
  83.                 If g > 255 Then g = 255
  84.                 If b < 0 Then b = 0
  85.                 If b > 255 Then b = 255
  86.                 PSet (x0 + x, y0 - a * 0.707 + y), _RGB(r, g, b)
  87.             End If
  88.         Next
  89.     Next
  90.     Line (0, 0)-(x0 + 15, y0 - 4), &HFF000000
  91.     Line (0, 1)-(x0 + 15, y0 - 3), &HFF000000
  92.     Line (20, sh)-(x0 + 10, y0 - 9 + fh), &HFF000000
  93.     Line (20, sh + 1)-(x0 + 10, y0 - 9 + fh + 1), &HFF000000
  94.     _Display
  95.     _Limit 50
  96.  
  97. Function max (a, b)
  98.     If a > b Then max = a Else max = b
  99.  
  100.  
JR on Fire 2.PNG


Zip with bas sources and image


24
Programs / Boggle play against AI - WIP
« on: January 13, 2022, 11:46:33 am »
https://en.wikipedia.org/wiki/Boggle

The AI is going to be handicapped starting with only 1 point words (3 or 4 letters words from Scrabble Dictionary that don't use Q (that is 2 points)) and maybe a shorter time limit too.

Just got started last night from trying to figure out Dimster's "Babble" Game, I thought he might mean Boggle?

Any way got a board working:
Code: QB64: [Select]
  1. _Title "Boggle 1" ' b+ start 2022-01-12
  2. ' Scabble Word List and Dictionary
  3. ' ref dictionary: https://boardgames.stackexchange.com/questions/38366/latest-collins-scrabble-words-list-in-text-file
  4. ' Die configurations
  5. ' https://boardgames.stackexchange.com/questions/29264/boggle-what-is-the-dice-configuration-for-boggle-in-various-languages
  6. ' Thank you!
  7.  
  8. Dim Shared Board$(3, 3)
  9. Dim Shared As Long f48, f30, dx(7), dy(7)
  10. Screen _NewImage(800, 600, 32)
  11. _ScreenMove 200, 100
  12.     Cls
  13.     NewBoard
  14.     ' display timer and allow input of words from user for 3 minutes
  15.     ' meanwhile AI will calc all the 1 point words it can from board
  16.  
  17.     Sleep
  18.  
  19. Sub NewBoard
  20.     Static BeenHere, Di$(), Numbers()
  21.     Dim As Long i, r, c, row, col
  22.     If BeenHere = 0 Then 'load and initialize
  23.         f48 = _LoadFont("Arial.ttf", 48, "MONOSPACE")
  24.         f30 = _LoadFont("Arial.ttf", 30, "MONOSPACE")
  25.         If f48 <= 0 Then Print "Sub NewBoard: Font did not load, goodbye.": End
  26.         dx(0) = -1: dy(0) = -1 ' this is for AI to find words
  27.         dx(1) = 0: dy(1) = -1
  28.         dx(2) = 1: dy(2) = -1
  29.         dx(3) = -1: dy(3) = 0
  30.         dx(4) = 1: dy(4) = 0
  31.         dx(5) = -1: dy(5) = 1
  32.         dx(6) = 0: dy(6) = 1
  33.         dx(7) = 1: dy(7) = 1
  34.         Dim Di$(0 To 15) ' this for 16 di, 6 letters per
  35.         Di$(1) = "RIFOBX"
  36.         Di$(2) = "IFEHEY"
  37.         Di$(3) = "DENOWS"
  38.         Di$(4) = "UTOKND"
  39.         Di$(5) = "HMSRAO"
  40.         Di$(6) = "LUPETS"
  41.         Di$(7) = "ACITOA"
  42.         Di$(8) = "YLGKUE"
  43.         Di$(9) = "QBMJOA"
  44.         Di$(10) = "EHISPN"
  45.         Di$(11) = "VETIGN"
  46.         Di$(12) = "BALIYT"
  47.         Di$(13) = "EZAVND"
  48.         Di$(14) = "RALESC"
  49.         Di$(15) = "UWILRG"
  50.         Di$(0) = "PACEMD"
  51.         Dim Numbers(0 To 15) ' for shuffling die order
  52.         For i = 0 To 15
  53.             Numbers(i) = i
  54.         Next
  55.         BeenHere = -1
  56.     End If
  57.     For i = 15 To 1 Step -1 'shuffle die
  58.         Swap Numbers(i), Numbers(Int(Rnd * (i + 1)))
  59.     Next
  60.     'For i = 1 To 16: Print Numbers(i);: Next: Print   ' check the shuffle
  61.     For i = 0 To 15 'choosing random face of die = 1 Letter
  62.         Index2ColRow i, c, r
  63.         Board$(c, r) = Mid$(Di$(Numbers(i)), Int(Rnd * 6) + 1, 1)
  64.     Next
  65.     _Font f48
  66.     For row = 0 To 3 '  display the board
  67.         For col = 0 To 3
  68.             Line ((col + 1) * 60 - 5, (row + 1) * 60 - 5)-Step(54, 54), &HFF2020FF, BF 'face color or die
  69.             If Board$(col, row) = "Q" Then 'If face has a Q it is supposed to be "Qu"
  70.                 _Font f30
  71.                 Color &HFF661111 'shade
  72.                 _PrintString ((col + 1) * 60 - 4, (row + 1) * 60 + 11), "Q"
  73.                 _PrintString ((col + 1) * 60 + 24, (row + 1) * 60 + 11), "U"
  74.                 Color &HFFBBBBBB 'letter
  75.                 _PrintString ((col + 1) * 60 - 7, (row + 1) * 60 + 9), "Q"
  76.                 _PrintString ((col + 1) * 60 + 22, (row + 1) * 60 + 9), "U"
  77.                 _Font f48
  78.             Else
  79.                 Color &HFF661111 'shade
  80.                 _PrintString ((col + 1) * 60 + 2, (row + 1) * 60 + 2), Board$(col, row)
  81.                 Color &HFFBBBBBB 'letter
  82.                 _PrintString ((col + 1) * 60, (row + 1) * 60), Board$(col, row)
  83.             End If
  84.         Next
  85.     Next
  86.     _Font 16
  87.  
  88. Function ColRow2Index& (row As Long, col As Long) ' convert a board letter to index (not needed yet?)
  89.     ColRow2Index& = row * 4 + col
  90. Sub Index2ColRow (indexIn As Long, rowOut As Long, colOut As Long) 'convert die index to board col, row
  91.     colOut = indexIn Mod 4: rowOut = indexIn \ 4
  92.  

25
Programs / Read & Print the Type from your bas source
« on: January 09, 2022, 04:45:11 pm »
Proof of concept, proved!
Code: QB64: [Select]
  1. _Title "Read Type test" 'b+ 2022-01-09
  2.  
  3. Type ButtonData
  4.     Caption As String
  5.     Department As String
  6.     Group As String
  7.     Price As Integer
  8.     TaxRate As Integer
  9.     Printer As Integer
  10.     Colour_Red As Integer
  11.     Colour_Green As Integer
  12.     Colour_Blue As Integer
  13.  
  14. Print myType$("Read Type test.bas")
  15.  
  16.  
  17. Function myType$ (file$) ' for proof of concept assuming one type to get
  18.     If _FileExists(file$) Then
  19.         Open file$ For Input As #1
  20.         While Not EOF(1)
  21.             Line Input #1, fl$
  22.             If Left$(fl$, 4) = "Type" Then
  23.                 While Left$(fl$, 8) <> "End Type"
  24.                     Line Input #1, fl$
  25.                     If b$ = "" Then
  26.                         b$ = _Trim$(Mid$(fl$, 1, InStr(fl$, " A"))) ' hmmm does trim$ do tabs?
  27.                     Else
  28.                         b$ = b$ + Chr$(10) + _Trim$(Mid$(fl$, 1, InStr(fl$, " A")))
  29.                     End If
  30.                 Wend
  31.                 myType$ = b$
  32.                 Close #1
  33.                 Exit Function
  34.             End If
  35.         Wend
  36.     End If
  37.  

Remember to save this to disk before trying.

edit: add close #1
edit: exit function when you got what you came for

26
Programs / TriQuad Puzzle inspired by Rick3137
« on: January 09, 2022, 04:14:29 pm »
Welcome @Rick3137

Remember this (over 4 years ago)?
Code: QB64: [Select]
  1. _Title "TriQuad Puzzle" 'B+ start 2019-07-17 trans to QB64 from:
  2. ' TriQuad.bas  SmallBASIC 0.12.8 [B+=MGA] 2017-03-26
  3. ' inspired by rick3137's recent post at Naalaa of cute puzzle
  4. ' 2019-07 Complete remake for N X N puzzles, not just 3 X 3's.
  5. ' post at QB64 forum 2019-10-14
  6.  
  7.  
  8. Const xmax = 1000, margin = 50 'screen size, margin that should allow a line above and below the puzzle display
  9. Const topLeftB1X = margin, topLeftB2X = xmax / 2 + .5 * margin, topY = margin
  10.  
  11. 'these have to be decided from user input from Intro screen
  12. Dim Shared ymax, N, Nm1, NxNm1, sq, sq2, sq4
  13. ymax = 500 'for starters in intro screen have resizing in pixels including ymax
  14.  
  15. ReDim Shared B1(2, 2), B2(2, 2) ' B1() box container for scrambled pieces of C(), B2 box container to build solution
  16. ReDim Shared C(8, 3) '9 squares 4 colored triangles, C() contains the solution as created by code, may not be the only one!
  17.  
  18. Dim mx, my, mb, bx, by, holdF, ky As String, again As String
  19.  
  20. Screen _NewImage(xmax, ymax, 32)
  21. _ScreenMove 300, 40
  22. intro
  23. restart:
  24. assignColors
  25. holdF = N * N
  26.     Cls
  27.     showB (1)
  28.     showB (2)
  29.     mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
  30.     If mb Then
  31.         Do While mb
  32.             While _MouseInput: Wend
  33.             mx = _MouseX: my = _MouseY: mb = _MouseButton(1)
  34.         Loop
  35.         If topY <= my And my <= topY + N * sq Then
  36.             by = Int((my - topY) / sq)
  37.             If topLeftB1X <= mx And mx <= topLeftB1X + N * sq Then 'mx in b1
  38.                 bx = Int((mx - topLeftB1X) / sq)
  39.                 If holdF < N * N Then 'trying to put the piece on hold here?
  40.                     If B1(bx, by) = N * N Then
  41.                         B1(bx, by) = holdF: holdF = N * N
  42.                     End If
  43.                 ElseIf holdF = N * N Then
  44.                     If B1(bx, by) < N * N Then
  45.                         holdF = B1(bx, by): B1(bx, by) = N * N
  46.                     End If
  47.                 End If
  48.             ElseIf topLeftB2X <= mx And mx <= topLeftB2X + N * sq Then 'mx in b2
  49.                 bx = Int((mx - topLeftB2X) / sq)
  50.                 If holdF < N * N Then
  51.                     If B2(bx, by) = N * N Then
  52.                         B2(bx, by) = holdF: holdF = N * N
  53.                     End If
  54.                 ElseIf holdF = N * N Then
  55.                     If B2(bx, by) < N * N Then
  56.                         holdF = B2(bx, by): B2(bx, by) = N * N
  57.                     End If
  58.                 End If 'my out of range
  59.             End If
  60.         End If
  61.     End If
  62.     If solved Then
  63.         Color hue(9)
  64.         Locate 2, 1: centerPrint "Congratulations puzzle solved!"
  65.         _Display
  66.         _Delay 3
  67.         Exit While
  68.     End If
  69.     ky = InKey$
  70.     If Len(ky) Then
  71.         If ky = "q" Then
  72.             showSolution
  73.             Color hue(9)
  74.             Locate 2, 1: centerPrint "Here is solution (for 10 secs), Goodbye!"
  75.             _Display
  76.             _Delay 10
  77.             System
  78.         End If
  79.     End If
  80.     _Display
  81.     _Limit 100
  82. Color hue(9): Locate 2, 1: centerPrint Space$(50): Locate 2, 1
  83. centerPrint "Press enter to play again, any + enter ends... "
  84. again = InKey$
  85. While Len(again) = 0: again = InKey$: _Limit 200: Wend
  86. If Asc(again) = 13 Then GoTo restart Else System
  87.  
  88. Function solved
  89.     'since it is possible that a different tile combination could be a valid solution we have to check points
  90.     Dim x, y
  91.     'first check that there is a puzzle piece in every slot of b2
  92.     For y = 0 To Nm1
  93.         For x = 0 To Nm1
  94.             If B2(x, y) = N * N Then Exit Function
  95.         Next
  96.     Next
  97.     'check left and right triangle matches in b2
  98.     For y = 0 To Nm1
  99.         For x = 0 To Nm1 - 1
  100.             If Point(topLeftB2X + x * sq + sq2 + sq4, topY + y * sq + sq2) <> Point(topLeftB2X + (x + 1) * sq + sq4, topY + y * sq + sq2) Then Exit Function
  101.         Next
  102.     Next
  103.     'check to and bottom triangle matches in b2
  104.     For y = 0 To Nm1 - 1
  105.         For x = 0 To Nm1
  106.             'the color of tri4 in piece below = color tri1 of piece above
  107.             If Point(topLeftB2X + x * sq + sq2, topY + y * sq + sq2 + sq4) <> Point(topLeftB2X + x * sq + sq2, topY + (y + 1) * sq + sq4) Then Exit Function
  108.         Next
  109.     Next
  110.     'if made it this far then solved
  111.     solved = -1
  112.  
  113. Sub showSolution
  114.     Dim x, y, index
  115.     For y = 0 To Nm1
  116.         For x = 0 To Nm1
  117.             drawSquare index, x * sq + topLeftB2X, y * sq + topY
  118.             index = index + 1
  119.         Next
  120.     Next
  121.  
  122. Sub showB (board)
  123.     Dim x, y, index
  124.     For y = 0 To Nm1
  125.         For x = 0 To Nm1
  126.             If board = 1 Then
  127.                 index = B1(x, y)
  128.                 drawSquare index, x * sq + topLeftB1X, y * sq + topY
  129.             Else
  130.                 index = B2(x, y)
  131.                 drawSquare index, x * sq + topLeftB2X, y * sq + topY
  132.             End If
  133.         Next
  134.     Next
  135.  
  136. Sub drawSquare (index, x, y)
  137.     Line (x, y)-Step(sq, sq), &HFF000000, BF
  138.     Line (x, y)-Step(sq, sq), &HFFFFFFFF, B
  139.     If index < N * N Then
  140.         Line (x, y)-Step(sq, sq), &HFFFFFFFF
  141.         Line (x + sq, y)-Step(-sq, sq), &HFFFFFFFF
  142.         Paint (x + sq2 + sq4, y + sq2), hue(C(index, 0)), &HFFFFFFFF
  143.         Paint (x + sq2, y + sq2 + sq4), hue(C(index, 1)), &HFFFFFFFF
  144.         Paint (x + sq4, y + sq2), hue(C(index, 2)), &HFFFFFFFF
  145.         Paint (x + sq2, y + sq4), hue(C(index, 3)), &HFFFFFFFF
  146.     End If
  147.  
  148. Sub assignColors ()
  149.     'the pieces are indexed 0 to N X N -1  (NxNm1)
  150.     ' y(index) = int(index/N) : x(index) = index mod N
  151.     ' index(x, y) = (y - 1) * N + x
  152.  
  153.     Dim i, j, x, y
  154.     'first assign a random color rc to every triangle
  155.     For i = 0 To NxNm1 'piece index
  156.         For j = 0 To 3 'tri color index for piece
  157.             C(i, j) = rand(1, 9)
  158.         Next
  159.     Next
  160.     'next match c0 to c3 of square to right
  161.     For y = 0 To Nm1
  162.         For x = 0 To Nm1 - 1
  163.             'the color of tri3 of next square piece to right = color of tri0 to left of it
  164.             C(y * N + x + 1, 2) = C(y * N + x, 0)
  165.         Next
  166.     Next
  167.     For y = 0 To Nm1 - 1
  168.         For x = 0 To Nm1
  169.             'the color of tri4 in piece below = color tri1 of piece above
  170.             C((y + 1) * N + x, 3) = C(y * N + x, 1)
  171.         Next
  172.     Next
  173.  
  174.     ' C() now contains one solution for puzzle, may not be the only one
  175.  
  176.     ' scramble pieces to box1
  177.     Dim t(0 To NxNm1), index 'temp array
  178.     For i = 0 To NxNm1: t(i) = i: Next
  179.     For i = NxNm1 To 1 Step -1: Swap t(i), t(rand(0, i)): Next
  180.     For y = 0 To Nm1
  181.         For x = 0 To Nm1
  182.             B1(x, y) = t(index)
  183.             index = index + 1
  184.             B2(x, y) = N * N
  185.             'PRINT B1(x, y), B2(x, y)
  186.         Next
  187.     Next
  188.  
  189. Function hue~& (n)
  190.     Select Case n
  191.         Case 0: hue~& = &HFF000000
  192.         Case 1: hue~& = &HFFA80062
  193.         Case 2: hue~& = &HFF000050
  194.         Case 3: hue~& = &HFFE3333C
  195.         Case 4: hue~& = &HFFFF0000
  196.         Case 5: hue~& = &HFF008000
  197.         Case 6: hue~& = &HFF0000FF
  198.         Case 7: hue~& = &HFFFF64FF
  199.         Case 8: hue~& = &HFFFFFF00
  200.         Case 9: hue~& = &HFF00EEEE
  201.         Case 10: hue~& = &HFF663311
  202.     End Select
  203.  
  204. Function rand% (n1, n2)
  205.     Dim hi, lo
  206.     If n1 > n2 Then hi = n1: lo = n2 Else hi = n2: lo = n1
  207.     rand% = (Rnd * (hi - lo + 1)) \ 1 + lo
  208.  
  209. Sub intro 'use intro to select number of pieces
  210.     Dim test As Integer
  211.     Cls: Color hue(8): Locate 3, 1
  212.     centerPrint "TriQuad Instructions:": Print: Color hue(9)
  213.     centerPrint "This puzzle has two boxes that contain up to N x N square pieces of 4 colored triangles."
  214.     centerPrint "The object is to match up the triangle edges from left Box to fill the Box on the right.": Print
  215.     centerPrint "You may move any square piece to an empty space on either board by:"
  216.     centerPrint "1st clicking the piece to disappear it,"
  217.     centerPrint "then clicking any empty space for it to reappear.": Print
  218.     centerPrint "You may press q to quit and see the solution displayed.": Print
  219.     centerPrint "Hint: the colors without matching"
  220.     centerPrint "complement, are edge pieces.": Print
  221.     centerPrint "Good luck!": Color hue(5)
  222.     Locate CsrLin + 2, 1: centerPrint "Press number key for square pieces per side (3 to 9, 1 to quit)..."
  223.     While test < 3 Or test > 9
  224.         test = Val(InKey$)
  225.         If test = 1 Then System
  226.     Wend
  227.     N = test ' pieces per side of 2 boards
  228.     Nm1 = N - 1 ' FOR loops
  229.     NxNm1 = N * N - 1 ' FOR loop of piece index
  230.     'sizing
  231.     sq = (xmax / 2 - 1.5 * margin) / N 'square piece side size
  232.     sq2 = sq / 2: sq4 = sq / 4
  233.     ymax = sq * N + 2 * margin
  234.     ReDim B1(Nm1, Nm1), B2(Nm1, Nm1), C(NxNm1, 3)
  235.     Screen _NewImage(xmax, ymax, 32)
  236.     '_SCREENMOVE 300, 40    'need again?
  237.     'PRINT ymax
  238.  
  239. Sub centerPrint (s$)
  240.     Locate CsrLin, (xmax / 8 - Len(s$)) / 2: Print s$
  241.  

Quote
Sub intro 'use intro to select number of pieces
    Dim test As Integer
    Cls: Color hue(8): Locate 3, 1
    centerPrint "TriQuad Instructions:": Print: Color hue(9)
    centerPrint "This puzzle has two boxes that contain up to N x N square pieces of 4 colored triangles."
    centerPrint "The object is to match up the triangle edges from left Box to fill the Box on the right.": Print
    centerPrint "You may move any square piece to an empty space on either board by:"
    centerPrint "1st clicking the piece to disappear it,"
    centerPrint "then clicking any empty space for it to reappear.": Print
    centerPrint "You may press q to quit and see the solution displayed.": Print
    centerPrint "Hint: the colors without matching"
    centerPrint "complement, are edge pieces.": Print
    centerPrint "Good luck!": Color hue(5)
TriQuad move 1 more piece.PNG



27
Programs / Wordle - a new word game
« on: January 07, 2022, 11:48:47 pm »
Pretty easy to figure out, read title bar for instructions:
Code: QB64: [Select]
  1. _Title "Wordle: 6 guesses to get 5 letter word, enter guess or nothing to quit, yellow is right letter wrong place, green is right letter right place."
  2. Randomize Timer ' b+ 20220107
  3. f& = _LoadFont("arial.ttf", 24, "MONOSPACE")
  4. Screen _NewImage(1024, 600, 32)
  5. _ScreenMove 100, 100
  6. Color _RGB32(200, 200, 200), _RGB32(0, 0, 0)
  7. Do ' again new round
  8.     Cls
  9.     Open "5 Letter Words.txt" For Input As #1 'grab a word, this is fast enough
  10.     nWord = Int(Rnd * 2104) + 1
  11.     For i = 1 To nWord
  12.         Input #1, w$
  13.     Next
  14.     Close #1
  15.     'Locate 20, 60: Print w$ ' for debug or cheat
  16.     printRow = 0
  17.     For i = 1 To 6 ' allowed 6 guesses
  18.         hits = 0 ' how many letters are dead right?
  19.         tryAgain: ' opps too many or few letters in guess
  20.         printRow = printRow + 1 ' track left print line for inputs mostly
  21.         Locate printRow, 1: Print " "; _Trim$(Str$(i)); "# ";
  22.         Input "Enter a 5 letter word for your guess "; guess$
  23.         If guess$ = "" Then System
  24.         If Len(guess$) <> 5 Then Sound 50, 4: printRow = printRow + 1: Print "Try again": GoTo tryAgain
  25.         _Font f&
  26.         For letter = 1 To 5
  27.             Locate i, letter + 30
  28.             If Mid$(w$, letter, 1) = Mid$(guess$, letter, 1) Then
  29.                 hits = hits + 1
  30.                 Color _RGB32(0, 0, 0), _RGB32(0, 128, 0)
  31.             ElseIf InStr(w$, Mid$(guess$, letter, 1)) Then
  32.                 Color _RGB32(0, 0, 0), _RGB32(255, 255, 0)
  33.             Else
  34.                 Color _RGB32(200, 200, 200), _RGB32(0, 0, 0)
  35.             End If
  36.             Print Mid$(guess$, letter, 1)
  37.         Next
  38.         _Font 16
  39.         Color _RGB32(200, 200, 200), _RGB32(0, 0, 0)
  40.         If hits = 5 Then Locate printRow + 1: Print "You got it!": _Delay 3: GoTo skip
  41.     Next
  42.     Sound 50, 4
  43.     printRow = printRow + 2
  44.     Locate printRow, 1: Print "The word was "; w$
  45.     _Delay 3
  46.     skip:
  47.  

The zip contains source, exe for Windows, 2 word files and the code to convert one to "5 Letter Words.txt" file.
 
wordle.PNG

28
Programs / Custom Edit Image, Save and Load with Turkey Hunt WIP Game
« on: December 30, 2021, 02:45:44 pm »
OK here's the story I started translating this guys tutorial for beginner Blitzmax here:
https://www.syntaxbomb.com/tutorials/learning-basic-for-total-beginners-blitzmax-ng/msg347053898/#msg347053898

Blitzmax code:
Code: [Select]
SuperStrict
Graphics 800,600
Global Land:TImage    = LoadImage("land.png")
Global Chicken:TImage = LoadImage("chicken.png")
Global Shot:TSound=LoadSound("fire.ogg")
Global cX:Int, cY:Int=300
Global mX:Int, mY:Int
Global Points:Int
Repeat
        Cls
        DrawImage Land    , 0 , 0
        'DrawImage Chicken , cX , cY
        '   comment out the original command, and use DrawRect instead:
        SetColor 111,0,0
        DrawRect cX, cY, 60,40
        cX = cX +2
        If GunFire() =True Then
                cX=-100
                Points=Points+1
        EndIf
        SetColor 255,255,255
        DrawRect mX-25, mY-1,50,3
        DrawRect mX-1, mY-25,3,50
        'HideMouse
        DrawText "Points: " + points, 700,550
        Flip
Until AppTerminate()
ShowMouse
 
 
Function GunFire:Int()
        mX=MouseX()
        mY=MouseY()   
        If MouseHit(1)
                PlaySound Shot
                If (mX>cX) And (mx<cX+60)
                        If (mY>cY) And (mY<cY+40)
                                ' collision
                                Return True
                        EndIf
                EndIf
        EndIf
        Return False
End Function

But the code didn't come with a chicken image so I thought I'd reuse the Turkey Cartoon from Turkey Run from Thanksgiving ie Turkey Day

OK but now the Turkey's background isn't working with the background for the Hunt. (I just used white to hide the turkey background mostly white in image in Turkey Day.)

So like Colonel Panic here: https://qb64forum.alephc.xyz/index.php?topic=4539.0
I got interested in custom editing and saving and loading a modified image.

So I reworked SMcNeill's quick demo for any image not just the screen got it working without _defalte$ _inflate with this code:
Code: QB64: [Select]
  1. _Title "Edit image test" 'b+ 2021-12-29 sure would like to take an image and the subject wo background colors
  2. ' from  C:\Users\marka\Desktop\QB64 work\000 work QB64\000 Test\More Saving Images
  3. ' file "Fast Image Save and Load.bas" by SMcNeill 2021-12-07
  4.  
  5.  
  6. ''Scn& = _NewImage(800, 600, 32)  'should not need these 2 lines if loadimage with 32
  7. ''Screen Scn&
  8. Dim image&: image& = _LoadImage("turkey run.jpg", 32) ' <<<<<<<<<<<<<<<<< Edit Image file name
  9. ''Print image& ' OK -12   guess I forgot to save file before trying so in QB64 folder instead of project folder
  10. ''Sleep
  11.  
  12. Dim Scn&: Scn& = _NewImage(_Width(image&), _Height(image&), 32)
  13. Screen Scn&
  14. _Source image& ' for using Point from image
  15.  
  16. ''_ClearColor Point(10, 10), image&  ' testing a know background point to make transparent
  17. ''_PutImage , image&, 0 '
  18. ''Print "Paint test, press any... ": Sleep
  19. ''_PutImage , image&, 0 '
  20. ''Paint (10, 10), &HFFFFFFFF, &HFF000000 ' nope "turkey run.jpg" has no pure black border enclosing the image
  21. ''End
  22.  
  23. Dim mx, my, outRed, outGrn, outBlu, outAlp, x, y
  24.     Cls ' must clear screen to see what was cleared from image if anything
  25.     _PutImage , image&, 0 '
  26.     While _MouseInput: Wend ' poll mouse to show me where I am at
  27.     mx = _MouseX: my = _MouseY
  28.     Line (mx - 3, my - 3)-(mx + 3, my + 3), , B ' eraser block  black & white frame around eraser
  29.     Line (mx - 4, my - 4)-(mx + 4, my + 4), &HFF000000, B ' eraser block
  30.     cAnalysis Point(mx, my), outRed, outGrn, outBlu, outAlp
  31.     Locate 1, 1: Print Space$((_Width - 1) / 8)
  32.     Locate 1, 1: Print outRed; outGrn; outBlu; outAlp
  33.         For y = my - 2 To my + 2
  34.             For x = mx - 2 To mx + 2
  35.                 _ClearColor Point(x, y), image&
  36.             Next
  37.         Next
  38.     End If
  39.     _Display
  40.     _Limit 100
  41. Cls 'get rid of mouse stuff before save image
  42. _PutImage , image&, 0
  43.  
  44. 'Dim M As _MEM: M = _MemImage(Scn&)
  45. 'Screengrab$ = Space$(M.SIZE)
  46. '_MemGet M, M.OFFSET, Screengrab$
  47.  
  48. 'The above will:
  49. 'Dim a mem block.  Point it to your screen's image.
  50. 'Set a string that size.
  51. 'Get the whole screen at once into that string.
  52.  
  53.  
  54. 'Then to save to disk all at once:
  55. 'Open "Test SaveLoad Image.bin" For Binary As #1
  56. 'Put #1, , Screengrab$
  57. 'Close
  58. 'Open the file, put the data in one chunk, close the file.
  59.  
  60. ' hopefully the above has been encoded properly into a Sub
  61. SaveCustomImage Scn&, "Test Save Turkey Run"
  62.  
  63. Print "Press any to test load image again... "
  64.  
  65. 'Loading is the same, in reverse:
  66. 'Open "Test SaveLoad Image.bin" For Binary As #1
  67. 'Get #1, , Screengrab$
  68. 'Close
  69. 'And putting the data back to screen is also done all in one command:
  70. '_MemPut M, M.OFFSET, Screengrab$
  71.  
  72. 'And hopefully the LoadCustomImage& Function gets the data back from file
  73. Dim image2&: image2& = LoadCustomImage&("Test Save Turkey Run")
  74. _PutImage , image2&, 0 ' put back on screen
  75.  
  76. Sub cAnalysis (c As _Unsigned Long, outRed, outGrn, outBlu, outAlp)
  77.     outRed = _Red32(c): outGrn = _Green32(c): outBlu = _Blue32(c): outAlp = _Alpha32(c)
  78.  
  79. 'this will create 2 files for Custom Image:
  80. '1) FileName$ + "CI_DIM" for image dimensions
  81. '2) FileName$ + "CI" for the Custom Image data
  82. Sub SaveCustomImage (imgHdl&, fileSaveBaseName$) ' for any image setup by _newimage
  83.     Dim As Long w, h: w = _Width(imgHdl&): h = _Height(imgHdl&)
  84.     Dim M As _MEM: M = _MemImage(imgHdl&) 'Dim a mem block.  Point it to your screen's image.
  85.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE) 'Set a string that size.
  86.     'screenGrab$ = _Deflate$(screenGrab$)
  87.     _MemGet M, M.OFFSET, screenGrab$ 'Get the whole screen at once into that string.
  88.     Open fileSaveBaseName$ + ".CI_DIM" For Output As #1
  89.     Print #1, w
  90.     Print #1, h
  91.     Close #1
  92.     Open fileSaveBaseName$ + ".CI" For Binary As #1
  93.     Put #1, , screenGrab$
  94.     Close
  95.  
  96. ' Function returns Image Handle& (like _LoadFile)
  97. Function LoadCustomImage& (fileLoadBaseName$) ' reverse the Save
  98.     Dim As Long w, h
  99.     Open fileLoadBaseName$ + ".CI_DIM" For Input As #1 ' get dimensions of custom image
  100.     Input #1, w
  101.     Input #1, h
  102.     Close #1
  103.     Dim imgHdl&: imgHdl& = _NewImage(w, h, 32) 'setup space and handle for it
  104.     Dim M As _MEM: M = _MemImage(imgHdl&) ' put data into handle space reserved
  105.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE)
  106.     Open fileLoadBaseName$ + ".CI" For Binary As #1 ' get data
  107.     'screenGrab$ = Space$(LOF(1))
  108.     Get #1, , screenGrab$
  109.     Close #1
  110.     'screenGrab$ = _Inflate$(screenGrab$)  ' doesn't work
  111.     _MemPut M, M.OFFSET, screenGrab$
  112.     LoadCustomImage& = imgHdl& ' finally assign the function
  113.  

Press escape when done erasing pixels and the image is saved and the loaded and displayed to test code in subs just as it was tested in Steve's original.

Then I ran the modified image in Turkey Hunt:
Code: QB64: [Select]
  1. _Title "Turkey Shoot" 'b+ 2021-12-29   translate from BlitzMax to QB64 and modify, source:
  2. '  https://www.syntaxbomb.com/tutorials/learning-basic-for-total-beginners-blitzmax-ng/msg347053898/#msg347053898
  3. '  from MidiMaster tutorial on BlitzMax started Dec 22, 2021
  4.  
  5. ' single comments are BlitzMax code
  6. '' double comments are added notes by bplus
  7.  
  8. 'SuperStrict
  9. Option _Explicit ' must Dimension variables with types before using
  10.  
  11. '' current default type is single suffix ! not needed which is low precision float
  12.  
  13. 'Graphics 800,600
  14. '' land.png the background is 1347 X 600 so let's use a screen in same proportion  shrink by 1.1225 so no distorion of background
  15. Screen _NewImage(1200, 534, 32) ' << the 32 allows RGBA color, this sets up customized graphics screen
  16. _ScreenMove 60, 100 '' centers screen in window
  17.  
  18. 'Global Land:TImage    = LoadImage("land.png")   '' dims 1347 x 600
  19. Dim Land&: Land& = _LoadImage("land.png")
  20.  
  21. 'Global Chicken:TImage = LoadImage("chicken.png")
  22. '' for Global use Shared keyword with Dim (or ReDim or Static for Subs to preserve values)
  23. ''Dim Shared Turkey&: Turkey& = _LoadImage("turkey run.jpg")
  24. '' remove background color OK this isn't the cleanest removal , BlizMax just drew a rectangle
  25. ''_Source Turkey&
  26. ''_ClearColor Point(10, 10), Turkey&
  27. ''_ClearColor Point(64, 22), Turkey&
  28. ''_ClearColor Point(86, 133), Turkey&
  29. ''_PutImage (0, 0), Turkey&, 0
  30.  
  31. ''Do ' find points to make transparent
  32. ''    While _MouseInput: Wend
  33. ''    Locate 1, 1: Print Space$(40)
  34. ''    Locate 1, 1: Print _MouseX, _MouseY, Point(_MouseX, _MouseY) \ 256, (Point(_MouseX, _MouseY) \ 256) \ 256, ((Point(_MouseX, _MouseY) \ 256) \ 256) \ 256
  35. ''    _Display
  36. ''    _Limit 100
  37. ''Loop
  38. ''End
  39. ''_ClearColor Point(10, 10), Turkey&
  40. ''_Source 0
  41.  
  42. ' the above block was replaced with a Custom Image Load
  43. Dim Shared Turkey&: Turkey& = LoadCustomImage&("Test Save Turkey Run")
  44. _ClearColor &HFF000000, Turkey&
  45. _PutImage (100, 100), Turkey&, 0 ' I want to see how our image looks from custom load
  46. Print "Here is our target, press any to continue..."
  47.  
  48.  
  49. Dim Shared TurkeyWidth&: TurkeyWidth& = 100 '     proportional to image
  50. Dim Shared TurkeyHeight&: TurkeyHeight& = 83
  51.  
  52. 'Global Shot:TSound=LoadSound("fire.ogg")
  53. Dim Shared Shot&: Shot& = _SndOpen("fire.ogg")
  54.  
  55. 'Global cX:Int, cY:Int=300
  56. 'Global mX:Int, mY:Int
  57. 'Global Points:Int
  58. ' in QB64 you can Dim with suffix or say Type in DIM ststement
  59. 'Since we are using a Turkey instead of a Chicken:
  60. Dim Shared As Long TurkeyX, TurkeyY, MX, MY, Points
  61. TurkeyY = 350 ' for now the other values are at 0
  62.  
  63.  
  64. 'start turkey on right side of screen, this image can only run left
  65. TurkeyX = _Width
  66.  
  67.  
  68. 'Repeat
  69. ' default drawing color is already white
  70.  
  71.     'Cls '' not needed in QB64
  72.  
  73.     'DrawImage Land    , 0 , 0
  74.     _PutImage , Land&, 0 ' stretch/shrink image to fit screen  This already CLS screen
  75.  
  76.     'DrawImage Chicken , cX , cY
  77.     '   comment out the original command, and use DrawRect instead:
  78.     '    SetColor 111,0,0
  79.     '    DrawRect cX, cY, 60,40
  80.  
  81.     _PutImage (TurkeyX, TurkeyY)-Step(TurkeyWidth&, TurkeyHeight&), Turkey&, 0 ' shrink image into Box
  82.  
  83.  
  84.     '    cX = cX +2
  85.     TurkeyX = TurkeyX - Rnd * 20
  86.  
  87.     'if turkey lives to run outside of screen replace it on left side
  88.     If TurkeyX + _Width(Turkey&) < 0 Then TurkeyX = _Width + 50
  89.  
  90.  
  91.     'If GunFire() =True Then
  92.     If GunFire& Then
  93.  
  94.         ' QB64 Bonus display turkey upside down!!!
  95.         _PutImage , Land&, 0 ' stretch/shrink image to fit screen
  96.         _PutImage (TurkeyX, TurkeyY)-Step(TurkeyWidth&, TurkeyHeight&), Turkey&, 0, (0, _Height(Turkey&))-Step(_Width(Turkey&), -_Height(Turkey&))
  97.         _Display
  98.         _Delay 1 ' ha, upside down
  99.  
  100.  
  101.         '        cX=-100
  102.         TurkeyX = _Width ' reset turkey to left side of screen
  103.  
  104.         Points = Points + 1 'same for both for next loop
  105.  
  106.     End If ' same
  107.  
  108.     'SetColor 255,255,255
  109.     'DrawRect mX-25, mY-1,50,3
  110.     'DrawRect mX-1, mY-25,3,50
  111.  
  112.     ' This is for mouse scope  (the gunFire call updates mouse info in loop)
  113.     Line (MX - 20, MY)-Step(40, 0), &HFF000000
  114.     Line (MX, MY - 20)-Step(0, 40), &HFF000000
  115.     Circle (MX, MY), 8
  116.     Circle (MX, MY), 14
  117.     ''HideMouse
  118.     'did this before starting loop
  119.  
  120.     'DrawText "Points: " + points, 700,550
  121.     _PrintString (10, 10), " Points:" + Str$(Points) + " "
  122.  
  123.     'Flip
  124.     _Display ' prevent blinking form CLS
  125.     _Limit 60 ' 30 frames per second at most!
  126.  
  127.     'Until AppTerminate()
  128. Loop Until _KeyDown(27) 'quit with escape, top right x click will also close window no matter what
  129. 'ShowMouse
  130. '_MouseShow not really needed
  131.  
  132.  
  133. 'Function GunFire:Int()
  134. '        mX=MouseX()
  135. '        mY=MouseY()
  136. '        If MouseHit(1)
  137. '                PlaySound Shot
  138. '                If (mX>cX) And (mx<cX+60)
  139. '                        If (mY>cY) And (mY<cY+40)
  140. '                                ' collision
  141. '                                Return True
  142. '                        EndIf
  143. '                EndIf
  144. '        EndIf
  145. '        Return False
  146. 'End Function
  147.  
  148. Function GunFire& () ' Long integer Type
  149.     While _MouseInput: Wend ' poll mouse updates the mouse information in keyWords starting with _Mouse...
  150.     MX = _MouseX: MY = _MouseY
  151.     If _MouseButton(1) Then ' Left mouse button is down, might want to wait until released but we delay in main loop if hit
  152.         _SndPlay Shot&
  153.         If (MX > TurkeyX) And (MX < TurkeyX + TurkeyWidth&) Then
  154.             If (MY > TurkeyY) And (MY < TurkeyY + TurkeyHeight&) Then
  155.                 ' collision
  156.                 ' return True value with Function name
  157.                 GunFire& = -1 ' anything not 0 is true
  158.             End If
  159.         End If
  160.     End If
  161.     'else function returns 0
  162.  
  163. ' Function returns Image Handle& (like _LoadFile)
  164. Function LoadCustomImage& (fileLoadBaseName$) ' reverse the Save
  165.     Dim As Long w, h
  166.     Open fileLoadBaseName$ + ".CI_DIM" For Input As #1 ' get dimensions of custom image
  167.     Input #1, w
  168.     Input #1, h
  169.     Close #1
  170.     Dim imgHdl&: imgHdl& = _NewImage(w, h, 32) 'setup space and handle for it
  171.     Dim M As _MEM: M = _MemImage(imgHdl&) ' put data into handle space reserved
  172.     Dim screenGrab$: screenGrab$ = Space$(M.SIZE)
  173.     Open fileLoadBaseName$ + ".CI" For Binary As #1 ' get data
  174.     Get #1, , screenGrab$
  175.     Close #1
  176.     _MemPut M, M.OFFSET, screenGrab$
  177.     LoadCustomImage& = imgHdl& ' finally assign the function
  178.  
  179.  

Which is nice start but begging for refinements ;-))

So my question (mostly to @SMcNeill) is can the sub and function be modified to use _deflate and _inflate from the Editing app?  I left in comments to the code I tried but the playback is ending up blank without any errors flagged, so I uncommented the working save and load that I could use in Turkey Hunt.

Oh here is a zip with code, images and exes for Windows 10-64. The sound and images are for forum use only for discussion.

29
Programs / There they go!
« on: December 24, 2021, 07:54:55 pm »
Code: QB64: [Select]
  1. _Title " There they go!"
  2. Screen _NewImage(1280, 640, 32)
  3. Dim sleigh$(1 To 5)
  4. For i = 1 To 5
  5.     Read sleigh$(i)
  6. x = 1: y = _Height - 7 * 16
  7.     Cls
  8.     For i = 1 To 5
  9.         _PrintString (x, y + i * 16), sleigh$(i)
  10.     Next
  11.     x = x + 1
  12.     y = y - .5
  13.     _Display
  14.     _Limit 100
  15. Loop Until x = _Width Or y = -16 * 6
  16.  
  17. sleigh: ' thanks tsh73 at JB   len 34
  18. Data "__     _  __                      "
  19. Data "| \__ `\O/  `--  {}    \}    {/   "
  20. Data "\    \_(~)/______/=____/=____/=*  "
  21. Data " \=======/    //\\  >\/> || \>    "
  22. Data "----`---`---  `` `` ```` `` ``    "
  23.  
  24.  

30
Programs / UDT Array to Data File by Random Access Test
« on: December 24, 2021, 02:17:34 am »
Again inspired by conversation on Discord, this is something I did in 90's with old QB but never got around to testing with QB64 until now:
Code: QB64: [Select]
  1. _Title "UDT to Random Access File Test" ' b+ 2021-12-24
  2. Type Image
  3.     As String * 255 Text, FileName
  4.     As Long SzX, SzY, PosX, PosY
  5.  
  6. Const SW = 1000, SH = 700
  7. ReDim As Image TheItem(1 To 100), TheRecord
  8.  
  9. 'testing the FakeText$ function because RA is very strict on fixed strings!
  10. TheItem(1).Text = FakeText$(255)
  11. TheItem(1).FileName = FakeText$(255)
  12. Print TheItem(1).Text
  13. Print Len(TheItem(1).Text)
  14. Print TheItem(1).FileName
  15. Print Len(TheItem(1).FileName)
  16. Print "zzz"
  17.  
  18. 'make fake data to file
  19. For i = 1 To 100
  20.     TheItem(i).Text = FakeText$(255)
  21.     TheItem(i).SzX = 100 + Rnd * 20
  22.     TheItem(i).SzY = 70 + Rnd * 14
  23.     TheItem(i).PosX = Rnd * (SW - TheItem(i).SzX)
  24.     TheItem(i).PosY = Rnd * (SH - TheItem(i).SzY)
  25.     TheItem(i).FileName = FakeText$(255)
  26.  
  27. Open "Data Dump.RA" For Random As #1 Len = Len(TheRecord)
  28. For i = 1 To 100
  29.     'odious and tedious is this
  30.     TheRecord.Text = TheItem(i).Text
  31.     TheRecord.SzX = TheItem(i).SzX
  32.     TheRecord.SzY = TheItem(i).SzY
  33.     TheRecord.PosX = TheItem(i).PosX
  34.     TheRecord.PosY = TheItem(i).PosY
  35.     TheRecord.FileName = TheItem(i).FileName
  36.     Put #1, , TheRecord
  37. Print "Data File Ready"
  38.  
  39. ' OK we got data filed! Now can we get it back
  40. Open "Data Dump.RA" For Random As #1 Len = Len(TheRecord)
  41. For i = 1 To 100
  42.     Cls
  43.     Get #1, i, TheRecord
  44.     Print "Record Number:"; i
  45.     Print "Text: "; TheRecord.Text
  46.     Print "SzX:"; TheRecord.SzX
  47.     Print "SzY:"; TheRecord.SzY
  48.     Print "PosX:"; TheRecord.PosX
  49.     Print "PosY:"; TheRecord.PosY
  50.     Print "FileName:"; TheRecord.FileName
  51.     Print " zzz..."
  52.     Sleep
  53.  
  54. Function FakeText$ (lengthh)
  55.     BlankString$ = Space$(lengthh)
  56.     fini = Int(Rnd * 255) + 1
  57.     For i = 1 To fini
  58.         Mid$(BlankString$, i, 1) = Chr$(Rnd * (96 - 32) + 32)
  59.     Next
  60.     FakeText$ = BlankString$
  61.  

Pages: 1 [2] 3 4 ... 21