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 - SMcNeill

Pages: 1 [2] 3 4 ... 16
16
QB64 Discussion / Steve's Xmas Game 2021
« on: November 26, 2021, 07:12:02 am »
Since Thanksgiving is now officially over, I guess it's time to prepare for our yearly Christmas Collection! 

Now, I was busy as heck during Halloween doing stuff around the farm here (and to be honest, things are STILL hectic around here with the Xmas tree side of things going on full swing), but I wanted to try and do a *little* better in my attempts at creating something this time around than what I managed to hobble together that time.  /blush!

So, here's the first look at something which I tossed together in about an hour this morning, making heavy use of already existing libraries and such that I already have...

Code: QB64: [Select]
  1. PRINT "Download and extract the attachment to the post where you copied this code from!"
  2. PRINT "You'll find the Xmas.bas file there, along with all its helper routines all in one easy 7z package."
  3.  

Now, at this point, this is only about an hour's work or so, so all it really is, is a quick little splash screen, a main menu, and a little routine so folks can enter their user name for the game.  (So it can track progress and store high scores later.)  It's got a little sound and a few images which help set the Xmas mood for the user, but it's not really doing too much of anything at this point in time...

BUT, I figured it might be something that other folks would be interested in taking a look at (or even using for their own stuff with some minor alterations), as it's basically now at the point where the actual game would be added and played with it...  Use your own fonts, images, and sounds...  Make your own pretty little screens...  Let the program run and give you an instant intro style interface to have a quick start to making your game!  :P

As for the game I'm thinking of inserting into this, I'm hoping to have time to add several little games to the project.  I've got multiple images I tossed into the package for use, so I was thinking I could toss those into the program and use them to create playing cards.  Then I have access to easy things like Poker, 21, War, Match Up...  I found me a nice little slot machine image which I can use to create a slot machine (Santa Slots!), for folks who might like that type of thing.

I'm feeling much more ambitious with this little project than I was with the one for Halloween, and things have came together nicely and fairly quick up to this point so far, which is a good sign.  I just hope LIFE stays calm enough around here so I can follow through and expand upon this as I go between now and Christmas.  ;D

v 0.4: https://1drv.ms/u/s!AknUrv8RXVYMm_QQ3W8KOf27i39tTA?e=jphyRd

17
QB64 Discussion / QB64 _Display/_ScreenMove Glitch
« on: November 25, 2021, 02:58:32 pm »
Now here's a little oddity which you guys might want to make note of, if you're ever going to write a program which removes the window's title:

Code: QB64: [Select]
  1. Screen _NewImage(1280, 720, 32)
  2.  
  3.  
  4.     Function GetWindowLongA& (ByVal hWnd As _Offset, Byval nIndex As Long)
  5.     Function SetWindowLongA& (ByVal hWnd As _Offset, Byval nIndex As Long, Byval dwNewLong As Long)
  6. a = SetWindowLongA&(_WindowHandle, -16, GetWindowLongA(_WindowHandle, -16) And Not &H00C80000)
  7.  
  8.     k = _KeyHit
  9.     If k = 32 Then TRY = Not TRY
  10.     If k = 27 Then System
  11.     If TRY Then
  12.         _Display
  13.     Else
  14.         _ScreenMove _Middle
  15.     End If
  16.  

Honestly, I don't have a clue what the heck is going on here!   To start with, we make a screen.... Then we remove the title and border...   So far, so good...

Then we enter the do loop with an initial value of 0 for TRY, so we attempt to _SCREENMOVE _MIDDLE endlessly...

And, at this point, the window then centers itself for a nanosecond or two, only to then pop down to my bottom right corner of my screen where it stays until the next call to _SCREENMOVE _MIDDLE.  Inside the loop, this produces a sickening flicker as the screen jumps back and forth endlessly.

BUT....

Then you hit the SPACE BAR and the value of TRY toggles.  We execute a simple _DISPLAY command...  And NOW our window stays in the center, regardless of if we ever hit the spacebar again, or not.

Without the _DISPLAY, the window loses itself and doesn't know where the heck to pop, going to the bottom corner rather than the center of the screen.

My initial impression is (and this might be completely wrong):

I have a feeling that QB64 (or GLUT) has internal variables which track our various pieces of screen information (x and y position, size, ect..), and this information doesn't update until a call to _DISPLAY is made.  By removing the title bar, we've changed some of the Windows-side value of these things, but not the QB64-side of stuff.  GLUT, or Windows, or whatever has one value for the middle of the screen (as seen by how it first positions itself in the correct position), but our internal variables have a different position (as seen by how it moves to the second position).

All this time, I've been telling folks that there's a race condition in handles going on when a screen is first created, so they need to place a small delay before making a screenmove call; when instead, it might be this issue with variables not updating until _DISPLAY is called.

Note that the following works perfectly and places the screen in the middle of our display as it should:
Code: QB64: [Select]
  1. Screen _NewImage(1280, 720, 32)
  2.  
  3.  
  4.     Function GetWindowLongA& (ByVal hWnd As _Offset, Byval nIndex As Long)
  5.     Function SetWindowLongA& (ByVal hWnd As _Offset, Byval nIndex As Long, Byval dwNewLong As Long)
  6. a = SetWindowLongA&(_WindowHandle, -16, GetWindowLongA(_WindowHandle, -16) And Not &H00C80000)
  7.  
  8.  

Whereas this doesnt:
Code: QB64: [Select]
  1. Screen _NewImage(1280, 720, 32)
  2.  
  3.     Function GetWindowLongA& (ByVal hWnd As _Offset, Byval nIndex As Long)
  4.     Function SetWindowLongA& (ByVal hWnd As _Offset, Byval nIndex As Long, Byval dwNewLong As Long)
  5. a = SetWindowLongA&(_WindowHandle, -16, GetWindowLongA(_WindowHandle, -16) And Not &H00C80000)
  6.  
  7.  

The  only difference in the two?  The use of _DISPLAY before _SCREENMOVE.  :P

18
QB64 Discussion / How about a Snippets forum?
« on: November 23, 2021, 12:31:36 pm »
If you look at the Forum descriptions, Programs reads as "This section is for (i) completed programs, or (ii) works in progress. If the code ages well, it will be archived and immortalized in the Samples Gallery by the Librarian."

But what about when one just wants to highlight a singular SUB or FUNCTION, rather than a whole program?  (Like the PutText topic I just posted in Discussion.  Somehow, it just doesn't seem *worthy* enough to qualify as a whole "program", since it's just a simple little SUB at work to copy/paste text from one image to another.) 

