QB64.org Forum

Active Forums => QB64 Discussion => Topic started by: SMcNeill on October 20, 2021, 01:26:27 pm

Title: Match Three
Post by: SMcNeill 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!)
Title: Re: Match Three
Post by: bplus on October 20, 2021, 02:03:25 pm
OK here's what it looks like on my screen, Title with desktop dimensions:
Title: Re: Match Three
Post by: SMcNeill on October 20, 2021, 02:08:11 pm
Your QB64 IDE is hiding the taskbar, but from the size and all, it looks like it's properly sizing and positioning itself on your screen.  👍
Title: Re: Match Three
Post by: Pete on October 20, 2021, 03:37:21 pm
Too hard for me. I lost 10 times in a row. Barely pressed a key and it indicated game over... Press any key to end, I believe it said. Can you dumb it down a bit for us non-farm professionals? :D

Hey Steve, looks the same on mine as on Mark's. Yes, I can see my Windows task bar at the bottom, and the title bar, of the app, at the top. My only concern is the numbers appear blurry with that font, size, and the close approximation of characters.

Pete
Title: Re: Match Three
Post by: bplus on October 20, 2021, 04:47:57 pm
Your QB64 IDE is hiding the taskbar, but from the size and all, it looks like it's properly sizing and positioning itself on your screen.  👍

I have my task bar on the left side (You can see half), there is so much more width than height on my laptop I save every pixel of height I can for QB64 programs!

But the sizing does seem to work OK, so far ;-))
Title: Re: Match Three
Post by: Dav on October 20, 2021, 07:47:02 pm
The Autoscale works well here.  Looks great.  Doesn't hide taskbar, and i can see title bar.

- Dav

Title: Re: Match Three
Post by: Pete on October 20, 2021, 08:25:02 pm
Steve does know we mean this Halloween, right???

Pete
Title: Re: Match Three
Post by: Richard on October 20, 2021, 08:41:15 pm
@SMcNeill

This is what it looks like on my display (native resolution 3200 x 1800)




 


 [ This attachment cannot be displayed inline in 'Print Page' view ]  






Can you make a    Match One    version for me?
Title: Re: Match Three
Post by: Dav on October 21, 2021, 08:14:00 am
Here's my screenshot.  The autoscale works well on my 1366x768 laptop.

- Dav

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Match Three
Post by: SMcNeill on October 21, 2021, 09:40:57 am
Thanks guys.  Seems like it's scaling properly for everyone.  Now I just need some little candy icons and the input loop, and I can turn it into a game with just a few hours work.  Scaling has been bugging the crap out of me lately, mainly because I hurt my back again and have been doing a lot more stuff on the 4k ultra-high def laptop where I can lounge in my recliner, than I have been on my PC with the less comfortable office chair associated with it. 

Having to upscale/downscale/resize everything was turning into a real PITA, so I have a feeling that little AutoScale snippet is going to end up in a lot of my stuff for the next couple of months.  It's a pleasure to see that it's properly sizing things on various displays properly, without any issues. 

Many thanks for testing and posting screenshots, one and all.  😘
Title: Re: Match Three
Post by: SMcNeill on October 27, 2021, 02:58:32 am
A very simple first version of this little One Click Match program:

