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 ... 3 4 [5] 6 7 ... 21
61
Programs / Word ladder - Rosetta Code
« on: September 03, 2021, 08:46:12 pm »
ref: http://rosettacode.org/wiki/Word_ladder

Oh this was a little more tricky!

Code: QB64: [Select]
  1. _Title "Word ladder - Rosetta Code" 'b+ start 2021-09-03 ref: http://rosettacode.org/wiki/Word_ladder
  2. Type connectType
  3.     connect As String
  4.     word As String
  5.  
  6. Dim Shared wordList$(2 To 7)
  7. LoadWords 'build the strings for each word length the split them for that length
  8. Print ladder$("boy", "man") '     quick
  9. Print ladder$("girl", "lady") '   this takes awhile
  10. Print ladder$("john", "jane") '   quick enough
  11. Print ladder$("alien", "drool") ' cool but takes a long long time!
  12. Print ladder$("child", "adult") ' and this takes awhile
  13. Print ladder$("play", "ball") '   goes quick
  14. Print ladder$("fun", "job") '     ditto
  15.  
  16. Sub LoadWords
  17.     Open "unixdict.txt" For Input As #1
  18.     While EOF(1) = 0
  19.         Input #1, wd$
  20.         If Len(wd$) > 1 And Len(wd$) < 8 Then
  21.             ok = -1
  22.             For m = 1 To Len(wd$)
  23.                 If Asc(wd$, m) < 97 Or Asc(wd$, m) > 122 Then ok = 0: Exit For
  24.             Next
  25.             If ok Then
  26.                 If wordList$(Len(wd$)) = "" Then wordList$(Len(wd$)) = wd$ Else wordList$(Len(wd$)) = wordList$(Len(wd$)) + " " + wd$
  27.             End If
  28.         End If
  29.     Wend
  30.     Close #1
  31.  
  32. Function ladder$ (w1$, w2$)
  33.     If Len(w1$) <> Len(w2$) Then ladder$ = "": Exit Function
  34.     ReDim TheList(1 To 1) As connectType, listPlace
  35.     ReDim wl$(1 To 1)
  36.     Split wordList$(Len(w1$)), " ", wl$()
  37.     connect$ = w1$
  38.  
  39.     newConnect:
  40.     'progress
  41.     'Print "Connect word is "; connect$; UBound(wl$); listPlace;
  42.     For i = 1 To UBound(wl$)
  43.         If oneChange%(connect$, wl$(i)) Then
  44.             If TheList(1).connect = "" Then
  45.                 TheList(1).connect = connect$
  46.                 TheList(1).word = wl$(i)
  47.             Else ' add to list only if word isn't a connect
  48.                 found = 0
  49.                 For j = 1 To UBound(theList)
  50.                     If wl$(i) = TheList(j).connect Then found = -1: Exit For
  51.                 Next
  52.                 If found = 0 Then
  53.                     cAppend TheList(), connect$, wl$(i)
  54.                 End If
  55.             End If
  56.             If wl$(i) = w2$ Then done = -1: Exit For
  57.         End If
  58.     Next
  59.     If done = 0 Then
  60.         listPlace = listPlace + 1
  61.         If listPlace > UBound(TheList) Then
  62.             ladder$ = "Could NOT connect " + w1$ + " to " + w2$
  63.         Else
  64.             connect$ = TheList(listPlace).word
  65.             GoTo newConnect
  66.         End If
  67.     Else
  68.         'should be able to backtrack our path?
  69.         ladder$ = "Could connect " + w1$ + " to " + w2$
  70.         target$ = w2$: trail$ = w2$
  71.         again:
  72.         For i = 1 To UBound(theList)
  73.             If TheList(i).word = target$ Then target$ = TheList(i).connect: trail$ = target$ + " > " + trail$: GoTo again
  74.         Next
  75.         ladder$ = ladder$ + Chr$(10) + trail$
  76.     End If
  77.  
  78. Sub Split (SplitMeString As String, delim As String, loadMeArray() As String)
  79.     Dim curpos As Long, arrpos As Long, LD As Long, dpos As Long 'fix use the Lbound the array already has
  80.     curpos = 1: arrpos = LBound(loadMeArray): LD = Len(delim)
  81.     dpos = InStr(curpos, SplitMeString, delim)
  82.     Do Until dpos = 0
  83.         loadMeArray(arrpos) = Mid$(SplitMeString, curpos, dpos - curpos)
  84.         arrpos = arrpos + 1
  85.         If arrpos > UBound(loadMeArray) Then ReDim _Preserve loadMeArray(LBound(loadMeArray) To UBound(loadMeArray) + 1000) As String
  86.         curpos = dpos + LD
  87.         dpos = InStr(curpos, SplitMeString, delim)
  88.     Loop
  89.     loadMeArray(arrpos) = Mid$(SplitMeString, curpos)
  90.     ReDim _Preserve loadMeArray(LBound(loadMeArray) To arrpos) As String 'get the ubound correct
  91.  
  92. Sub cAppend (arr() As connectType, cWrd$, w$)
  93.     ReDim _Preserve arr(LBound(arr) To UBound(arr) + 1) As connectType
  94.     arr(UBound(arr)).connect = cWrd$
  95.     arr(UBound(arr)).word = w$
  96.  
  97. Function oneChange% (last$, test$)
  98.     For i = 1 To Len(last$)
  99.         If Mid$(last$, i, 1) <> Mid$(test$, i, 1) Then strike = strike + 1
  100.     Next
  101.     If strike = 1 Then oneChange% = -1
  102.  
  103.  
  104.  