Wouldn't a little Snippets forum be better for those type things, and help declutter the Programs forum for actual "completed programs or works in progress"?

And while we're at it, how about a "Completed Library" forum, so folks who make libraries can post them there and they'd be easier to find and access.  It could help highlight those useful extensions like falcon.h and direntry.h, and the libraries that use them, that are copy and pasted as attachments in dozens of posts on the forums.  Folks would be able to easily find and point to things with "Get the helper files from the library HERE, if needed."

19
QB64 Discussion / PutText
« on: November 23, 2021, 12:21:00 pm »
For all you SCREEN 0 herpes out there like Pete, here's PutText -- it's like PutImage, but for TextScreens!

Code: QB64: [Select]
  1. FooBar = _NewImage(10, 5, 0)
  2. _Dest FooBar
  3. Color 4, 15: Locate 1, 1: Print "**********";
  4. Color 15, 4: Locate 2, 1: Print "*-Foobar-*";
  5. Color 4, 15: Locate 3, 1: Print "**********";
  6. Color 2, 0: Locate 4, 1: Print "**********";
  7. Locate 5, 1: Print "**********";
  8.  
  9. PutText "(10,1)", FooBar, 0, "(1,1) to (10,3)"
  10.  
  11.  
  12. 'let's try to put the text at an off image coordinate
  13. PutText "(0,0)", FooBar, 0, "(1,1) to  (10,5)"
  14.  
  15.  
  16. 'or off the right of the screen
  17. PutText "(75,20)", FooBar, 0, "(1,1) to step (9,2)"
  18.  
  19. _Delay .25
  20.  
  21. x = 80
  22.     Cls
  23.     PutText Str$(x) + ",3", FooBar, 0, "(1,1) to step (9,2)"
  24.     _Limit 30
  25.     _Display
  26.     x = x - 1
  27.     If x < -10 Then x = 80
  28.  
  29.  
  30. Sub PutText (dest$, source, dest, source$)
  31.     CurrentDest = _Dest: CurrentSource = _Source
  32.     Type PutType
  33.         x1 As Integer
  34.         y1 As Integer
  35.         x2 As Integer
  36.         y2 As Integer
  37.     End Type
  38.     Dim As PutType d, s
  39.  
  40.  
  41.     ParsePutParam dest$, d
  42.     ParsePutParam source$, s
  43.  
  44.     _Source source: _Dest dest
  45.     For x = s.x1 To s.x2 'Step Sgn(s.x2 - s.x1)
  46.         For y = s.y1 To s.y2 'Step Sgn(s.y2 - s.y1)
  47.             If x > 0 And x <= _Width(source) And y > 0 And y <= _Height(source) Then
  48.                 p = Screen(y, x, 0)
  49.                 c = Screen(y, x, 1)
  50.                 x1 = d.x1 + x - s.x1: y1 = d.y1 + y - s.y1
  51.                 If x1 > 0 And x1 <= _Width(dest) And y1 > 0 And y1 <= _Height(dest) Then
  52.                     Color c Mod 16, c \ 16
  53.                     _PrintString (x1, y1), Chr$(p)
  54.                 End If
  55.             End If
  56.         Next
  57.     Next
  58.     _Dest CurrentDest: _Source CurrentSource
  59.     Color DC, BG
  60.  
  61. Sub ParsePutParam (param$, o As PutType)
  62.     p$ = UCase$(_Trim$(param$))
  63.     strip$ = "() "
  64.     For j = 1 To Len(strip$)
  65.         Do
  66.             i = InStr(p$, Mid$(strip$, j, 1))
  67.             If i Then p$ = Left$(p$, i - 1) + Mid$(p$, i + 1)
  68.         Loop Until i = 0
  69.     Next
  70.     o.x1 = Val(p$)
  71.     comma = InStr(p$, ",")
  72.     If comma Then p$ = Mid$(p$, comma + 1) Else Exit Sub
  73.  
  74.     o.y1 = Val(p$)
  75.     p$ = Mid$(p$, Len(_Trim$(Str$(o.y1))) + 1)
  76.  
  77.     If Left$(p$, 2) = "TO" Then p$ = Mid$(p$, 3) Else Exit Sub
  78.  
  79.     If Left$(p$, 4) = "STEP" Then
  80.         o.x2 = o.x1: o.y2 = o.y1: p$ = Mid$(p$, 5)
  81.     Else
  82.         o.x2 = 0: o.y2 = 0
  83.     End If
  84.  
  85.     o.x2 = o.x2 + Val(p$)
  86.     comma = InStr(p$, ",")
  87.  
  88.     If comma Then p$ = Mid$(p$, comma + 1) Else Exit Sub
  89.     o.y2 = o.y2 + Val(p$)
  90.  

I was going to build this to  work more like PutImage, but then I realized that wouldn't be possible with a text screen.  For instance, there's no way to stretch or scale the "image" here, since all text screens are stuck with a single font in use at a time, so I figured all I really needed was a singular destination point (x,y) rather than (x,y) to (x2,y2).   

Get the portion of text you want, put it where you want it.  It's that simple.

Another little change is that I tweaked the syntax to use "TO" instead of a dash ("-") to separate points. You never know -- somebody, somewhere, might be using WINDOW to work with negative screen coordinates, so I didn't want to run into issues with that dash getting screwed up with the parsing of a negative location.   "(10,10) TO STEP (-10,0)", for an example.

Currently I'm only printing text in an incremental fashion (from position 0 to 10, for instance rather than from 10 to 0), but I do plan on adding in the optionality later for bidirectional putting of text so we can reverse and flip text as wanted with one little command.  (I'll just need to wake up enough to sort out how to do it first!  LOL!)
 

20
QB64 Discussion / Resizing Screen Demo
« on: November 09, 2021, 04:29:04 pm »
I had someone send me a message asking about how to use $RESIZE to set a screen to reflow text (not stretch or scale it), so I thought I'd write up a quick little demo and share with everyone.