Code: QB64: [Select]
  1. Dim Shared WS, GridSize, Choice, Matches, Center, Guess$, Guess, DisplayScreen
  2. ReDim Shared Grid(0, 0) As _Byte
  3. Choice = 1
  4.  
  5.     Function taskbar_height& ()
  6.  
  7. GridSize = 8: Matches = 3
  8.  
  9. renewgrid = -1
  10.     If renewgrid Then MakeGrid: renewgrid = 0
  11.     DisplayGrid
  12.     UserInput
  13.     _Limit 2
  14.     Choice = (Choice + 1) Mod GridSize
  15.     If Choice = 0 Then Choice = GridSize
  16. Loop Until checkwin
  17. WS = _NewImage(240, 240, 32)
  18.  
  19. Print "YOU ARE A BIG WEENER!! YAAAYYY!!"
  20. _FreeImage DisplayScreen
  21. DisplayScreen = 0
  22. AutoScale
  23.  
  24.  
  25.  
  26. Function checkwin
  27.     For x = 1 To GridSize
  28.         For y = 1 To GridSize
  29.             If Grid(x, y) <> 0 Then Exit Function
  30.     Next y, x
  31.     checkwin = -1
  32.  
  33. Sub UserInput
  34.     C = Choice - 1
  35.     If C = 0 Then C = GridSize
  36.     k = _KeyHit
  37.     Select Case k
  38.         Case 27
  39.             Screen 0: _FreeImage WS
  40.             WS = _NewImage(240, 240, 32)
  41.             Screen WS
  42.             _Font 8
  43.  
  44.             Cls
  45.             Print "YOU ARE A BIG LOSER!! HAHAHAHA!!"
  46.             _FreeImage DisplayScreen
  47.             DisplayScreen = 0
  48.             AutoScale
  49.             _KeyClear
  50.             Sleep
  51.             System
  52.  
  53.  
  54.         Case 32
  55.             For y = GridSize To 1 Step -1
  56.                 If Grid(C, y) <> 0 Then Exit For
  57.             Next
  58.             If y <> 0 Then
  59.                 '             If Grid(C, y) <> 0 Then
  60.                 If Grid(C, y) = Guess Or Guess = 0 Then
  61.                     Guess = Grid(C, y)
  62.                     Guess$ = Guess$ + _Trim$(Str$(Guess))
  63.                     Grid(C, y) = 0
  64.                     If Len(Guess$) = Matches Then
  65.                         Guess$ = ""
  66.                         Guess = 0
  67.                     End If
  68.                     DisplayGrid
  69.                 End If
  70.                 '        End If
  71.             End If
  72.     End Select
  73.     _KeyClear
  74.  
  75.  
  76. Sub DisplayGrid
  77.     Cls
  78.     For x = 1 To GridSize: For y = 1 To GridSize
  79.         If Grid(x, y) Then Locate y, x: Print _Trim$(Str$(Grid(x, y)));
  80.     Next y, x
  81.     Locate y, Choice: Print "^";
  82.     Center = 640 - _PrintWidth(String$(Matches, " ")) / 2
  83.     Line (0, GridSize * 8 + 8)-Step(639, 16), -1, BF
  84.     PW = _PrintWidth(String$(Matches, " "))
  85.     Line ((GridSize * 8 - PW) \ 2, GridSize * 8 + 8)-Step(PW, 8), &HFF000000, BF
  86.     _PrintString ((GridSize * 8 - PW) \ 2, GridSize * 8 + 8), Guess$
  87.     AutoScale
  88.  
  89. Sub MakeGrid
  90.  
  91.     If WS <> 0 Then Screen 0: _FreeImage WS
  92.  
  93.     WS = _NewImage(GridSize * 8, GridSize * 8 + 16, 32)
  94.     Screen WS
  95.     _Font 8 'this creates a 30x32 screen
  96.     ReDim Grid(1 To GridSize, 1 To GridSize) As _Byte
  97.  
  98.     count = -1: value = -1
  99.     For x = 1 To GridSize: For y = 1 To GridSize
  100.         count = (count + 1) Mod Matches
  101.         If count = 0 Then value = (value + 1) Mod Matches
  102.             Grid(y, x) = value + 1
  103.     Next y, x
  104.     If count <> Matches - 1 Then
  105.         For i = count To 0 Step -1
  106.             Grid(GridSize - i, GridSize) = 0
  107.         Next
  108.     End If
  109.  
  110.  
  111.     For x = 1 To GridSize: For y = 1 To GridSize
  112.         xswap = Int(Rnd * GridSize) + 1: yswap = Int(Rnd * GridSize) + 1
  113.         If Grid(x, y) <> 0 And Grid(xswap, yswap) <> 0 Then Swap Grid(xswap, yswap), Grid(x, y) 'Shuffle the grid
  114.     Next y, x
  115.     Guess$ = ""
  116.     Guess = 0
  117.  
  118. Sub AutoScale
  119.     If DisplayScreen = 0 Then
  120.         DW = _DesktopWidth
  121.         DH = _DesktopHeight
  122.  
  123.         Scale = (DH - taskbar_height) / 640
  124.         DisplayScreen = _NewImage(640 * Scale, 640 * Scale, 32)
  125.         Screen DisplayScreen
  126.         ScreenMove (DW - _Width(DisplayScreen)) \ 2, 0
  127.         _Source WS: _Dest WS
  128.     End If
  129.     _PutImage , WS, DisplayScreen
  130.     _Display
  131.  
  132. Sub ScreenMove (x, y)
  133.     $If BORDERDEC = UNDEFINED Then
  134.         $Let BORDERDEC = TRUE
  135.         Declare Library
  136.             Function glutGet& (ByVal what&)
  137.         End Declare
  138.     $End If
  139.     BorderWidth = glutGet(506)
  140.     TitleBarHeight = glutGet(507)
  141.     _ScreenMove x - BorderWidth, y - BorderWidth - TitleBarHeight
  142.  