Same unixdict.txt for words attached and screen shot of output.
 
Word ladder output.PNG


All original in Basic!

62
Programs / Wordiff - Rosetta Code
« on: September 03, 2021, 12:33:54 am »
ref: http://rosettacode.org/wiki/Wordiff

I think I have the game roughed out now and will go for the "Optional Stretch Goals" with the scores array tomorrow. Kind'a fun to play :)

Code: QB64: [Select]
  1. _Title "Wordiff - Rosetta Code" 'b+ 2021-09-02 ref: http://rosettacode.org/wiki/Wordiff
  2. Const nWords = 24819 ' precounted for  unixdict.txt word list
  3. Dim Shared words$(1 To nWords), used$(1 To 1000), nUsed, players$(1 To 100), scores(1 To 100), nPlayers, nextPlayer
  4.  
  5. LoadWords
  6. getPlayers
  7. nextPlayer = 1
  8.  
  9. newRound:
  10. lastWord$ = StartWord$
  11. Print "Start word is "; lastWord$
  12. bad = 0
  13.     Print players$(nextPlayer);
  14.     Input ", please enter your try "; try$
  15.     For i = 1 To nUsed
  16.         If try$ = used$(i) Then Print "I'm sorry, " + players$(nextPlayer) + ", " + try$ + " was already used.": bad = -1
  17.     Next
  18.     If bad = 0 Then
  19.         If wordFound%(try$) Then
  20.             If Len(try$) = Len(lastWord$) - 1 Then
  21.                 If oneLess%(lastWord$, try$) Then Print "Good" Else Print try$ + " doesn't work.": bad = -1
  22.             ElseIf Len(try$) = Len(lastWord$) Then
  23.                 If oneChange%(lastWord$, try$) Then Print "Good" Else Print try$ + " doesn't work.": bad = -1
  24.             ElseIf Len(try$) = Len(lastWord$) + 1 Then
  25.                 If oneMore%(lastWord$, try$) Then Print "Good" Else Print try$ + " doesn't work.": bad = -1
  26.             Else
  27.                 Print "I'm sorry, " + players$(nextPlayer) + ", " + try$ + " was not the correct length.": bad = -1
  28.             End If
  29.         Else
  30.             Print "I'm sorry, " + players$(nextPlayer) + ", " + try$ + " was not found in dictionary.": bad = -1
  31.         End If
  32.     End If
  33.     If bad = 0 Then
  34.         nUsed = nUsed + 1
  35.         used$(nUsed) = try$
  36.         lastWord$ = try$
  37.     End If
  38.     nextPlayer = nextPlayer + 1
  39.     If nextPlayer > nPlayers Then nextPlayer = 1
  40. GoTo newRound
  41.  
  42. Sub LoadWords
  43.     Dim wd$, i As Integer, m As Integer, ok As _Bit
  44.     Open "unixdict.txt" For Input As #1
  45.     While EOF(1) = 0
  46.         Input #1, wd$
  47.         If Len(wd$) > 2 Then
  48.             ok = -1
  49.             For m = 1 To Len(wd$)
  50.                 If Asc(wd$, m) < 97 Or Asc(wd$, m) > 122 Then ok = 0: Exit For
  51.             Next
  52.             If ok Then i = i + 1: words$(i) = wd$
  53.         End If
  54.     Wend
  55.     Close #1
  56.  
  57. Sub getPlayers
  58.     nPlayers = 0
  59.     Do
  60.         Input "Enter a player name or nothing to finish list "; player$
  61.         If player$ <> "" Then nPlayers = nPlayers + 1: players$(nPlayers) = player$
  62.     Loop Until player$ = ""
  63.     If nPlayers = 0 Then Print "No players, goodbye!"
  64.  
  65. Function StartWord$
  66.     Do
  67.         StartWord$ = words$(Int(Rnd * nWords) + 1)
  68.         If Len(StartWord$) > 2 And Len(StartWord$) < 5 Then
  69.             OK = -1
  70.             For i = 1 To nUsed ' let us at least not start with a word used in last game
  71.                 If used$(i) = StartWord$ Then OK = 0
  72.             Next
  73.         End If
  74.         If OK Then Erase used$: nUsed = 1: used$(1) = StartWord$
  75.     Loop Until OK
  76.  
  77. Function wordFound% (word$) ' is the word 3 or more letters in dictionary
  78.     If Len(word$) > 2 Then
  79.         lo = 1: hi = nWords
  80.         Do While wordFound% = 0
  81.             test = Int((hi + lo) / 2)
  82.             If words$(test) = word$ Then
  83.                 wordFound% = -1: Exit Function
  84.             ElseIf words$(test) < word$ Then
  85.                 lo = test + 1
  86.             Else
  87.                 hi = test - 1
  88.             End If
  89.             If hi < lo Then Exit Function
  90.         Loop
  91.     End If
  92.  
  93. Function oneLess% (last$, test$) ' is word one letter less than last word
  94.     If Len(test$) = Len(last$) - 1 Then
  95.         lastfind = 1
  96.         For i = 1 To Len(test$)
  97.             find = InStr(lastfind, last$, Mid$(test$, i, 1))
  98.             If find = 0 Then Exit Function Else lastfind = find + 1
  99.         Next
  100.         oneLess% = -1
  101.     End If
  102.  
  103. Function oneMore% (last$, test$) ' is word one letter more than last word
  104.     If Len(test$) = Len(last$) + 1 Then
  105.         lastfind = 1
  106.         For i = 1 To Len(last$)
  107.             find = InStr(lastfind, test$, Mid$(lasst$, i, 1))
  108.             If find = 0 Then Exit Function Else lastfind = find + 1
  109.         Next
  110.         oneMore% = -1
  111.     End If
  112.  
  113. Function oneChange% (last$, test$)
  114.     If Len(test$) = Len(last$) Then
  115.         For i = 1 To Len(last$)
  116.             If Mid$(last$, i, 1) <> Mid$(test$, i, 1) Then strike = strike + 1
  117.         Next
  118.         If strike = 1 Then oneChange% = -1
  119.     End If
  120.  
  121.  