Code: QB64: [Select]
  1. Dim Shared As Long DW, DH, DisplayScreen, WorkScreen, Font, FontSize
  2. Dim Shared As Long ScreenWidth, ScreenHeight
  3.  
  4.  
  5.  
  6. _Title "X-Mas Adventure"
  7. '$Dynamic
  8. DefLng A-Z
  9.  
  10.  
  11.  
  12. If DW > 1920 Then 'I'm going to assume it's a super highres screen
  13.     DisplayScreen = _NewImage(1280, 960, 32)
  14.     FontSize = 40
  15.     DisplayScreen = _NewImage(640, 480, 32)
  16.     FontSize = 20
  17.  
  18. Screen DisplayScreen
  19. Font = _LoadFont("courbd.ttf", FontSize, "monospace")
  20. _Font Font
  21.  
  22.  
  23.  
  24.  
  25.     Cls , 0
  26.     k = _KeyHit
  27.     If _Resize Then resize
  28.  
  29.     Select Case k
  30.         Case 27: System
  31.     End Select
  32.  
  33.  
  34.     Select Case Room
  35.         Case 0: TitleScreen
  36.         Case 1: Room1
  37.     End Select
  38.  
  39.  
  40.     _Limit 30
  41.     _Display
  42.  
  43.  
  44.  
  45. Sub Room1
  46.     Print "This is just a demo of a resizable screen and how we'd adjust our text to give us more words per row with a wide screen and fewer words with a narrower screen.  This will also change font size automatically to a much larger font, if your screen resolution is greater than 1920 pizels wide, and still look proper for you.  This is just a demo and really does nothing beyond this point..."
  47.     Print
  48.     Print "Note, there is *NO* word-wrap built into this demo."
  49.  
  50.  
  51. Sub TitleScreen
  52.     Static Delay#
  53.     If Delay# = 0 Then Delay# = ExtendedTimer + 10.0 '10 seconds to view and resize my pretty little title screen
  54.     If Delay# < ExtendedTimer Then
  55.         Room = 1
  56.     End If
  57.     Text1$ = "Resizing Screen Demo"
  58.     Text2$ = "By. SMcNeill"
  59.     Text3$ = "2021"
  60.     Top = (_Height - _FontHeight * 3) / 2
  61.     CenterText Text1$, Top
  62.     CenterText Text2$, Top + _FontHeight
  63.     CenterText Text3$, Top + _FontHeight * 2
  64.  
  65. Sub CenterText (text$, Ypos)
  66.     CenterX = (_Width - _PrintWidth(text$)) / 2
  67.     _PrintString (CenterX, Ypos), text$
  68.  
  69.  
  70. Sub resize
  71.     RX = _ResizeWidth: RY = _ResizeHeight
  72.     _Font 16
  73.     tempscreen = _NewImage(RX, RY, 32)
  74.     Screen tempscreen
  75.     _FreeImage DisplayScreen
  76.     DisplayScreen = tempscreen
  77.     _Font Font
  78.     ScreenWidth = _Width / _FontWidth
  79.     ScreenHeight = _Height / _FontHeight
  80.  
  81. Function ExtendedTimer##
  82.     d$ = Date$
  83.     l = InStr(d$, "-")
  84.     l1 = InStr(l + 1, d$, "-")
  85.     m = Val(Left$(d$, l))
  86.     d = Val(Mid$(d$, l + 1))
  87.     y = Val(Mid$(d$, l1 + 1)) - 1970
  88.     For i = 1 To m
  89.         Select Case i 'Add the number of days for each previous month passed
  90.             Case 1: d = d 'January doestn't have any carry over days.
  91.             Case 2, 4, 6, 8, 9, 11: d = d + 31
  92.             Case 3: d = d + 28
  93.             Case 5, 7, 10, 12: d = d + 30
  94.         End Select
  95.     Next
  96.     For i = 1 To y
  97.         d = d + 365
  98.     Next
  99.     For i = 2 To y Step 4
  100.         If m > 2 Then d = d + 1 'add an extra day for leap year every 4 years, starting in 1970
  101.     Next
  102.     d = d - 1 'for year 2000
  103.     s~&& = d * 24 * 60 * 60 'Seconds are days * 24 hours * 60 minutes * 60 seconds
  104.     ExtendedTimer## = (s~&& + Timer)
  105.  

Now this makes a simple little program for us with a resizable screen.  The first screen is nothing but some text that centers itself for us as a simple title screen.  It's configured to remain visible for 10 seconds while you play with the size of the screen and watch the text move to reposition itself always into the center of your screen, regardless of the dimensions you set.  (Unless you scrunch the screen too small, of course.  I'm keeping the demo simple here, so there's no limit to how large/small you can make your screen, and if it's too small, the text won't have room to display properly, so be aware of that.  :P )

Note the resize SUB in particular -- it's the one which is in charge of the screen dimensions:

Code: QB64: [Select]
  1. Sub resize
  2.     RX = _ResizeWidth: RY = _ResizeHeight
  3.     _Font 16
  4.     tempscreen = _NewImage(RX, RY, 32)
  5.     Screen tempscreen
  6.     _FreeImage DisplayScreen
  7.     DisplayScreen = tempscreen
  8.     _Font Font
  9.     ScreenWidth = _Width / _FontWidth
  10.     ScreenHeight = _Height / _FontHeight

    RX = _ResizeWidth: RY = _ResizeHeight -- read the resized dimensions
    _Font 16  -- get ready to free the screen by making certain to swap to a default font for the display
    tempscreen = _NewImage(RX, RY, 32) -- make the new screen
    Screen tempscreen -- swap to the new screen
    _FreeImage DisplayScreen -- free the old screen
    DisplayScreen = tempscreen -- make the new screen the old screen
    _Font Font -- set the proper font back for the new screen

And that's basically the whole process in a nutshell!

If anyone has questions about this little resizing technique, feel free to ask, and I'll answer all I can for you guys until the process makes sense to everybody.  It's really not as difficult as some people make it out to be.  ;)

21
QB64 Discussion / Autoformat off
« on: November 08, 2021, 09:03:22 am »
  [ You are not allowed to view this attachment ]  

I know that if we end a line with an underscore, it messes the autoformat up, but here it's tossing extra spaces into the mix to move SUB to be in line with the normal code, which is rather odd.  Normally it just completely skips formatting on both the continued lines, but here the autospace is kicking the SUB one indent right, even though we never tend to indent SUB...

Oddest thing is this happens in the first instance of QB64 which I've got up and running, but not in the second, and I really don't think there's anything in the source which changes formatting based on which temp or temp2 or temp12 file we're using...

Anyone else get something odd like this to happen for them, or am I just shortbus special again?  :P

22
Programs / TextToImage and DisplayImage (v2.0+ compliant)
« on: November 07, 2021, 06:14:45 am »
Two of my most used routines, updated to work properly with version 2.0 and above:

Code: QB64: [Select]
  1. 'SMcNeill  ref https://www.qb64.org/forum/index.php?topic=4374.msg137907#msg137907
  2. Screen _NewImage(800, 700, 32)
  3. For i = 1 To 4
  4.     HW(i) = TextToImage("Hello World", 16, &HFFFFFF00, 0, i)
  5.  
  6.  
  7. Print "The first thing to showcase with these two routines is just how simple it is to turn"
  8. Print "text into an image with TextToImage."
  9. Print "First, let's print it forwards:"
  10. _PutImage (250, 48), HW(1)
  11. Print "Then, let's print it backwards:"
  12. _PutImage (250, 80), HW(2)
  13. Print "Then, let's print it up to down:"
  14. _PutImage (270, 112), HW(3)
  15. Locate 8, 40: Print "And let's finish with down to up:"
  16. _PutImage (580, 112), HW(4)
  17. Locate 20, 1
  18. Print "TextToImage simply transforms text into an image for us, with a few built in options"
  19. Print "to it for the direction we want we text to print."
  20. Print "It's as simple as a call with:"
  21. Print "    Handle = TextToImage(text$, fonthandle, fontcolor, backgroundcolor, mode"
  22. Print "        text$ is the string which we want to print.  (In this case 'Hello World'"
  23. Print "        fonthandle is the handle of the font which we _LOADFONT for use."
  24. Print "            (In this case, I choose the default _FONT 16.)"
  25. Print "        fontcolor is the color which we want our text in.  (Here, it's YELLOW.)"
  26. Print "        backgroundcolor is the background which we want for the text time.  (Clear this time.)"
  27. Print "        mode is how we decide to print forwards, backwards, up to down, or down to up."
  28. Print "Once we have an image handle, we can use that image just the same as we can with any other."
  29. Print "For those who don't need to do anything more than display the text as an image,"
  30. Print "feel free to use it as I have in the first part of this program with _PUTIMAGE."
  31. Print "Trust me -- TextToImage works just fine with _PUTIMAGE."
  32. Print "But....   If you need more..."
  33.  
  34. Cls , 0
  35.  
  36. Print "There's always DisplayImage to help you out!"
  37. DisplayImage HW(1), 300, 30, 1, 1, 0, 1
  38. Print "Display your image at a scale!"
  39. Print "Twice as wide! ";
  40. DisplayImage HW(1), 300, 60, 2, 1, 0, 1
  41. Print "Twice as tall! "
  42. DisplayImage HW(1), 500, 60, 1, 2, 0, 1
  43. Print "At an angle!"
  44. DisplayImage HW(1), 280, 90, 1, 1, -45, 1
  45. Print "Make it rotate!"
  46.     Line (355, 155)-Step(100, 100), &HFF000000, BF
  47.     DisplayImage HW(1), 400, 200, 1, 1, angle, 0
  48.  
  49.     angle = (angle + 1) Mod 360
  50.     _Limit 30
  51.     _Display
  52. Print "You can basically use DisplayImage just as you'd normally use RotoZoom, EXCEPT..."
  53. Print "You can choose which CORNER of the image you want to display at your coordinates."
  54. Line (350, 350)-Step(100, 100), -1, B
  55. Circle (400, 400), 10, -1
  56. Print "Top Left corner! ";
  57. DisplayImage HW(1), 400, 400, 2, 2, 0, 1
  58. Print "Bottom Left corner! ";
  59. DisplayImage HW(1), 400, 400, 2, 2, 0, 2
  60. Print "Top Right corner! ";
  61. DisplayImage HW(1), 400, 400, 2, 2, 0, 3
  62. Print "Bottom Right corner! "
  63. DisplayImage HW(1), 400, 400, 2, 2, 0, 4
  64. HW(1) = TextToImage("Hello World", 16, &HFFFF0000, &HFF0000FF, 1)
  65. Print "Or Centered!"
  66. DisplayImage HW(1), 400, 400, 2, 2, 0, 0
  67. Circle (400, 400), 10, -1
  68.  
  69.  
  70. Print "With TextToImage, you can turn text into an image...  It's that simple!"
  71. Print "With DisplayImage, you have a ton of options for how to display ANY image"
  72. Print "   (NOT just for use with text images!!)"
  73. Print "Scale them, stretch them, rotate them, position them by various corners..."
  74. Print "Between these two routines, I generally don't need anything else when working"
  75. Print "   with images in my programs.  ;)"
  76. Print "And that's THE END of this demo.  Post any questions you have on the forums for me!"
  77.  
  78.  
  79.  
  80.  
  81.  
  82. ' (Image As Long, x As Integer, y As Integer, xscale As Single, yscale As Single,
  83. '  angle As Single, mode As _Byte)
  84.  
  85.  
  86.  
  87.  
  88. Function TextToImage& (text$, font&, fc&, bfc&, mode As _Byte)
  89.     'text$ is the text that we wish to transform into an image.
  90.     'font& is the handle of the font we want to use.
  91.     'fc& is the color of the font we want to use.
  92.     'bfc& is the background color of the font.
  93.  
  94.     'Mode 1 is print forwards
  95.     'Mode 2 is print backwards
  96.     'Mode 3 is print from top to bottom
  97.     'Mode 4 is print from bottom up
  98.     'Mode 0 got lost somewhere, but it's OK.  We check to see if our mode is < 1 or > 4 and compensate automatically if it is to make it one (default).
  99.  
  100.     If mode < 1 Or mode > 4 Then mode = 1
  101.     dc& = _DefaultColor: bgc& = _BackgroundColor
  102.     D = _Dest
  103.     F = _Font
  104.     T2Idown = CsrLin: T2Iright = Pos(0)
  105.     If font& <> 0 Then _Font font&
  106.     If mode < 3 Then
  107.         'print the text lengthwise
  108.         w& = _PrintWidth(text$): h& = _FontHeight
  109.     Else
  110.         'print the text vertically
  111.         For i = 1 To Len(text$)
  112.             If w& < _PrintWidth(Mid$(text$, i, 1)) Then w& = _PrintWidth(Mid$(text$, i, 1))
  113.         Next
  114.         h& = _FontHeight * (Len(text$))
  115.     End If
  116.  
  117.     TextToImage_temp& = _NewImage(w&, h&, 32)
  118.     TextToImage = TextToImage_temp&
  119.     _Dest TextToImage_temp&
  120.     If font& <> 0 Then _Font font&
  121.     Color fc&, bfc&
  122.  
  123.     Select Case mode
  124.         Case 1
  125.             'Print text forward
  126.             _PrintString (0, 0), text$
  127.         Case 2
  128.             'Print text backwards
  129.             temp$ = ""
  130.             For i = 0 To Len(text$) - 1
  131.                 temp$ = temp$ + Mid$(text$, Len(text$) - i, 1)
  132.             Next
  133.             _PrintString (0, 0), temp$
  134.         Case 3
  135.             'Print text upwards
  136.             'first lets reverse the text, so it's easy to place
  137.             temp$ = ""
  138.             For i = 0 To Len(text$) - 1
  139.                 temp$ = temp$ + Mid$(text$, Len(text$) - i, 1)
  140.             Next
  141.             'then put it where it belongs
  142.             For i = 1 To Len(text$)
  143.                 fx = (w& - _PrintWidth(Mid$(temp$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  144.                 _PrintString (fx, _FontHeight * (i - 1)), Mid$(temp$, i, 1)
  145.             Next
  146.         Case 4
  147.             'Print text downwards
  148.             For i = 1 To Len(text$)
  149.                 fx = (w& - _PrintWidth(Mid$(text$, i, 1))) / 2 + .99 'This is to center any non-monospaced letters so they look better
  150.                 _PrintString (fx, _FontHeight * (i - 1)), Mid$(text$, i, 1)
  151.             Next
  152.     End Select
  153.     _Dest D
  154.     Color dc&, bgc&
  155.     _Font F
  156.     Locate T2Idown, T2Iright
  157.  
  158. Sub DisplayImage (Image As Long, x As Integer, y As Integer, xscale As Single, yscale As Single, angle As Single, mode As _Byte)
  159.     'Image is the image handle which we use to reference our image.
  160.     'x,y is the X/Y coordinates where we want the image to be at on the screen.
  161.     'angle is the angle which we wish to rotate the image.
  162.     'mode determines HOW we place the image at point X,Y.
  163.     'Mode 0 we center the image at point X,Y
  164.     'Mode 1 we place the Top Left corner of oour image at point X,Y
  165.     'Mode 2 is Bottom Left
  166.     'Mode 3 is Top Right
  167.     'Mode 4 is Bottom Right
  168.  
  169.  
  170.     Dim px(3) As Integer, py(3) As Integer, w As Integer, h As Integer
  171.     Dim sinr As Single, cosr As Single, i As _Byte
  172.     w = _Width(Image): h = _Height(Image)
  173.     Select Case mode
  174.         Case 0 'center
  175.             px(0) = -w \ 2: py(0) = -h \ 2: px(3) = w \ 2: py(3) = -h \ 2
  176.             px(1) = -w \ 2: py(1) = h \ 2: px(2) = w \ 2: py(2) = h \ 2
  177.         Case 1 'top left
  178.             px(0) = 0: py(0) = 0: px(3) = w: py(3) = 0
  179.             px(1) = 0: py(1) = h: px(2) = w: py(2) = h
  180.         Case 2 'bottom left
  181.             px(0) = 0: py(0) = -h: px(3) = w: py(3) = -h
  182.             px(1) = 0: py(1) = 0: px(2) = w: py(2) = 0
  183.         Case 3 'top right
  184.             px(0) = -w: py(0) = 0: px(3) = 0: py(3) = 0
  185.             px(1) = -w: py(1) = h: px(2) = 0: py(2) = h
  186.         Case 4 'bottom right
  187.             px(0) = -w: py(0) = -h: px(3) = 0: py(3) = -h
  188.             px(1) = -w: py(1) = 0: px(2) = 0: py(2) = 0
  189.     End Select
  190.     sinr = Sin(angle / 57.2957795131): cosr = Cos(angle / 57.2957795131)
  191.     For i = 0 To 3
  192.         x2 = xscale * (px(i) * cosr + sinr * py(i)) + x: y2 = yscale * (py(i) * cosr - px(i) * sinr) + y
  193.         px(i) = x2: py(i) = y2
  194.     Next
  195.     _MapTriangle (0, 0)-(0, h - 1)-(w - 1, h - 1), Image To(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
  196.     _MapTriangle (0, 0)-(w - 1, 0)-(w - 1, h - 1), Image To(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
  197.  
  198.  

The fix to recursion in SUBs and FUNCTIONs keeps sneaking into my code from time to time, and I keep having to make little adjustments to things, but I'm surprised it took so long for me to notice the glitches in these two routines as I use them constantly!

Anywho...  Here they are, all spruced up and fixed for use with the newest versions of QB64.  If you're one of the people who have made use of these routines in the past, you might want to check your code and swap out to the updated versions here, in case you ever need to compile you EXE again in the future.  ;)

23
QB64 Discussion / Somebody explain this one to me...
« on: November 05, 2021, 09:10:54 am »
Code: QB64: [Select]
  1. Screen _NewImage(1024, 720, 32)
  2.  
  3.  
  4. TestLimit = 100
  5. Radius = 350
  6.  
  7. t# = Timer
  8. For i = 1 To TestLimit
  9.     'Cls , &HFF000000 + Int(Rnd * &HFFFFFF)
  10.     k& = &HFF000000 + Int(Rnd * &HFFFFFF)
  11.  
  12.     Circle (512, 360), Radius, k&
  13.     Fill 512, 360, k&, 0
  14.  
  15. t1# = Timer
  16. For i = 1 To TestLimit
  17.     'Cls , &HFF000000 + Int(Rnd * &HFFFFFF)
  18.     k& = &HFF000000 + Int(Rnd * &HFFFFFF)
  19.  
  20.     Circle (512, 360), Radius, k&
  21.     Fill 512, 360, k&, -1
  22. t2# = Timer
  23.  
  24. Print Using "###.#### seconds for Fill."; t1# - t#
  25. Print Using "###.#### seconds for Fill Method -1."; t2# - t1#
  26.  
  27.  
  28.  
  29.  
  30.  
  31. Sub Fill (Passx, Passy, kolor As Long, METHOD)
  32.     B = _Blend
  33.  
  34.     Dim TempGrid(0 To _Width - 1, 0 To _Height - 1) As Long
  35.     Dim As _MEM m, m1: m = _Mem(TempGrid()): m1 = _MemImage(0)
  36.     Dim o As _Offset
  37.     If METHOD Then
  38.         _MemCopy m1, m1.OFFSET, m1.SIZE To m, m.OFFSET
  39.     End If
  40.     o = 0
  41.     Do Until o >= m.SIZE
  42.         If _MemGet(m1, m1.OFFSET + o, _Unsigned Long) = kolor Then
  43.             _MemPut m, m.OFFSET + o, -1 As LONG
  44.             'Else
  45.             '_MemPut m, m.OFFSET + o, 0 As LONG
  46.         End If
  47.         o = o + 4
  48.     Loop
  49.  
  50.     TempGrid(Passx, Passy) = 1
  51.     startx = Passx: finishx = Passx
  52.     starty = Passy: finishy = Passy
  53.  
  54.     Do Until finished
  55.         pass = pass + 1
  56.         finished = -1
  57.         For x = startx To finishx
  58.             For y = starty To finishy
  59.                 'If TempGrid(x, y) <> 0 Then Print x, y, TempGrid(x, y): Sleep
  60.  
  61.                 If TempGrid(x, y) = pass Then
  62.                     tempx = x
  63.                     Do Until tempx = 0
  64.                         If TempGrid(tempx - 1, y) = 0 Then
  65.                             TempGrid(tempx - 1, y) = pass + 1
  66.                             tempx = tempx - 1
  67.                             If tempx < startx Then startx = tempx
  68.                             finished = 0
  69.                         Else
  70.                             tempx = 0
  71.                         End If
  72.                     Loop
  73.  
  74.                     tempx = x
  75.                     Do Until tempx = _Width - 1
  76.                         If TempGrid(tempx + 1, y) = 0 Then
  77.                             TempGrid(tempx + 1, y) = pass + 1
  78.                             tempx = tempx + 1
  79.                             If tempx > finishx Then finishx = tempx
  80.                             finished = 0
  81.                         Else
  82.                             tempx = _Width - 1
  83.                         End If
  84.                     Loop
  85.  
  86.                     tempy = y
  87.                     Do Until tempy = 0
  88.                         If TempGrid(x, tempy - 1) = 0 Then
  89.                             TempGrid(x, tempy - 1) = pass + 1
  90.                             tempy = tempy - 1
  91.                             If tempy < starty Then startx = tempy
  92.                             finished = 0
  93.                         Else
  94.                             tempy = 0
  95.                         End If
  96.                     Loop
  97.  
  98.                     tempy = y
  99.                     Do Until tempy = _Height - 1
  100.                         If TempGrid(x, tempy + 1) = 0 Then
  101.                             TempGrid(x, tempy + 1) = pass + 1
  102.                             tempy = tempy + 1
  103.                             If tempy > finishy Then finishy = tempy
  104.                             finished = 0
  105.                         Else
  106.                             tempy = _Height - 1
  107.                         End If
  108.                     Loop
  109.                 End If
  110.         Next y, x
  111.     Loop
  112.  
  113.     o = 0
  114.     Do Until o >= m.SIZE
  115.         If _MemGet(m, m.OFFSET + o, _Unsigned Long) <> 0 Then _MemPut m1, m1.OFFSET + o, kolor As _UNSIGNED LONG
  116.         o = o + 4
  117.     Loop
  118.     _MemFree m: _MemFree m1
  119.     If B Then _Blend

  [ You are not allowed to view this attachment ]  

Now, if you guys look, there's only one difference in the code:

    If METHOD Then
        _MemCopy m1, m1.OFFSET, m1.SIZE To m, m.OFFSET
    End If

The main process here works like this:

First, we make an array the size of the screen.
Then where the color exists that we want to use as a paint boundary, we assign a value of -1 to the grid in that position.
Then we do a little pathfinding style routine counting passes to fill in from the point we choose to the end of those boundaries...

Both routines work flawlessly.  Neither has any issues doing what they're supposed to do. 

In one (where we pass a method value of 0), the array has starts out empty with values of in it, and we assign a value of -1 to any point where the chosen color is... 

In the other (where we pass a method value of anything but 0), we copy the whole array of screen colors over, and assign a value of -1 to any point where the chosen color is..  (Note, this can only work as long as our screen doesn't have any bright white characters printed on it, as it doesn't have in these instances here.)

Now, logically speaking, it would seem that one method would, indeed, be faster than the other.  Wouldn't it be faster to go with a blank array, rather than first having to copy and alter every pixel from the screen onto the array?  You'd think so...

...and, as the screenshot above illustrates, YOU'D BE WRONG!!

It's faster to copy the whole screen into our array -- a LOT faster -- than it is to NOT copy the screen.  WTH?!!  WHY??

Why is it faster to do MORE work than it is to SKIP that work???

I find the differences in the speed runs here to be mind boggling, and I can't sort out why the heck it's faster to do more work than it is to NOT do it.

Anyone want to take a shot at explaining why this has such different speed results with it?  I'm completely baffled here.

24
QB64 Discussion / Match Three
« on: October 20, 2021, 01:26:27 pm »
So I've finally rounded up a little free time and have decided to play around with the little "one key input" Halloween contest that's currently going on.  What I've decided to shoot for is a simple little strategy game of a match-3 style.

Code: QB64: [Select]
  1. Dim Shared WS, GridSize
  2. ReDim Shared Grid(0, 0) As _Byte
  3.  
  4. GridSize = 30
  5. MakeGrid
  6. DisplayGrid
  7.  
  8.  
  9.  
  10. Sub DisplayGrid
  11.     For x = 1 To GridSize: For y = 1 To GridSize
  12.         Locate y, x: Print _Trim$(Str$(Grid(x, y)));
  13.     Next y, x
  14.     AutoScale
  15.  
  16. Sub MakeGrid
  17.     If GridSize Mod 3 <> 0 Then Error 5: End
  18.     If WS <> 0 Then _FreeImage WS
  19.  
  20.     WS = _NewImage(GridSize * 8, GridSize * 8 + 16, 32)
  21.     Screen WS
  22.     _Font 8 'this creates a 30x32 screen
  23.     ReDim Grid(1 To GridSize, 1 To GridSize) As _Byte
  24.  
  25.     count = 3
  26.     For x = 1 To GridSize: For y = 1 To GridSize
  27.         count = (count + 1) Mod 3 + 1
  28.         Grid(x, y) = count 'Assign values of 1 to 3 equally amongst the grid
  29.     Next y, x
  30.     For x = 1 To GridSize: For y = 1 To GridSize
  31.         xswap = Int(Rnd * GridSize) + 1: yswap = Int(Rnd * GridSize) + 1
  32.         Swap Grid(xswap, yswap), Grid(x, y) 'Shuffle the grid
  33.     Next y, x
  34.  
  35. Sub AutoScale
  36.     Static DisplayScreen
  37.     If DisplayScreen = 0 Then
  38.         DW = _DesktopWidth
  39.         DH = _DesktopHeight
  40.         Scale = (DH - 80) / 640
  41.         DisplayScreen = _NewImage(640 * Scale, 640 * Scale, 32)
  42.         Screen DisplayScreen
  43.         _ScreenMove (DW - _Width(DisplayScreen)) \ 2, 0
  44.         _Source WS: _Dest WS
  45.     End If
  46.     _PutImage , WS, DisplayScreen
  47.     _Display

Now, all this is doing at the moment is tossing a bunch of numbers up on the screen for us, with values of 1, 2, or 3.  The goal here would be to clear the screen of all numbers, making matches from the bottom up as you go.  Simple enough game play, but one which many people end up failing to do properly. All you need to do to fail is to get stuck with something like 1, 3, 2, 2, 1, 3 for the bottom numbers of the last six columns, and you've lost.  It's impossible to make another match-3 with those 6 numbers!  There's a few hiding behind those that you need to access, so you didn't clear the rest of the puzzle properly to get a win!  :(

Of course, at this point, there's no actual game here -- just a way to toss the numbers up on the screen.  You can't match them or eliminate them in and way, shape, or form so far.  :P

All I'm curious about at this point is how the AutoScale works out for everyone.  This should make a rather small screen, then scale over to fit any desktop out there -- and it shouldn't cover your Window's Taskbar, leaving a little room open at the bottom of the screen.  Can folks test this little snippet out for me and let me know how things work with the scaling department for you guys? I don't know of a simple way to get Taskbar height that's cross compatible for all OSes, so I'm just eyeballing it with my display and hoping it doesn't cover anything. 

The goal, if scaling works properly, is to substitute numbers for images of candy, and then it'll become a match-3 candy puzzle!  (Expandable to Match-4, 5, 6, ect, if I want to add harder levels as a player progresses.)  I just need to find a good candy spritesheet somewhere, which shouldn't be too hard to come up with with all the Candy Crush type games out there, and then I can turn this little concept into a Halloween-themed game!  (And come Christmas, I can swap candies for reindeer, snowmen, presents, and snowflakes!)

25
Programs / DisplayedScaled
« on: October 16, 2021, 07:36:18 pm »
A little SUB which folks might want to make use of, if they have super high resolution monitors such as the one on my laptop.  At 3840x2048, most QB64 screens end up soooo dang tiny that I can't read or interact with them at all!

My solution for now?  A simple little DisplayScale routine.

Code: QB64: [Select]
  1. Screen _NewImage(1024, 720, 32)
  2. Const ScreenScale = 2.5
  3.  
  4.  
  5. Print "Foo"
  6. Print "Testing"
  7.  
  8. Sleep 'So we can see our screen before we scale it
  9.  
  10. DisplayScaled
  11.  
  12. Sleep 'so we can watch it scale
  13.  
  14.  
  15. Print "Cheetos?"
  16. Print "Testing...1...2..3" 'and, as you can tell here, we keep using the screen the same as always.
  17.  
  18. DisplayScaled 'All we do is call DisplayedScaled to display the screen at scale, rather than call _DISPLAY
  19.  
  20.  
  21. Sub DisplayScaled
  22.     Static DisplayDoubleScreen As Long
  23.     D = _Dest: S = _Source
  24.     If DisplayDoubleScreen = 0 Then
  25.         DisplayDoubleScreen = _NewImage(_Width * ScreenScale, _Height * ScreenScale, 32)
  26.         Screen DisplayDoubleScreen
  27.     End If
  28.     _PutImage , S, DisplayDoubleScreen
  29.     _Display
  30.     _Dest D: _Source S

Others might find this useful for something else, but it's probably going to become something that I tend to toss into a lot of my programs when I write them on my laptop in the future. 

Just swap out calls to _DISPLAY with DisplayScaled, and it does all the work for us.  ;)

26
QB64 Discussion / These forums are trying to self-destruct
« on: October 09, 2021, 12:08:50 am »
  [ You are not allowed to view this attachment ]  

  [ You are not allowed to view this attachment ]  

Am I the only person who has been seeing these type of glitches and error messages with the forums lately?  I’m getting them both on my iPad with Safari as the browser, and on Win 11, with Chrome.

Is this just on my end, or is it something others are seeing as well?

27
Programs / One Key Input
« on: October 04, 2021, 12:55:45 pm »
For the Halloween Challenge that @bplus and @johnno56 have been talking about recently, one of the rules is to set up a program so that it only works with a single key being used.  For many folks, this could be a rather difficult thing to add into a game (How the heck do we get alphabetic responses with just the space bar??), so I thought I'd whip up a really simple little demo for one way to do this:

Code: QB64: [Select]
  1. Selection$ = "<Will be accepted after two seconds inactivity>": terminate = Timer: t = Timer
  2.  
  3.     Cls
  4.     k = _KeyDown(32)
  5.     DisplayKeys Selection
  6.     If t = 0 Then
  7.         If k Then t = Timer: Selection = (Selection + 1) Mod 26
  8.     Else
  9.         If Timer > t + 2 Then
  10.             Selection$ = Chr$(65 + Selection)
  11.             t = 0
  12.         Else
  13.             If k Then t = Timer: Selection = (Selection + 1) Mod 26
  14.             Selection$ = "<Will be accepted after two seconds inactivity>"
  15.         End If
  16.     End If
  17.     If t <> 0 Then terminate = Timer
  18.     Locate 5, 1: Print "SELECTED: "; Selection$; Chr$(13); "TERMINATION IN: "; _Ceil(terminate - Timer) + 5
  19.     _Display
  20.     _Limit 5
  21. Loop Until Timer > terminate + 5 '5 seconds of zero activity after a selection will terminate the program completely.
  22.  
  23. Sub DisplayKeys (Selection)
  24.     Color Red
  25.     Locate Selection \ 13 + 1, (Selection Mod 13) * 3 + 2: Print "[ ]"
  26.     Color BrightWhite
  27.     For j = 0 To 1
  28.         For i = 0 To 12
  29.             Locate j + 1, (i + 1) * 3: Print Chr$(65 + 13 * j + i)
  30.     Next i, j

My whole little demo here comes in at around 30 lines of code or so, so something like this should be easy enough to implement in just about any sort of program someone would need it in.  The only real change might be a need to alter the termination part of the program (in this case it's just 5 seconds of total inactivity) to whatever suits your program needs instead.  (For example, hangman might terminate after the player either wins or dies...)

Usage...  Just press the SPACEBAR.  If you can't figure it out after that, I've did something wrong!   It's just a simple 1-key input routine!  :P

28
QB64 Discussion / What happened to the forum? Update: Nothing.
« on: September 20, 2021, 12:03:03 pm »
We no longer have an user profile with an avatar at the top left of the screen, nor is there any sort of quick link for "Recent Unread Topics".  Is this another change to improve the user experience here, or is something broken?  Is this just something affecting me and Win 11 with Chrome, or is it a glitch for everyone?

29
QB64 Discussion / How is DATA stored in memory?
« on: September 18, 2021, 05:51:39 pm »
So here’s something I was wondering about today: How is our DATA statements stored in memory?

Let’s say I have the following: DATA 123, 456, 789, Foo, EOD

Is that stored and read as a single string?  “123, 456, 789, Foo, EOD”

Individual strings?  “123”, “456”, “789”, “Foo”, “EOD”

As a series of integers and strings?

Just how the heck is that data actually stored in memory, and is there ever anyway to free it from a program’s memory if it’s never needed anymore to reduce memory usage?

If I assign values to an array manually like so:
x(1) = “123”
x(2) = “456”
x(3) = “789”
x(4) = “foo”

Then I can always free that memory with a REDIM x(0) AS STRING, an ERASE, or a CLEAR statement.

But is there anyway to remove DATA from memory?  Or is it just stuck there always using resources even when it doesn’t need to?

30
Programs / Code Breaker
« on: September 15, 2021, 03:37:47 pm »
A little game I was playing around with making to just give my little grand-niece something to waste time on when she comes to visit.

Code: QB64: [Select]
  1. Dim Shared f, f1, lastsolved, guess(10), guesses
  2. Screen _NewImage(640, 480, 32)
  3. f = _LoadFont("courbd.ttf", 64, "monospace")
  4. f1 = _LoadFont("courbd.ttf", 32, "monospace")
  5. Color Black, none
  6.  
  7. n$ = GetNum(5)
  8.  
  9.     Cls
  10.     guess$ = "": wheel = 0: Xon = 0
  11.     For i = 1 To Len(n$)
  12.         guess$ = guess$ + _Trim$(Str$(guess(i)))
  13.     Next
  14.     DrawLock guess$, n$
  15.  
  16.     While _MouseInput: wheel = wheel + _MouseWheel: Wend
  17.     X = _MouseX: y = _MouseY: mb = _MouseButton(1): mb2 = _MouseButton(2)
  18.  
  19.     If y > 105 And y < 195 Then 'we're on the proper spot to be in the combination area
  20.         Xon = Int((X - 105) / (300 / Len(n$)) + 1) 'this is the tumbler we're on
  21.         If Xon > 0 And Xon <= Len(n$) Then
  22.             If wheel Then
  23.                 guess(Xon) = guess(Xon) + wheel
  24.             End If
  25.             If mb And Not oldmouse Then guess(Xon) = guess(Xon) + 1
  26.             If mb2 And Not oldmouse2 Then guess(Xon) = guess(Xon) - 1
  27.             If guess(Xon) > 9 Then guess(Xon) = 0
  28.             If guess(Xon) < 0 Then guess(Xon) = 9
  29.         End If
  30.     End If
  31.     If mb And Not oldmouse Then
  32.         If y > 205 And y < 295 Then 'in the solved row
  33.             If X > 105 And X < 395 Then 'in the Last row
  34.                 lastsolved = 0: guesses = guesses + 1
  35.                 For i = 1 To Len(n$)
  36.                     If Asc(guess$, i) = Asc(n$, i) Then lastsolved = lastsolved + 1
  37.                 Next
  38.             End If
  39.         End If
  40.     End If
  41.     oldmouse = mb: oldmouse2 = mb2
  42.     _Display
  43.     _Limit 15
  44. Loop Until lastsolved = Len(n$)
  45. Color White
  46. Print "YAY!  You got it in"; lastsolved; "tries!"
  47.  
  48. Function GetNum$ (size)
  49.     For i = 1 To size
  50.         n = Int(Rnd * 11)
  51.         GetNum$ = GetNum$ + _Trim$(Str$(n))
  52.     Next
  53.  
  54. Sub DrawLock (guess$, num$)
  55.     _Font f
  56.     Color Black, none
  57.     size = Len(num$)
  58.     s = 300 / size
  59.     Line (100, 100)-(400, 200), SlateGray, BF
  60.     Line (100, 100)-(400, 300), SlateGray, BF
  61.     Line (105, 105)-(395, 195), LightGray, BF
  62.     Line (105, 205)-(395, 295), Green, BF
  63.     For i = i To (size - 1)
  64.         Line (100 + i * s, 100)-Step(5, 100), SlateGray, BF
  65.         t$ = Mid$(guess$, i, 1)
  66.         left = 105 + (s - _FontWidth) / 2
  67.         _PrintString (left + (i - 1) * s, 150 - _FontHeight / 2), t$
  68.     Next
  69.     t$ = Mid$(guess$, i, 1)
  70.     _PrintString (left + (i - 1) * s, 150 - _FontHeight / 2), t$
  71.     _Font f1
  72.     _PrintString (110, 210), "Last:" + _Trim$(Str$(lastsolved))
  73.     _PrintString (110, 250), "Guesses:" + _Trim$(Str$(guesses))

This should be easy enough to figure out: 
Use the mouse wheel or the buttons to increase or decrease the values of a tumbler. 
Click in the green area to make a guess and see how many numbers you got correct out of your attempt.

Match the actual combination and win!



At this point, this only runs through the creation and puzzle process a single time, for a single 5-digit combination lock.  I suppose all it really needs at this point to become a "replayable game" is to offer an option to select difficulty (it can generate anywhere up to 9-digit locks for increased difficulty), and then an option to replay/quit again afterwards -- but that's a simple enough mod for another day, when I have a little more free time again.

Now the question is:  How fast can someone solve these type of puzzles?  What's the best strategy to get to the win in the least possible number of moves normally? 

Randomly type in a number and you *could* get it in one guess, but where's the logic in that? 

Type in each number one at a time, click to check, and you're guaranteed to get the solution in 10 * wordlength guesses.

Type in all 5 digits the same, and you can eliminate a whole number from your guess each time.  (For example guess five zeros 00000, find out that there's no matches, you've now dropped the possible data pool down to only using numbers 1 to 9.  Do it for each of the numbers from 0 to 10, and you've eliminated half the puzzle in 10 guesses, as your 5 digit number can't hold 10 different values!)

Now that I've came up with the little problem to create the puzzles, I'm now left pondering on what might be the best solution for an AI to use to guess the puzzle in the fewest amount of tries possible.  Anyone have any thoughts on a surefire Code Breaker solution routine with the fewest possible attempts usually? 

I may end up trying to incorporate some sort of competition where a player tries to compete against the computer to shoot for the answer first, so various ideas for AI attempts could be written into the game as different opponents to try your luck against.  Suzy might just try random numbers.  Jane might do the meticulous one by one approach.  Fred might do an elimination approach to solving.  Anybody have any other methods to attempt for an AI?

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