There's a few internal variables which you guys can mess around with to affect difficulty and numbers of matches required:

 GridSize = 8: Matches = 3

Gridsize changes the size of our grid, Matches changes the number that an user has to meet for a match.

Surprisingly, I find the game to be harder than it first appears, at least for myself.  If I'm not careful, I end up boxing myself in and not being able to form a proper match to clear the values from the board, ending up with me getting stuck and having to forfeit the game.  :(



Still to come (if I find time between now and Halloween -- this has always been a crazy busy time here on the farm) is a substitution of candy sprites instead of numbers, a level system which gets progressively harder (level one might be gridsize 8, match 3.  level two would be gridsize 12, match 3.  level three might be gridsize 12, match 4.  level four might be gridsize 8, match 4...  And so on until the user barfs at the attempt to match an almost impossible level and quits.), and once we have levels, I can install a highscore system.

The basic gameplay is there for a one-button game (with a second button emergency exit with the ESC key, but does that *really* count towards gameplay??  IF necessary, I can swap the exit condition to something rather simple such as simply letting the selector pass the screen three times without choosing a number to remove, but personally I like the "QUICK, QUIT" use of the ESC key.  :P

Anywho, the hard part is done here with the mechanics.  Everything from this point forward is just bells and whistles. 

I *did* manage to create a little game before Halloween after all.  LOL!   ;D
Title: Re: Match Three
Post by: bplus on October 27, 2021, 09:50:23 am
Doesn't work for people (like me) who have their taskbar along the side of their screen, scale = 0 so errors out when scale is applied to resize or create screen.
Title: Re: Match Three
Post by: SMcNeill on October 27, 2021, 10:12:18 am
Doesn't work for people (like me) who have their taskbar along the side of their screen, scale = 0 so errors out when scale is applied to resize or create screen.

Evil sidebar!  I'll need to put an exemption in there for crazy machines with set-ups like that.  😤
Title: Re: Match Three
Post by: bplus on October 27, 2021, 11:47:51 am
This fixed it for me, interesting game, I am "A BIG WEENER!! YAAAYYY!!" thanks for that LOL

Code: QB64: [Select]
  1. Sub AutoScale
  2.     If DisplayScreen = 0 Then
  3.         DW = _DesktopWidth
  4.         DH = _DesktopHeight ' usuallly the le
  5.  
  6.         If DH = taskbar_height Then
  7.             If DH < DW Then scale = DH / 640 Else scale = DW / 640
  8.         Else
  9.             scale = (DH - taskbar_height) / 640
  10.         End If
  11.         'Cls
  12.         'Print DH, scale, taskbar_height ' <<<<<<<<<<<<<< taskbar_height is DH !!!
  13.         'End
  14.  
  15.  
  16.  
  17.  
  18.         DisplayScreen = _NewImage(640 * scale, 640 * scale, 32) '<<<<<<<<<<<<<<<<< error
  19.         Screen DisplayScreen
  20.         ScreenMove (DW - _Width(DisplayScreen)) \ 2, 0
  21.         _Source WS: _Dest WS
  22.     End If
  23.     _PutImage , WS, DisplayScreen
  24.     _Display
  25.  
Title: Re: Match Three
Post by: Pete on October 27, 2021, 06:46:43 pm
Quit playing games and vote! That one VA candidate is a real...


      /***\
***         ***  (ASCII Hat).

Sorry, I had to hack your Kobayashi Maru app. It turns out me and Kirk have that much in common; so now, "I'm a BIG WINNER!"

Pete 😉
Title: Re: Match Three
Post by: SMcNeill on October 27, 2021, 09:46:28 pm
Code: QB64: [Select]
  1. Type GameTurn_Type
  2.     GridSize As _Byte
  3.     Matches As _Byte
  4. Dim Shared WS, GridSize, Choice, Matches, Center, Guess$, Guess, DisplayScreen, score
  5. Dim GameTurn(10) As GameTurn_Type
  6.  
  7. ReDim Shared Grid(0, 0) As _Byte
  8. Choice = 1
  9.  
  10. GameLimit = 3
  11. GameTurn(0).GridSize = 8: GameTurn(0).Matches = 3
  12. GameTurn(1).GridSize = 12: GameTurn(1).Matches = 3
  13. GameTurn(2).GridSize = 12: GameTurn(2).Matches = 4
  14. GameTurn(3).GridSize = 8: GameTurn(3).Matches = 4
  15.  
  16. renewgrid = -1
  17.  
  18.  
  19. t# = Timer
  20.     If renewgrid Then
  21.         GridSize = GameTurn(GameOn).GridSize: Matches = GameTurn(GameOn).Matches
  22.         GameOn = GameOn + 1
  23.         If GameOn > GameLimit Then Exit Do
  24.         MakeGrid
  25.         DisplayScreen = 0
  26.         renewgrid = 0
  27.     End If
  28.     DisplayGrid
  29.     UserInput
  30.     _Limit 2
  31.     Choice = (Choice + 1) Mod GridSize
  32.     If Choice = 0 Then Choice = GridSize
  33.     If checkwin Then
  34.         score = score + Int(t# - Timer) * 5
  35.         ShowScore
  36.         renewgrid = -1
  37.         t# = Timer
  38.     End If
  39. WS = _NewImage(240, 240, 32)
  40.  
  41. Print "YOU ARE A BIG WEENER!! YAAAYYY!!"
  42. _FreeImage DisplayScreen
  43. DisplayScreen = 0
  44. AutoScale
  45.  
  46.  
  47.  
  48. Function checkwin
  49.     For x = 1 To GridSize
  50.         For y = 1 To GridSize
  51.             If Grid(x, y) <> 0 Then Exit Function
  52.     Next y, x
  53.     checkwin = -1
  54.  
  55. Sub UserInput
  56.     C = Choice - 1
  57.     If C = 0 Then C = GridSize
  58.     k = _KeyHit
  59.     Select Case k
  60.         Case 27
  61.             Screen 0: _FreeImage WS
  62.             WS = _NewImage(240, 240, 32)
  63.             Screen WS
  64.             _Font 8
  65.  
  66.             Cls
  67.             Print "YOU ARE A BIG LOSER!! HAHAHAHA!!"
  68.             _FreeImage DisplayScreen
  69.             DisplayScreen = 0
  70.             AutoScale
  71.             _KeyClear
  72.             Sleep
  73.             System
  74.  
  75.  
  76.         Case 32
  77.             For y = GridSize To 1 Step -1
  78.                 If Grid(C, y) <> 0 Then Exit For
  79.             Next
  80.             If y <> 0 Then
  81.                 '             If Grid(C, y) <> 0 Then
  82.                 If Grid(C, y) = Guess Or Guess = 0 Then
  83.                     Guess = Grid(C, y)
  84.                     Guess$ = Guess$ + _Trim$(Str$(Guess))
  85.                     Grid(C, y) = 0
  86.                     If Len(Guess$) = Matches Then
  87.                         Guess$ = ""
  88.                         Guess = 0
  89.                         score = score + 10 ^ Matches
  90.                     End If
  91.                     DisplayGrid
  92.                 End If
  93.                 '        End If
  94.             End If
  95.     End Select
  96.     _KeyClear
  97.  
  98.  
  99. Sub ShowScore
  100.     If WS <> 0 Then Screen 0: _FreeImage WS
  101.  
  102.     WS = _NewImage(240, 240, 32)
  103.     Screen WS
  104.     _Font 8
  105.     Cls , -1
  106.     Color &HFF000000, 0
  107.     Print "Round", "Score"
  108.  
  109.     Print _Trim$(Str$(GameOn + 1)), _Trim$(Str$(score))
  110.     DisplayScreen = 0
  111.     AutoScale
  112.     _Delay 2
  113.     _KeyClear
  114.     Sleep
  115.     _KeyClear
  116.  
  117.  
  118.  
  119. Sub DisplayGrid
  120.     Cls
  121.     For x = 1 To GridSize: For y = 1 To GridSize
  122.         If Grid(x, y) Then Locate y, x: Print _Trim$(Str$(Grid(x, y)));
  123.     Next y, x
  124.     Locate y, Choice: Print "^";
  125.     Center = 640 - _PrintWidth(String$(Matches, " ")) / 2
  126.     Line (0, GridSize * 8 + 8)-Step(639, 16), -1, BF
  127.     PW = _PrintWidth(String$(Matches, " "))
  128.     Line ((GridSize * 8 - PW) \ 2, GridSize * 8 + 8)-Step(PW, 8), &HFF000000, BF
  129.     _PrintString ((GridSize * 8 - PW) \ 2, GridSize * 8 + 8), Guess$
  130.     AutoScale
  131.  
  132. Sub MakeGrid
  133.     If WS <> 0 Then Screen 0: _FreeImage WS
  134.  
  135.     WS = _NewImage(GridSize * 8, GridSize * 8 + 16, 32)
  136.     Screen WS
  137.     _Font 8 'this creates a 30x32 screen
  138.     ReDim Grid(1 To GridSize, 1 To GridSize) As _Byte
  139.  
  140.     count = -1: value = -1
  141.     For x = 1 To GridSize: For y = 1 To GridSize
  142.         count = (count + 1) Mod Matches
  143.         If count = 0 Then value = (value + 1) Mod Matches
  144.             Grid(y, x) = value + 1
  145.     Next y, x
  146.     If count <> Matches - 1 Then
  147.         For i = count To 0 Step -1
  148.             Grid(GridSize - i, GridSize) = 0
  149.         Next
  150.     End If
  151.  
  152.  
  153.     For x = 1 To GridSize: For y = 1 To GridSize
  154.         xswap = Int(Rnd * GridSize) + 1: yswap = Int(Rnd * GridSize) + 1
  155.         If Grid(x, y) <> 0 And Grid(xswap, yswap) <> 0 Then Swap Grid(xswap, yswap), Grid(x, y) 'Shuffle the grid
  156.     Next y, x
  157.     Guess$ = ""
  158.     Guess = 0
  159.  
  160. Sub AutoScale
  161.     If DisplayScreen = 0 Then
  162.         DW = _DesktopWidth
  163.         DH = _DesktopHeight
  164.         $If WIN Then
  165.             Declare Library "th"
  166.                 Function taskbar_height& ()
  167.             End Declare
  168.             TH = taskbar_height
  169.         $End If
  170.         If TH >= DH Or TH = 0 Then TH = 100
  171.         Scale = (DH - TH) / 640
  172.         DisplayScreen = _NewImage(640 * Scale, 640 * Scale, 32)
  173.         Screen DisplayScreen
  174.         ScreenMove (DW - _Width(DisplayScreen)) \ 2, 0
  175.         _Source WS: _Dest WS
  176.     End If
  177.     _PutImage , WS, DisplayScreen
  178.     _Display
  179.  
  180. Sub ScreenMove (x, y)
  181.     $If BORDERDEC = UNDEFINED Then
  182.         $Let BORDERDEC = TRUE
  183.         Declare Library
  184.             Function glutGet& (ByVal what&)
  185.         End Declare
  186.     $End If
  187.     BorderWidth = glutGet(506)
  188.     TitleBarHeight = glutGet(507)
  189.     _ScreenMove x - BorderWidth, y - BorderWidth - TitleBarHeight
  190.  

Game now runs for multiple rounds before ending, as well as having a scoring system in it.   Bplus's glitch with the autoscale not working should be fixed, and the taskbar height routine shouldn't be an issue for folks on Linux or Mac now. 

At this point, the game is basically finished, unless I want to swap in some bells and whistles like music and images instead of the plain old numbers which we're using here.  In a lot of ways, I kind of like just sticking with the numbers for a sort of retro-Screen 0 type feel for everything.  A simple high score system would be nice to add, but it's a pain in the rump to add and deal with, while sticking to the single-input rule, and my time is limited here before Halloween.  Maybe I'll take time and add that into the game after the holiday comes around and passes.  LOL!  :P

Anywho, test it out.  Tell me what you think, and let me know if you run into any glitches or unexpected behavior with everything.
Title: Re: Match Three
Post by: Pete on October 27, 2021, 09:59:21 pm
If you decide you want to add a top five scoring system, here's my stripped down version using LINE INPUT: https://www.qb64.org/forum/index.php?topic=4339.msg137511#msg137511

I think we both have custom keyboard input programs, which could substitute for the LINE INPUT statement.

The ASCII Invaders game uses the 1-key method: https://www.qb64.org/forum/index.php?topic=4245.msg137017#msg137017

I might even still have the stripped down 1-key input method, if you're interested.

Pete