Attached is dictionary used at RC (doesn't have "has")

63
Hello QB64 developers,

https://www.qb64.org/forum/index.php?topic=4134.msg134972#msg134972
This discussion has led me to wonder when the next stable release might occur?

I really don't want to mess with dev versions if we are close to next stable.

My guess, this is up to @FellippeHeitor and the Debug update. True?


64
Programs / Creep Out
« on: August 19, 2021, 03:51:19 pm »
Quote
Creepy break-out? Hmm... Interesting. I like the sound of that... Moo Ha Ha....

Here is v2021-08-19A


65
Programs / String Collapse Function - Rosetta Code
« on: July 28, 2021, 08:27:57 pm »
Code: QB64: [Select]
  1. _Title "Collapse String Function - Rosetta Code" 'b+ 2021-07-28
  2. ' ref: http://rosettacode.org/wiki/Determine_if_a_string_is_collapsible
  3. t$(1) = "" ' a null string  (length zero)
  4. t$(2) = Chr$(34) + "If I were two-faced, would I be wearing this one?" + Chr$(34) + " --- Abraham Lincoln "
  5. t$(3) = "..1111111111111111111111111111111111111111111111111111111111111117777888"
  6. t$(4) = "I never give 'em hell, I just tell the truth, and they think it's hell. "
  7. t$(5) = "                                                    --- Harry S Truman  "
  8. For i = 1 To 5
  9.     Print t$(i); Len(t$(i))
  10.     Print collapse$(t$(i)); Len(collapse$(t$(i)))
  11.  
  12. Function collapse$ (s$)
  13.     If Len(s$) < 2 Then collapse$ = s$: Exit Function
  14.     c$ = Mid$(s$, 1, 1)
  15.     collapse$ = c$
  16.     For i = 2 To Len(s$)
  17.         If Mid$(s$, i, 1) <> c$ Then c$ = Mid$(s$, i, 1): collapse$ = collapse$ + c$
  18.     Next
  19.  

Hey, about 10 lines less than FreeBASIC's entry. ;-))

66
Programs / Sailors and Coconuts Rosetta Code
« on: July 03, 2021, 11:04:33 pm »
http://rosettacode.org/wiki/Sailors,_coconuts_and_a_monkey_problem

With the present limit on main For loop, you can do 6 sailors:
Code: QB64: [Select]
  1. Input "Please enter number of sailors that collect coconuts "; s
  2. For i = 1 To 250000
  3.     n = i
  4.     For j = 1 To s
  5.         If n Mod s = 1 Then
  6.             n = n - Int(n / s) - 1
  7.         Else
  8.             GoTo skip
  9.         End If
  10.     Next
  11.     If n Mod s = 0 Then Print i: End
  12.     skip:
  13.  

PS for once FreeBasic follows QB64, see Word Search at RC. :)

67
Programs / Simple Simon
« on: June 27, 2021, 04:17:45 pm »
Code: QB64: [Select]
  1. _Title "Simple Simon"  'b+ 2021-06-27
  2.     b$ = b$ + _Trim$(Str$(Int(Rnd * 4) + 1))
  3.     For i = 1 To Len(b$)
  4.         Cls
  5.         Print Space$(i - 1); Mid$(b$, i, 1)
  6.         _Delay 1
  7.     Next
  8.     Cls
  9.     Print "Simon says repeat all that:"
  10.     For i = 1 To Len(b$)
  11.         k$ = InKey$
  12.         While k$ = ""
  13.             k$ = InKey$
  14.         Wend
  15.         Print k$;
  16.         If k$ <> Mid$(b$, i, 1) Then
  17.             Beep
  18.             Print
  19.             Print b$
  20.             Exit While
  21.         End If
  22.     Next

No Double Parking (with colons)


68
Programs / Spinner
« on: June 19, 2021, 07:54:36 pm »
A subject started at JB forum by tsh73, this is the version I came up with that won't work (way too slow) there but works great here in QB64:

Code: QB64: [Select]
  1. _Title "Spinner" 'b+ 2021-06-18
  2. Screen _NewImage(500, 500, 32)
  3. Const rad = _Pi / 180
  4.     Cls
  5.     b = b + 5
  6.     For r = 20 To 200 Step 20 ' tsh73 suggested fix for inner most
  7.         a = b * r / 20
  8.         For i = r - 15 To r
  9.             arc 250, 250, i, a, 180
  10.         Next
  11.     Next
  12.     _Display
  13.     _Limit 15
  14.  
  15. Sub arc (xCenter, yCenter, arcRadius, dAStart, dAMeasure)
  16.     'notes:
  17.     'you may want to adjust size and color for line drawing
  18.     'using angle measures in degrees to match Just Basic ways with pie and piefilled
  19.     'this sub assumes drawing in a CW direction if dAMeasure positive
  20.  
  21.     'for Just Basic angle 0 degrees is due East and angle increases clockwise towards South
  22.  
  23.     'dAStart is degrees to start Angle, due East is 0 degrees
  24.  
  25.     'dAMeasure is degrees added (Clockwise) to dAstart for end of arc
  26.  
  27.     rAngleStart = rad * dAStart
  28.     rAngleEnd = rad * dAMeasure + rAngleStart
  29.     Stepper = rad / (.1 * arcRadius) 'fixed
  30.     lastX = xCenter + arcRadius * Cos(rAngleStart)
  31.     lastY = yCenter + arcRadius * Sin(rAngleStart)
  32.     PSet (lastX, lastY)
  33.     For rAngle = rAngleStart + Stepper To rAngleEnd Step Stepper
  34.         nextX = xCenter + arcRadius * Cos(rAngle)
  35.         nextY = yCenter + arcRadius * Sin(rAngle)
  36.         Line -(nextX, nextY) 'int speeds things up
  37.     Next



69
Programs / Missile Command
« on: June 11, 2021, 07:51:51 pm »
A simple little game (I just learned about at LB):
Code: QB64: [Select]
  1. W = 800: H = 600
  2. Screen _NewImage(800, 600, 32)
  3. a:
  4. a = Rnd * W: b = 0: c = Rnd * 6 - 3: d = Rnd * 3 + 3: u = 0: v = 0: x = 400: y = H
  5.     _Title "MC hits:" + Str$(t) + ", misses:" + Str$(m)
  6.     If _MouseButton(1) Then e = _MouseX - 400: f = _MouseY - H: z = (e ^ 2 + f ^ 2) ^ .5: u = 5 * e / z: v = 5 * f / z
  7.     x = x + u: y = y + v: a = a + c: b = b + d
  8.     If x < 0 Or y < 0 Or a < 0 Or b < 0 Or x > W Or a > W Or b > H Then
  9.         If b > H Or x < 0 Or y < 0 Or x > W Then m = m + 1
  10.         GoTo a:
  11.     End If
  12.     If ((x - a) ^ 2 + (y - b) ^ 2) ^ .5 < 20 Then
  13.         For r = 1 To 20 Step 4
  14.             Circle ((x + a) / 2, (y + b) / 2), r
  15.             _Limit 60
  16.         Next
  17.         t = t + 1: GoTo a:
  18.     Else
  19.         PSet (x, y): PSet (a, b)
  20.     End If
  21.     _Limit 20
  22.  

Your missile base is at bottom, middle of screen. When you click mouse you want your missile to strike the incoming one before it reaches the bottom of screen. If incoming is not going to reach bottom don't worry about it unless you can hit it for sure (not likely).

70
Programs / Swizzle
« on: May 29, 2021, 01:24:17 pm »
A quickie:
Code: QB64: [Select]
  1. _Title "Swizzle" ' b+ 2021-05-29
  2. Const Xmax = 600, Ymax = 600, cxy = 300, Pi = _Pi
  3. Screen _NewImage(Xmax, Ymax, 32)
  4. _Delay .25
  5. Dim vScreenR(Xmax, Ymax), vScreenG(Xmax, Ymax), vScreenB(Xmax, Ymax)
  6. restart:
  7. r = Rnd * Rnd: g = Rnd * Rnd: b = Rnd * Rnd
  8. For x = 0 To Xmax
  9.     Line (x, 0)-(x, Ymax), _RGB32(128 + 128 * Sin(r * x), 128 + 128 * Sin(g * x), 128 + 128 * Sin(b * x))
  10.     For y = 0 To Ymax
  11.         vScreenR(x, y) = 128 + 128 * Sin(r * x)
  12.         vScreenG(x, y) = 128 + 128 * Sin(g * x)
  13.         vScreenB(x, y) = 128 + 128 * Sin(b * x)
  14.     Next
  15. swizzle = Rnd * .5 + .8
  16. _Title "Swizzle @" + _Trim$(Str$(swizzle))
  17. For radius = 1 To 200
  18.     For a = 0 To 2 * Pi Step 1 / (2 * Pi * radius)
  19.         x = Int(cxy + radius * Cos(a))
  20.         y = Int(cxy + radius * Sin(a))
  21.         r = vScreenR(x, y)
  22.         g = vScreenG(x, y)
  23.         b = vScreenB(x, y)
  24.         PSet (cxy + radius * Cos(a + radius ^ swizzle * Pi / 180), cxy + radius * Sin(a + radius ^ swizzle * Pi / 180)), _RGB32(r, g, b)
  25.     Next
  26. GoTo restart
  27.  

 
Swizzle number.PNG


71
Is it possible to tell a compiled QB64 exe from other exe's say for instance FB?

If so, then my follow up question is how?

72
Programs / Mouse Event Test
« on: May 17, 2021, 12:49:27 pm »
This might be interesting way to go with Mouse Button clicks?
Code: QB64: [Select]
  1. _Title "Mouse Event test" 'b+ 2021-05-17
  2.  
  3. Dim Shared mx, my, mb1DownX, mb1DownY, mb1UpX, mb1UpY, oldmb1
  4.  
  5. t1 = _FreeTimer 'get a timer number from _FREETIMER ONLY!
  6. On Timer(t1, .05) PollMouse
  7. Timer(t1) On
  8.  
  9. ' signal no button locations registered yet
  10. mb1DownX = -1
  11. mb1DownY = -1
  12. mb1UpX = -1
  13. mb1UpY = -1
  14.  
  15.     Cls
  16.     Print "         Mouse location at:"; mx; ","; my
  17.     Print "  Status Left Button Down: "; oldmb1
  18.     Print "First Mouse Button Down at:"; mb1DownX; ","; mb1DownY
  19.     Print "   Last Mouse Button Up at:"; mb1UpX; ","; mb1UpY
  20.     _Display
  21. Timer(t1) Free 'release timer
  22.  
  23. Sub PollMouse ' catch locations of mouse button 1 down and up
  24.     mx = _MouseX: my = _MouseY: mb1 = _MouseButton(1)
  25.     If mb1 And oldmb1 = 0 Then
  26.         mb1DownX = mx
  27.         mb1DownY = my
  28.         'mb1UpX = 0
  29.         'mb1UpY = 0
  30.     End If
  31.     If mb1 = 0 And oldmb1 Then
  32.         mb1UpX = mx
  33.         mb1UpY = my
  34.         'mb1DownX = 0
  35.         'mb1DownY = 0
  36.     End If
  37.     oldmb1 = mb1
  38.  
  39.  

Always wanted to try something like this.

BTW look at the example for On Timer Event, it is about mouse which I used to start this code test.

If MB1 then mb1DownX and mb1DownY are latest first down at locations.
If MB1 = 0 then mb1UpX, mb1UpY was location of last release of mouse button 1 which you can clear (set -1) when you have handled the Click.

73
Programs / A New Wrinkle with Voronoi
« on: May 10, 2021, 02:41:48 am »
Shading gives us a lovely psuedo-3D effect!
Code: QB64: [Select]
  1. _Title "Shading Voronoi Demo" 'b+ 2019-12-11  shading 2021-05-10
  2. Const xymax = 700, nPoints = 50
  3. Type pType
  4.     x As Single
  5.     y As Single
  6.     c As _Unsigned Long
  7. Screen _NewImage(xymax, xymax, 32)
  8. _ScreenMove 300, 20
  9. Dim pts(1 To nPoints) As pType
  10. For i = 1 To nPoints
  11.     pts(i).x = xymax * Rnd
  12.     pts(i).y = xymax * Rnd
  13.     pts(i).c = _RGB32(155 * Rnd + 100, -(Rnd < .5) * 255 * Rnd, -(Rnd < .5) * 255 * Rnd)
  14. For i = 1 To nPoints
  15.     Circle (pts(i).x, pts(i).y), 5, pts(i).c
  16. For y = 0 To xymax
  17.     For x = 0 To xymax
  18.         minD = 49000
  19.         For p = 1 To nPoints
  20.             d = ((pts(p).x - x) ^ 2 + (pts(p).y - y) ^ 2) ^ .5
  21.             If d < minD Then minD = d: saveP = p
  22.         Next
  23.         PSet (x, y), Ink~&(pts(saveP).c, &HFF000000, minD / 85)
  24.     Next
  25.  
  26. Sub cAnalysis (c As _Unsigned Long, outRed, outGrn, outBlu, outAlp)
  27.     outRed = _Red32(c): outGrn = _Green32(c): outBlu = _Blue32(c): outAlp = _Alpha32(c)
  28.  
  29. Function Ink~& (c1 As _Unsigned Long, c2 As _Unsigned Long, fr##)
  30.     Dim R1, G1, B1, A1, R2, G2, B2, A2
  31.     cAnalysis c1, R1, G1, B1, A1
  32.     cAnalysis c2, R2, G2, B2, A2
  33.     Ink~& = _RGB32(R1 + (R2 - R1) * fr##, G1 + (G2 - G1) * fr##, B1 + (B2 - B1) * fr##, A1 + (A2 - A1) * fr##)
  34.  
  35.  

 
Shading Voronoi.PNG

74
Programs / Collision Study #4
« on: May 09, 2021, 07:55:36 pm »
This version seems to be working better than my last:

Code: QB64: [Select]
  1. _Title "Collision Study #4   press spacebar to toggle tracer" ' b+ 2021-05-09 by bplus
  2. ' from  "Collision Study #3 Brownian Motion 2018-03-31 by bplus (which was terrible idea of Brownian Motion)
  3. ' This time I want to bounce balls with the closest collision first (in case ball is coliidable with 2 or more others)
  4. ' PLUS this time I wont change current arrays of ball data but store into NextArray so all bounces are calc'd
  5. '      before any new drawing takes place.  YES! I think this works better.
  6. ' All radii are const for less calc, need balls different colored
  7.  
  8.  
  9. Const Xmax = 600 ' screen width
  10. Const Ymax = 600 ' screen height
  11. Const R = 50 '     balls radii
  12. Const Balls = 18 ' number of balls
  13. Type Ball
  14.     As Long x, y, rr, gg, bb ' screen location and RGB colors
  15.     As Double dx, dy ' dx, dy = change x, y axis
  16.  
  17. Screen _NewImage(Xmax, Ymax, 32)
  18. _Delay .25
  19. ' these can be static as no balls added or subtracted in closed system
  20. Dim As Ball b(1 To Balls), nf(1 To Balls) ' b() is current frame balls data , nf( ) is for next frame balls data
  21. Dim As Long clrMode, i, rad, j
  22. clrMode = 1
  23. For i = 1 To Balls
  24.     b(i).x = rand(R, Xmax - R)
  25.     b(i).y = rand(R, Ymax - R)
  26.     b(i).dx = Rnd * 4 + 1 * rdir
  27.     b(i).dy = Rnd * 4 + 1 * rdir
  28.     b(i).rr = rand%(180, 255)
  29.     b(i).gg = rand%(180, 255)
  30.     b(i).bb = rand%(180, 255)
  31.  
  32.     k$ = InKey$
  33.     If Len(k$) Then
  34.         If Asc(k$) = 32 Then clrMode = -1 * clrMode
  35.         If Asc(k$) = 27 And Len(k$) = 1 Then End
  36.     End If
  37.     If clrMode > 0 Then Cls
  38.  
  39.     For i = 1 To Balls ' draw balls then  update for next frame
  40.  
  41.         For rad = R To 1 Step -1
  42.             Color _RGB32(b(i).rr - rad / R * 150, b(i).gg - rad / R * 150, b(i).bb - rad / R * 150)
  43.             fcirc b(i).x, b(i).y, rad
  44.         Next
  45.  
  46.         ' check for collision
  47.         cd = 100000: saveJ = 0
  48.         For j = 1 To Balls 'find deepest collision
  49.             If i <> j Then
  50.                 dx = b(i).x - b(j).x: dy = b(i).y - b(j).y
  51.                 If dx * dx + dy * dy < (2 * R) * (2 * R) Then ' collision but is it first or deepest collision
  52.                     If R * R - dx * dx + dy * dy < cd Then cd = (2 * R) * (2 * R) - dx * dx + dy * dy: saveJ = j
  53.                 End If
  54.             End If
  55.         Next
  56.         If cd <> 100000 Then ' found collision change ball i dx, dy   calc new course for ball i
  57.             a = _Atan2(b(i).y - b(saveJ).y, b(i).x - b(saveJ).x)
  58.             power1 = (b(i).dx ^ 2 + b(i).dy ^ 2) ^ .5
  59.             power2 = (b(saveJ).dx ^ 2 + b(saveJ).dy ^ 2) ^ .5
  60.             power = (power1 + power2) / 2
  61.             nf(i).dx = power * Cos(a)
  62.             nf(i).dy = power * Sin(a)
  63.         Else ' no collision
  64.             nf(i).dx = b(i).dx
  65.             nf(i).dy = b(i).dy
  66.         End If
  67.         'update location of ball next frame
  68.         nf(i).x = b(i).x + nf(i).dx
  69.         nf(i).y = b(i).y + nf(i).dy
  70.  
  71.         ' check in bounds next frame
  72.         If nf(i).x < R Then nf(i).dx = -nf(i).dx: nf(i).x = R
  73.         If nf(i).x > Xmax - R Then nf(i).dx = -nf(i).dx: nf(i).x = Xmax - R
  74.         If nf(i).y < R Then nf(i).dy = -nf(i).dy: nf(i).y = R
  75.         If nf(i).y > Ymax - R Then nf(i).dy = -nf(i).dy: nf(i).y = Ymax - R
  76.     Next
  77.  
  78.     'now that we've gone through all old locations update b() with nf() data
  79.     For i = 1 To Balls
  80.         b(i).x = nf(i).x: b(i).y = nf(i).y
  81.         b(i).dx = nf(i).dx: b(i).dy = nf(i).dy
  82.     Next
  83.     ' next frame ready to draw
  84.     _Display
  85.     _Limit 60
  86.  
  87. Function rand% (lo As Integer, hi As Integer)
  88.     rand% = (Rnd * (hi - lo + 1)) \ 1 + lo
  89.  
  90. Function rdir ()
  91.     If Rnd < .5 Then rdir = -1 Else rdir = 1
  92.  
  93. 'Steve McNeil's  copied from his forum   note: Radius is too common a name
  94. Sub fcirc (CX As Long, CY As Long, R As Long)
  95.     Dim subRadius As Long, RadiusError As Long
  96.     Dim X As Long, Y As Long
  97.  
  98.     subRadius = Abs(R)
  99.     RadiusError = -subRadius
  100.     X = subRadius
  101.     Y = 0
  102.  
  103.     If subRadius = 0 Then PSet (CX, CY): Exit Sub
  104.  
  105.     ' Draw the middle span here so we don't draw it twice in the main loop,
  106.     ' which would be a problem with blending turned on.
  107.     Line (CX - X, CY)-(CX + X, CY), , BF
  108.  
  109.     While X > Y
  110.         RadiusError = RadiusError + Y * 2 + 1
  111.         If RadiusError >= 0 Then
  112.             If X <> Y + 1 Then
  113.                 Line (CX - Y, CY - X)-(CX + Y, CY - X), , BF
  114.                 Line (CX - Y, CY + X)-(CX + Y, CY + X), , BF
  115.             End If
  116.             X = X - 1
  117.             RadiusError = RadiusError - X * 2
  118.         End If
  119.         Y = Y + 1
  120.         Line (CX - X, CY - Y)-(CX + X, CY - Y), , BF
  121.         Line (CX - X, CY + Y)-(CX + X, CY + Y), , BF
  122.     Wend
  123.  
  124.  

75
Code: QB64: [Select]
  1. '  Collision Study Mouse and Ball.bas for QB64 fork (B+=MGA) 2017-08-23
  2. 'updated from: Collision study mouse and ball.bas for QB64 fork (B+=MGA) trans 2017-08-20
  3. 'translated from "collision mouse study.bas"  SmallBASIC version 2017-01-10
  4. 'which was modify the yab version from six posts to one mouse
  5.  
  6. Const xmax = 800
  7. Const ymax = 600
  8. Screen _NewImage(xmax, ymax, 32)
  9. _Title "Collision Study: Mouse versus Ball - bplus"
  10.  
  11. Const RADIUS = 30 ' radius for both ball and angle
  12. Const SPEED = 5
  13. ba = _Pi(1 / 6) 'ball angle in radians
  14. bx = xmax / 2 'ball x
  15. by = ymax / 2 'ball y
  16.  
  17.  
  18.     Cls , _RGB(30, 70, 48)
  19.     If _KeyHit = 27 Then End 'pressed escape goodbye!
  20.  
  21.     'paddle px, py location
  22.     While _MouseInput: Wend  ' <<<<<<<<<< this code so old I had to fix this
  23.     px = _MouseX: py = _MouseY
  24.  
  25.     pbDistance = Sqr((px - bx) ^ 2 + (py - by) ^ 2)
  26.     'LOCATE 1, 1: PRINT px, py, pbDistance  'debug
  27.  
  28.     'show paddle
  29.     For i = RADIUS To 0 Step -1
  30.         Color _RGB(255 - i * 5, 0, 0)
  31.         CircleFill px, py, i
  32.     Next
  33.  
  34.     'update ball hit paddle
  35.     If Sqr((px - bx) ^ 2 + (py - by) ^ 2) < RADIUS * 2 Then ba = _Atan2(by - py, bx - px)
  36.  
  37.     'handle ball hit border
  38.     If bx < 0 + RADIUS Then ba = _Pi(1) - ba: bx = RADIUS
  39.     If bx > xmax - RADIUS Then ba = _Pi(1) - ba: bx = xmax - RADIUS
  40.     If by < 0 + RADIUS Then ba = -ba: by = RADIUS
  41.     If by > ymax - RADIUS Then ba = -ba: by = ymax - RADIUS
  42.  
  43.     'ball angle adjustments to keep between 0 and 2*pi
  44.     If ba > 2 * _Pi(1) Then ba = ba - _Pi(2)
  45.     If ba < 0 Then ba = ba + _Pi(2)
  46.  
  47.     'OK the ball is here
  48.     bx = bx + Cos(ba) * SPEED
  49.     by = by + Sin(ba) * SPEED
  50.  
  51.     'show ball
  52.     For i = RADIUS To 0 Step -1
  53.         Color _RGB(255 - i * 6, 255 - i * 6, 255 - i * 6)
  54.         CircleFill bx, by, i
  55.     Next
  56.  
  57.     'update screen and keep loops under 61 per second
  58.     _Display
  59.     _Limit 60
  60.  
  61. 'Steve McNeil's  copied from his forum
  62. Sub CircleFill (CX As Long, CY As Long, R As Long)
  63.     Dim subRADIUS As Long, RadiusError As Long
  64.     Dim X As Long, Y As Long
  65.  
  66.     subRADIUS = Abs(R)
  67.     RadiusError = -subRADIUS
  68.     X = subRADIUS
  69.     Y = 0
  70.  
  71.     If subRADIUS = 0 Then PSet (CX, CY): Exit Sub
  72.  
  73.     ' Draw the middle span here so we don't draw it twice in the main loop,
  74.     ' which would be a problem with blending turned on.
  75.     Line (CX - X, CY)-(CX + X, CY), , BF
  76.  
  77.     While X > Y
  78.         RadiusError = RadiusError + Y * 2 + 1
  79.         If RadiusError >= 0 Then
  80.             If X <> Y + 1 Then
  81.                 Line (CX - Y, CY - X)-(CX + Y, CY - X), , BF
  82.                 Line (CX - Y, CY + X)-(CX + Y, CY + X), , BF
  83.             End If
  84.             X = X - 1
  85.             RadiusError = RadiusError - X * 2
  86.         End If
  87.         Y = Y + 1
  88.         Line (CX - X, CY - Y)-(CX + X, CY - Y), , BF
  89.         Line (CX - X, CY + Y)-(CX + X, CY + Y), , BF
  90.     Wend
  91.  
  92.  
  93.  


Pages: 1 ... 3 4 [5] 6 7 ... 21