QB64.org Forum

Active Forums => Programs => Topic started by: bplus on July 20, 2019, 09:15:27 pm

Title: Letter Memory
Post by: bplus on July 20, 2019, 09:15:27 pm
A simple little game to play until Ken gets his next thing going. :)

Code: QB64: [Select]
  1. DEFINT A-Z
  2. _TITLE "Letter Memory Remake" '  by bplus started 2019-06-09 mod structure of first game
  3.  
  4. ' Keep clicking boxes until all the letter pairs are revealed.
  5.  
  6. TYPE XYtype
  7.     X AS INTEGER
  8.     Y AS INTEGER
  9.  
  10. TYPE LetterBox
  11.     XY AS XYtype
  12.     Reveal AS INTEGER ' 0, -1 revealed when matched, stay revealed
  13.     Letter AS STRING '  letter to match
  14.  
  15. CONST xmax = 400, ymax = 450, boxSize = 50, xoffLetter = (boxSize - 8) / 2, yoffLetter = (boxSize - 16) / 2 ' for letters in box
  16. SCREEN _NEWIMAGE(xmax, ymax, 32)
  17. _SCREENMOVE 360, 60
  18. REDIM SHARED LB(1 TO 1) AS LetterBox, nBoxes 'so setup can set values to these globals
  19. REDIM SHARED shuffle(1 TO 1) AS STRING 'container of letter pairs to shuffle and distrbute before each round
  20. DIM SHARED nRevealed, b1Index, b2Index, tStart!, s$
  21. DIM i
  22. setUpGame
  23.     tStart! = TIMER(.001)
  24.     initRound
  25.     CLS
  26.     updateScreen
  27.     DO
  28.         i = getBoxIndex
  29.         IF i THEN
  30.             IF b1Index = 0 THEN 'first reveal box
  31.                 IF LB(i).Reveal <> -1 THEN b1Index = i: LB(i).Reveal = -1
  32.             ELSE '2nd reveal box
  33.                 IF LB(i).Reveal <> -1 THEN b2Index = i: LB(i).Reveal = -1
  34.             END IF
  35.             updateScreen
  36.         END IF
  37.         IF b2Index <> 0 THEN 'check match, if they do leave them revealed
  38.             IF LB(b1Index).Letter <> LB(b2Index).Letter THEN 'no match
  39.                 _DELAY 1
  40.                 LB(b1Index).Reveal = 0: LB(b2Index).Reveal = 0
  41.                 nRevealed = nRevealed - 2 'when complete = number of squares then done
  42.                 updateScreen
  43.             END IF
  44.             b1Index = 0: b2Index = 0 'clear box clicks
  45.         END IF
  46.         _LIMIT 60
  47.     LOOP UNTIL nRevealed = nBoxes
  48.     COLOR &HFFDDDDDD, &HFF000000
  49.     s$ = "Completed in" + STR$(INT(TIMER(.001) - tStart!)) + " secs."
  50.     LOCATE 2, (xmax / 8 - LEN(s$)) / 2: PRINT s$
  51.     _DELAY 2
  52.  
  53. FUNCTION getBoxIndex
  54.     DIM m, mx, my, mb, i
  55.     mb = _MOUSEBUTTON(1) '            left button down
  56.     IF mb THEN '                      get last place mouse button was down
  57.         WHILE mb '                    wait for mouse button release as a "click"
  58.             m = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  59.         WEND
  60.         FOR i = 1 TO nBoxes '         now find which box was clicked
  61.             IF mx > LB(i).XY.X AND mx < LB(i).XY.X + boxSize THEN
  62.                 IF my > LB(i).XY.Y AND my < LB(i).XY.Y + boxSize THEN
  63.                     getBoxIndex = i: EXIT FUNCTION
  64.                 END IF
  65.             END IF
  66.         NEXT
  67.     END IF
  68.  
  69. SUB updateScreen
  70.     DIM i
  71.     nRevealed = 0 '              (shared) detect how many boxes are revealed
  72.     FOR i = 1 TO nBoxes
  73.         LINE (LB(i).XY.X, LB(i).XY.Y)-STEP(boxSize, boxSize), &HFFFF0000, BF
  74.         IF LB(i).Reveal = -1 THEN
  75.             COLOR &HFFDDDDDD, &HFFFF0000
  76.             _PRINTSTRING (LB(i).XY.X + xoffLetter, LB(i).XY.Y + yoffLetter), LB(i).Letter
  77.             nRevealed = nRevealed + 1
  78.         END IF
  79.     NEXT
  80.  
  81. SUB initRound 'reassign letters and hide them all
  82.     DIM i, r
  83.     FOR i = nBoxes TO 2 STEP -1 ' shuffle stuff in array
  84.         r = INT(i * RND) + 1
  85.         SWAP shuffle(i), shuffle(r)
  86.     NEXT
  87.     FOR i = 1 TO nBoxes '       reset or reassign values
  88.         LB(i).Letter = shuffle(i): LB(i).Reveal = 0
  89.     NEXT
  90.  
  91. SUB setUpGame
  92.     DIM i, x, y '(                main) CONST xmax = 400, ymax = 450, boxSize = 50
  93.     CONST xBoxes = 6, yBoxes = 4 '           Board N x M  boxes across, boxes down
  94.     nBoxes = xBoxes * yBoxes '               Total boxes (shared)
  95.     REDIM LB(1 TO nBoxes) AS LetterBox '     ready to rec data (shared)
  96.     'CONST boxSize = 50                '     Screen drawing topleft box locations
  97.     CONST spacer = 5 '                       for XY calc
  98.     CONST xoffset = INT((xmax - boxSize * xBoxes - spacer * (xBoxes - 1)) / 2)
  99.     CONST yoffset = INT((ymax - boxSize * yBoxes - spacer * (yBoxes - 1)) / 2)
  100.     CONST sq = boxSize + spacer '            for XY calc
  101.     FOR y = 1 TO yBoxes '                    set screen XY locations for all boxes
  102.         FOR x = 1 TO xBoxes
  103.             i = i + 1
  104.             LB(i).XY.X = xoffset + (x - 1) * sq
  105.             LB(i).XY.Y = yoffset + (y - 1) * sq
  106.         NEXT
  107.     NEXT
  108.     REDIM shuffle(1 TO nBoxes) AS STRING ' load shuffle array for shuffling later (shared)
  109.     CONST letterPairs = "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ11223344556677889900"
  110.     FOR i = 1 TO nBoxes
  111.         shuffle(i) = MID$(letterPairs, i, 1)
  112.     NEXT
  113.  

EDIT: updateScreen xoff, yoff made into xoffLetter, yoffLetter CONST's, as not efficient to recalc those for every update.
Title: Re: Letter Memory
Post by: SierraKen on July 20, 2019, 11:39:44 pm
Wow B+ nice game! Wouldn't help me that good though because my short term memory has been super bad since my head injury decades ago lol. I think I'm going to convert an old ASIC game called Alphabet Invaders to QB64. :)
Title: Re: Letter Memory
Post by: Ashish on July 21, 2019, 12:19:12 am
Cool game Bplus!

 [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Letter Memory
Post by: johnno56 on July 21, 2019, 12:42:07 am
Nice game. Bit of a workout for My grey matter as well...

Does it come in blue?  lol

J
Title: Re: Letter Memory
Post by: bplus on July 21, 2019, 09:09:51 am
Thanks guys, should be easy to modify colors, add more buttons for letters and digit pairs...  I don't know about pointy ears though. ;-))

Well what do you know!?
 
Title: Re: Letter Memory
Post by: Pete on July 21, 2019, 12:12:55 pm
I'll stick with Republican Red!

Easy game...

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

Pete
Title: Re: Letter Memory
Post by: TempodiBasic on July 21, 2019, 01:09:38 pm
Cool Bplus!
I find it very fine so that I think to add a simple mod while the ideas are flourishing!

try it please!
Code: QB64: [Select]
  1. DEFINT A-Z
  2. _TITLE "Letter Memory Remake" '  by bplus started 2019-06-09 mod structure of first game
  3.  
  4. ' Keep clicking boxes until all the letter pairs are revealed.
  5.  
  6. TYPE XYtype
  7.     X AS INTEGER
  8.     Y AS INTEGER
  9.  
  10. TYPE LetterBox
  11.     XY AS XYtype
  12.     Reveal AS INTEGER ' 0, -1 revealed when matched, stay revealed
  13.     Letter AS STRING '  letter to match
  14.  
  15. CONST xmax = 400, ymax = 450, boxSize = 50, xoffLetter = (boxSize - 8) / 2, yoffLetter = (boxSize - 16) / 2 ' for letters in box
  16.  
  17. CONST Topten = "TopTen.SAV", Bonus = 100 ' <---new line TDB
  18. SCREEN _NEWIMAGE(xmax, ymax, 32)
  19. _SCREENMOVE 360, 60
  20. REDIM SHARED LB(1 TO 1) AS LetterBox, nBoxes 'so setup can set values to these globals
  21. REDIM SHARED shuffle(1 TO 1) AS STRING 'container of letter pairs to shuffle and distrbute before each round
  22. DIM SHARED nRevealed, b1Index, b2Index, tStart!, s$
  23. DIM SHARED Score AS LONG ' <---new line TDB
  24. DIM i
  25. setUpGame
  26.  
  27.     tStart! = TIMER(.001)
  28.     initRound
  29.     CLS
  30.     updateScreen
  31.     DO
  32.         i = getBoxIndex
  33.         IF i THEN
  34.             IF b1Index = 0 THEN 'first reveal box
  35.                 IF LB(i).Reveal <> -1 THEN b1Index = i: LB(i).Reveal = -1
  36.             ELSE '2nd reveal box
  37.                 IF LB(i).Reveal <> -1 THEN b2Index = i: LB(i).Reveal = -1
  38.             END IF
  39.             updateScreen
  40.         END IF
  41.         IF b2Index <> 0 THEN 'check match, if they do leave them revealed
  42.             IF LB(b1Index).Letter <> LB(b2Index).Letter THEN 'no match
  43.                 _DELAY 1
  44.                 LB(b1Index).Reveal = 0: LB(b2Index).Reveal = 0
  45.                 nRevealed = nRevealed - 2 'when complete = number of squares then done
  46.                 updateScreen
  47.  
  48.                 Score = Score + Bonus
  49.             END IF
  50.             b1Index = 0: b2Index = 0 'clear box clicks
  51.         END IF
  52.         _LIMIT 60
  53.     LOOP UNTIL nRevealed = nBoxes
  54.     COLOR &HFFDDDDDD, &HFF000000
  55.     ' qua calcola il tempo come punteggio aggiuntivo
  56.     s$ = "Completed in" + STR$(INT(TIMER(.001) - tStart!)) + " secs."
  57.     LOCATE 2, (xmax / 8 - LEN(s$)) / 2: PRINT s$
  58.     _DELAY 2
  59.  
  60. FUNCTION getBoxIndex
  61.     DIM m, mx, my, mb, i
  62.     mb = _MOUSEBUTTON(1) '            left button down
  63.     IF mb THEN '                      get last place mouse button was down
  64.         WHILE mb '                    wait for mouse button release as a "click"
  65.             m = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  66.         WEND
  67.         FOR i = 1 TO nBoxes '         now find which box was clicked
  68.             IF mx > LB(i).XY.X AND mx < LB(i).XY.X + boxSize THEN
  69.                 IF my > LB(i).XY.Y AND my < LB(i).XY.Y + boxSize THEN
  70.                     getBoxIndex = i: EXIT FUNCTION
  71.                 END IF
  72.             END IF
  73.         NEXT
  74.         ' if no nBoxe clicked , user maybe clicks on menubar
  75.         DIM done, High$ ' <---new lines TDB
  76.         IF my < 16 THEN
  77.             SELECT CASE mx
  78.                 CASE 55 TO 85
  79.                     ' END
  80.                     COLOR , &HFF0000FF
  81.                     _PRINTSTRING ((xmax - 60) / 2, 400), "QUIT?"
  82.                     _PRINTSTRING ((xmax - 110) / 2, 430), "[YES]  [NO]"
  83.                     done = 0
  84.                     WHILE done = 0
  85.                         done = LEN(INKEY$)
  86.                         IF _MOUSEINPUT THEN
  87.                             IF _MOUSEBUTTON(1) OR _MOUSEBUTTON(2) THEN done = 1
  88.                             mx = _MOUSEX: my = _MOUSEY
  89.                         END IF
  90.                     WEND
  91.                     IF my >= 430 AND my <= 450 THEN
  92.                         IF mx <= 188 AND mx >= 130 THEN
  93.                             ' yes  Quit
  94.                             COLOR , &HFF000000
  95.                             CLS
  96.                             DIM NAMES AS STRING * 8
  97.                             _PRINTSTRING ((xmax - 110) / 2, 380), "ENTER NAME"
  98.                             INPUT NAMES
  99.                             OPEN Topten FOR APPEND AS #1
  100.                             PRINT #1, NAMES + STR$(Score)
  101.                             CLOSE #1
  102.                             'Topten
  103.                             COLOR , &HFF000000
  104.                             CLS
  105.                             IF NOT _FILEEXISTS(Topten) THEN
  106.                                 _PRINTSTRING ((xmax - 160) / 2, 100), "File " + Topten + " corrupted"
  107.                             ELSE
  108.                                 COLOR , &HFF0000FF
  109.                                 LOCATE , 20: PRINT "HIGHSCORES"
  110.                                 LOCATE , 20: PRINT " TOP TEN "
  111.                                 PRINT: PRINT
  112.                                 OPEN Topten FOR INPUT AS #1
  113.                                 WHILE NOT EOF(1)
  114.                                     INPUT #1, High$
  115.                                     LOCATE , 15
  116.                                     PRINT High$
  117.                                     _DELAY .5
  118.                                 WEND
  119.                                 CLOSE #1
  120.                             END IF
  121.  
  122.                             SLEEP 4
  123.                             END
  124.                         ELSE
  125.                             COLOR , &HFF000000
  126.                             CLS
  127.                             updateScreen
  128.                         END IF
  129.                     END IF
  130.  
  131.                 CASE 110 TO 158
  132.                     'pause
  133.                     COLOR , &HFF0000FF
  134.                     _PRINTSTRING ((xmax - 60) / 2, 400), "PAUSED"
  135.                     done = 0
  136.                     WHILE done = 0
  137.                         done = LEN(INKEY$)
  138.                         IF _MOUSEINPUT THEN
  139.                             IF _MOUSEBUTTON(1) OR _MOUSEBUTTON(2) THEN done = 1
  140.                         END IF
  141.                     WEND
  142.                     COLOR , &HFF000000
  143.                     CLS
  144.                     updateScreen
  145.                 CASE 180 TO 238
  146.                     'Topten
  147.                     COLOR , &HFF000000
  148.                     CLS
  149.                     IF NOT _FILEEXISTS(Topten) THEN
  150.                         _PRINTSTRING ((xmax - 160) / 2, 100), "File " + Topten + " corrupted"
  151.                     ELSE
  152.                         COLOR , &HFF0000FF
  153.                         LOCATE , 20: PRINT "HIGHSCORES"
  154.                         LOCATE , 20: PRINT " TOP TEN "
  155.                         PRINT: PRINT
  156.                         OPEN Topten FOR INPUT AS #1
  157.                         WHILE NOT EOF(1)
  158.                             INPUT #1, High$
  159.                             LOCATE , 15
  160.                             PRINT High$
  161.                             _DELAY .5
  162.                         WEND
  163.                         CLOSE #1
  164.                     END IF
  165.                     done = 0
  166.                     WHILE done = 0
  167.                         done = LEN(INKEY$)
  168.                         IF _MOUSEINPUT THEN
  169.                             IF _MOUSEBUTTON(1) OR _MOUSEBUTTON(2) THEN done = 1
  170.                         END IF
  171.                     WEND
  172.                     COLOR , &HFF000000
  173.                     CLS
  174.                     updateScreen
  175.                 CASE 250 TO 294
  176.                     ' Help
  177.                     COLOR , &HFF000000
  178.                     CLS
  179.                     COLOR , &HFF0000FF
  180.                     _PRINTSTRING ((xmax - 60) / 2, 100), "Help:"
  181.                     _PRINTSTRING (5, 120), "-find the matched letters"
  182.                     _PRINTSTRING (5, 140), "-more matches more scores"
  183.                     _PRINTSTRING ((xmax - 60) / 2, 160), "Menu:"
  184.                     _PRINTSTRING (5, 180), "END = quit, Pause = wait, Topten = HighScores"
  185.                     _PRINTSTRING (5, 200), "Help = this screen"
  186.                     done = 0
  187.                     WHILE done = 0
  188.                         done = LEN(INKEY$)
  189.                         IF _MOUSEINPUT THEN
  190.                             IF _MOUSEBUTTON(1) OR _MOUSEBUTTON(2) THEN done = 1
  191.                         END IF
  192.                     WEND
  193.                     COLOR , &HFF000000
  194.                     CLS
  195.                     updateScreen
  196.                 CASE ELSE
  197.             END SELECT
  198.         END IF
  199.     END IF
  200.  
  201. SUB updateScreen
  202.     DIM i
  203.     nRevealed = 0 '              (shared) detect how many boxes are revealed
  204.     FOR i = 1 TO nBoxes
  205.         LINE (LB(i).XY.X, LB(i).XY.Y)-STEP(boxSize, boxSize), &HFFFF0000, BF
  206.         IF LB(i).Reveal = -1 THEN
  207.             COLOR &HFFDDDDDD, &HFFFF0000
  208.             _PRINTSTRING (LB(i).XY.X + xoffLetter, LB(i).XY.Y + yoffLetter), LB(i).Letter
  209.             nRevealed = nRevealed + 1
  210.         END IF
  211.     NEXT
  212.     '    qua il rigo guida menu
  213.     LINE (1, 1)-(xmax, 15), &HFF0000FF, BF ' <---new lines TDB
  214.     COLOR , &HFF0000FF
  215.     _PRINTSTRING (50, 0), "[END]  [Pause]  [TopTen] [Help] " '55-85  110-158  180-238  250-294
  216.     COLOR &HFFDDDDDD, &HFFFF0000
  217.  
  218.  
  219. SUB initRound 'reassign letters and hide them all
  220.     DIM i, r
  221.     FOR i = nBoxes TO 2 STEP -1 ' shuffle stuff in array
  222.         r = INT(i * RND) + 1
  223.         SWAP shuffle(i), shuffle(r)
  224.     NEXT
  225.     FOR i = 1 TO nBoxes '       reset or reassign values
  226.         LB(i).Letter = shuffle(i): LB(i).Reveal = 0
  227.     NEXT
  228.  
  229. SUB setUpGame
  230.     DIM i, x, y '(                main) CONST xmax = 400, ymax = 450, boxSize = 50
  231.     CONST xBoxes = 6, yBoxes = 4 '           Board N x M  boxes across, boxes down
  232.     nBoxes = xBoxes * yBoxes '               Total boxes (shared)
  233.     REDIM LB(1 TO nBoxes) AS LetterBox '     ready to rec data (shared)
  234.     'CONST boxSize = 50                '     Screen drawing topleft box locations
  235.     CONST spacer = 5 '                       for XY calc
  236.     CONST xoffset = INT((xmax - boxSize * xBoxes - spacer * (xBoxes - 1)) / 2)
  237.     CONST yoffset = INT((ymax - boxSize * yBoxes - spacer * (yBoxes - 1)) / 2)
  238.     CONST sq = boxSize + spacer '            for XY calc
  239.     FOR y = 1 TO yBoxes '                    set screen XY locations for all boxes
  240.         FOR x = 1 TO xBoxes
  241.             i = i + 1
  242.             LB(i).XY.X = xoffset + (x - 1) * sq
  243.             LB(i).XY.Y = yoffset + (y - 1) * sq
  244.         NEXT
  245.     NEXT
  246.     REDIM shuffle(1 TO nBoxes) AS STRING ' load shuffle array for shuffling later (shared)
  247.     CONST letterPairs = "AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ11223344556677889900"
  248.     FOR i = 1 TO nBoxes
  249.         shuffle(i) = MID$(letterPairs, i, 1)
  250.     NEXT
  251.  
  252.     ' section score TopTen
  253.     Score = 0 ' <---new lines TDB
  254.     IF NOT _FILEEXISTS(Topten) THEN
  255.         OPEN Topten FOR OUTPUT AS #1
  256.         PRINT #1, " 1. SMcNeill... 100000"
  257.         PRINT #1, " 1. Heitor..... 100000"
  258.         PRINT #1, " 1. Bplus...... 100000"
  259.         PRINT #1, " 1. Pete....... 100000"
  260.         PRINT #1, " 1. Petr....... 100000"
  261.         PRINT #1, " 1. Ashish..... 100000"
  262.         PRINT #1, " 1. Rhosigma... 100000"
  263.         PRINT #1, " 1. Qwerkey.... 100000"
  264.         PRINT #1, " 1. _Vince..... 100000"
  265.         PRINT #1, " 1. The Others. 100000"
  266.         CLOSE #1
  267.     END IF
  268.  

fine changing color of back of boxes! It can be another item of the menu!
:-)
Good Playing

@Pete
but do you  use C++ to hacking Bplus code?
O_O  you're Anonymous! https://www.repubblica.it/images/2011/07/18/184150799-e341c968-23d0-4422-ba68-97dc59b84b8a.jpg (https://www.repubblica.it/images/2011/07/18/184150799-e341c968-23d0-4422-ba68-97dc59b84b8a.jpg)
 https://images2.alphacoders.com/606/thumb-1920-606513.jpg (https://images2.alphacoders.com/606/thumb-1920-606513.jpg)
Title: Re: Letter Memory
Post by: johnno56 on July 21, 2019, 05:47:28 pm
bplus,

Not exactly the shade of blue I was expecting, but blue none the less... Cool...

Now... about the letters.... How is your ancient Samarian? lol
Title: Re: Letter Memory
Post by: bplus on July 21, 2019, 09:33:40 pm
TempodiBasic, that's quite a mod! longer than the original program that took some time!

I did have in mind a mod myself, not quite Sumarian... :)


Title: Re: Letter Memory
Post by: johnno56 on July 22, 2019, 08:54:14 am
Oh. What about Klingon? Vulcan will do in a pinch (no pun intended) but, if you settle for Romulan, your punishment will be to memorise all the Ferengi Laws of Acquisition...
Title: Re: Letter Memory
Post by: TempodiBasic on July 22, 2019, 12:21:31 pm
Quote
not quite Sumarian... :)
???
Please what do you mean with sumarian?
Sumerian http://www.ilsapere.org/wp-content/uploads/bfi_thumb/sumeri-1-33i7zodpx38ur4jhrymnsw.jpg (http://www.ilsapere.org/wp-content/uploads/bfi_thumb/sumeri-1-33i7zodpx38ur4jhrymnsw.jpg)
or somariano (dummy or donkey) http://2.bp.blogspot.com/-WnfOoV8iYpc/UycT2mfxmsI/AAAAAAAAAY4/ygQu51cLbUw/s1600/donkey-821x1024.jpg (http://2.bp.blogspot.com/-WnfOoV8iYpc/UycT2mfxmsI/AAAAAAAAAY4/ygQu51cLbUw/s1600/donkey-821x1024.jpg)
:D

If you like, you can short my mod and make it fine to you  building more SUB and Function at the place of write the same code anywhere, moreover you can use a k-ed position on X an Y for the menu items to click. And a record type to store Topten in file.
Just as you prefer.
;-)
Thanks to give a look.
Title: Re: Letter Memory
Post by: bplus on July 22, 2019, 12:40:50 pm
Sumarian, Samarian, there is a difference?

Apparently so: https://www.quora.com/Is-Sumerian-the-same-thing-as-Samaritan... wait that's Samaritans, sa-martians???  :D those we learned about from Bible (the good one) and Ancient Aliens program ;-))

Hi TempodiBasic,

The top ten list is great for games of competition, IMHO not so hot for this little app. For me, scores quickly go down with repetition of play because I start to confuse letters in position 1 or 2 games ago.

The code you started might be generalized so one could add it to any great games program along with a sort to put scores from high to low... wait was that already in there? Also I would score times to complete a board of n matches.
Title: Re: Letter Memory
Post by: TempodiBasic on July 22, 2019, 04:27:51 pm
about
Quote
Also I would score times to complete a board of n matches.
what weight do you think to give to the time used to complete a level?
do you like a formula as scoreTimeBonus = Premium/timePassed and/ or use scoreTimeBonus as multiplier of total score of the match (that is always the same)?
Title: Re: Letter Memory
Post by: bplus on July 22, 2019, 05:55:03 pm
I'm not interested in scoring this game.
Title: Re: Letter Memory
Post by: Petr on July 23, 2019, 03:15:24 am
Cool game, BPlus.   

and...

Nice hack, Pete :-D
Title: Re: Letter Memory
Post by: bplus on July 23, 2019, 02:01:59 pm
Here is a much more challenging Letter Memory Game.

The letters are paired off such that when one letter is revealed you must reveal the paired letter, it takes a little longer to process :)

Code: QB64: [Select]
  1. DEFINT A-Z
  2. _TITLE "Match Paired Letters Memory Game" '  by bplus started 2019-07-23
  3. 'this is a variation of Letter Memory Game Remake (July 2019)
  4.  
  5. 'Listed in lines below the board are letters pairs to be matched.
  6. 'Click 2 boxes to reveal potential match, if so the boxes remain revealed.
  7. 'The object is to quickly get all the boxes revealed exposing full alphabet.
  8.  
  9. TYPE XYtype
  10.     X AS INTEGER
  11.     Y AS INTEGER
  12.  
  13. TYPE LetterBox
  14.     XY AS XYtype
  15.     Reveal AS INTEGER ' 0, -1 revealed when matched, stay revealed
  16.     Letter AS STRING '  letter to match
  17.  
  18. CONST xmax = 800, ymax = 300, boxSize = 50 'screen stuff
  19. CONST xoffLetter = (boxSize - 8) / 2, yoffLetter = (boxSize - 16) / 2 ' for letters in box
  20. SCREEN _NEWIMAGE(xmax, ymax, 32)
  21. _SCREENMOVE 360, 60
  22. REDIM SHARED LB(1 TO 1) AS LetterBox, nBoxes 'so setup can set values to these globals
  23. REDIM SHARED shuffle(1 TO 1) AS STRING 'container of letter pairs to shuffle and distrbute before each round
  24. DIM SHARED nRevealed
  25. DIM i, s$, b1Index, b2Index, tStart!, clickCnt
  26. setUpGame
  27.     tStart! = TIMER(.001)
  28.     initRound
  29.     CLS
  30.     updateScreen
  31.     DO
  32.         i = getBoxIndex
  33.         IF i THEN 'reveals, click counts only count if they are revealing
  34.             IF b1Index = 0 THEN 'first reveal box
  35.                 IF LB(i).Reveal <> -1 THEN b1Index = i: LB(i).Reveal = -1: clickCnt = clickCnt + 1
  36.             ELSE '2nd reveal box
  37.                 IF LB(i).Reveal <> -1 THEN b2Index = i: LB(i).Reveal = -1: clickCnt = clickCnt + 1
  38.             END IF
  39.             updateScreen
  40.         END IF
  41.         IF b2Index <> 0 THEN 'check pair, if they are a matched pair leave them revealed
  42.             IF ABS(ASC(LB(b1Index).Letter) - ASC(LB(b2Index).Letter)) <> 13 THEN 'no match
  43.                 _DELAY 1
  44.                 LB(b1Index).Reveal = 0: LB(b2Index).Reveal = 0
  45.                 nRevealed = nRevealed - 2 'when complete = number of squares then done
  46.                 updateScreen
  47.             END IF
  48.             b1Index = 0: b2Index = 0 'clear box clicks
  49.         END IF
  50.         _LIMIT 60
  51.     LOOP UNTIL nRevealed = nBoxes
  52.     COLOR &HFFDDDDDD, &HFF000000
  53.     s$ = "Completed in" + STR$(INT(TIMER(.001) - tStart!)) + " secs and" + STR$(clickCnt) + " clicks."
  54.     LOCATE 3, (xmax / 8 - LEN(s$)) / 2: PRINT s$
  55.     _DELAY 7
  56.  
  57. FUNCTION getBoxIndex
  58.     DIM m, mx, my, mb, i
  59.     mb = _MOUSEBUTTON(1) '            left button down
  60.     IF mb THEN '                      get last place mouse button was down
  61.         WHILE mb '                    wait for mouse button release as a "click"
  62.             m = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  63.         WEND
  64.         FOR i = 1 TO nBoxes '         now find which box was clicked
  65.             IF mx > LB(i).XY.X AND mx < LB(i).XY.X + boxSize THEN
  66.                 IF my > LB(i).XY.Y AND my < LB(i).XY.Y + boxSize THEN
  67.                     getBoxIndex = i: EXIT FUNCTION
  68.                 END IF
  69.             END IF
  70.         NEXT
  71.     END IF
  72.  
  73. SUB updateScreen
  74.     DIM i
  75.     COLOR &HFFAAAAFF, &HFF000000
  76.     LOCATE 15, 12: PRINT "Letter Pairs to Match:  A   B   C   D   E   F   G   H   I   J   K   L   M"
  77.     LOCATE 16, 12: PRINT "                 with:  N   O   P   Q   R   S   T   U   V   W   X   Y   Z"
  78.     nRevealed = 0 '              (shared) detect how many boxes are revealed
  79.     FOR i = 1 TO nBoxes
  80.         LINE (LB(i).XY.X, LB(i).XY.Y)-STEP(boxSize, boxSize), &HFFFF0000, BF
  81.         IF LB(i).Reveal = -1 THEN
  82.             COLOR &HFFDDDDDD, &HFFFF0000
  83.             _PRINTSTRING (LB(i).XY.X + xoffLetter, LB(i).XY.Y + yoffLetter), LB(i).Letter
  84.             nRevealed = nRevealed + 1
  85.         END IF
  86.     NEXT
  87.  
  88. SUB initRound 'reassign letters and hide them all
  89.     DIM i, r
  90.     FOR i = nBoxes TO 2 STEP -1 ' shuffle stuff in array
  91.         r = INT(i * RND) + 1
  92.         SWAP shuffle(i), shuffle(r)
  93.     NEXT
  94.     FOR i = 1 TO nBoxes '       reset or reassign values
  95.         LB(i).Letter = shuffle(i): LB(i).Reveal = 0
  96.     NEXT
  97.  
  98. SUB setUpGame
  99.     DIM i, x, y '(                main) CONST xmax = 800, ymax = 300, boxSize = 50
  100.     CONST xBoxes = 13, yBoxes = 2 '          Board N x M  boxes across, boxes down
  101.     nBoxes = xBoxes * yBoxes '               Total boxes (shared)
  102.     REDIM LB(1 TO nBoxes) AS LetterBox '     ready to rec data (shared)
  103.     'CONST boxSize = 50                '     Screen drawing topleft box locations
  104.     CONST spacer = 5 '                       for XY calc
  105.     CONST xoffset = INT((xmax - boxSize * xBoxes - spacer * (xBoxes - 1)) / 2)
  106.     CONST yoffset = INT((ymax - boxSize * yBoxes - spacer * (yBoxes - 1)) / 2)
  107.     CONST sq = boxSize + spacer '            for XY calc
  108.     FOR y = 1 TO yBoxes '                    set screen XY locations for all boxes
  109.         FOR x = 1 TO xBoxes
  110.             i = i + 1
  111.             LB(i).XY.X = xoffset + (x - 1) * sq
  112.             LB(i).XY.Y = yoffset + (y - 1) * sq
  113.         NEXT
  114.     NEXT
  115.     REDIM shuffle(1 TO nBoxes) AS STRING ' load shuffle array for shuffling later (shared)
  116.     CONST letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  117.     FOR i = 1 TO nBoxes
  118.         shuffle(i) = MID$(letters, i, 1)
  119.     NEXT
  120.  
  121.  

Title: Re: Letter Memory
Post by: Petr on July 23, 2019, 02:29:24 pm
Cool idea, very good!
Title: Re: Letter Memory
Post by: TempodiBasic on July 23, 2019, 04:37:07 pm
yep it is a harder level of pair!
Cool!
I find more difficult also the couple of boxes and not the previouse square scheme.
Title: Re: Letter Memory
Post by: bplus on July 23, 2019, 05:44:52 pm
Well I am glad I am cooling you guys off this summer :D

Thanks!
Title: Re: Letter Memory
Post by: Ashish on July 24, 2019, 03:32:09 am
Good Job. I played this for half an hour but I never get less than 200 sec...
Title: Re: Letter Memory
Post by: bplus on July 24, 2019, 03:01:33 pm
Good Job. I played this for half an hour but I never get less than 200 sec...

Hi Ashish,

Today I had my first below 200, it gets a little easier once you start to remember pairs automatically and mainly focus on remembering where letters are, trying not to waste time remembering the matching letter because you can look that up at bottom of screen.

Of course it doesn't hurt either to use the code to create and test Button tools for your toolbox.

Here I have the game rewritten with my first set of button tools:
Code: QB64: [Select]
  1. DEFINT A-Z
  2. _TITLE "Button Memory Game" '  by bplus started 2019-07-24
  3. 'This is a generalization of "Match Paired Letters Memory Game" by bplus started 2019-07-23
  4.  
  5. ' The goal here is 2 Fold:
  6. '   Broaden the Memory Game seires to more than letters,
  7. '   And develop some potential button library procedures.
  8. ' 1. Button Type
  9. ' 2. Button Draw
  10. ' 3. Buttons Layout  'setup a whole keypad of buttons, assuming base 1 for first index
  11. ' 4. ButtonIndexClicked  'get the button index clicked, assuming base 1 for first index
  12.  
  13. '1. Button Type common to all buttons
  14. TYPE ButtonType
  15.     X AS INTEGER
  16.     Y AS INTEGER
  17.     W AS INTEGER
  18.     H AS INTEGER
  19.     FC AS _UNSIGNED LONG 'fore color is the color of anything printed
  20.     BC AS _UNSIGNED LONG 'back color  is the color of button
  21.     L AS STRING 'label
  22.     IMG AS LONG 'image handle
  23.     O AS INTEGER 'O stands for On or Off reveal string/img of button function or keep hidden
  24.  
  25. CONST xmax = 800, ymax = 300, boxSize = 50, sbc = &HFF005500, sfc = &HFFAAAADD 'screen stuff
  26. CONST xoffLetter = (boxSize - 8) / 2, yoffLetter = (boxSize - 16) / 2 ' for letters in box
  27. SCREEN _NEWIMAGE(xmax, ymax, 32)
  28. _SCREENMOVE 360, 60
  29. REDIM SHARED Btn(1 TO 1) AS ButtonType, nBtns 'so setup can set values to these globals
  30. REDIM SHARED shuffle(1 TO 1) AS STRING 'container of letter pairs to shuffle and distrbute before each round
  31. DIM SHARED nRevealed
  32. DIM i, s$, b1Index, b2Index, tStart!, clickCnt
  33.  
  34. COLOR sfc, sbc: CLS
  35. setUpGame
  36.     tStart! = TIMER(.001)
  37.     initRound
  38.     updateScreen
  39.     DO
  40.         i = ButtonIndexClicked
  41.         IF i THEN 'reveals, click counts only count if they are revealing
  42.             IF b1Index = 0 THEN 'first reveal box
  43.                 IF Btn(i).O <> -1 THEN b1Index = i: Btn(i).O = -1: clickCnt = clickCnt + 1
  44.             ELSE '2nd reveal box
  45.                 IF Btn(i).O <> -1 THEN b2Index = i: Btn(i).O = -1: clickCnt = clickCnt + 1
  46.             END IF
  47.             updateScreen
  48.         END IF
  49.         IF b2Index <> 0 THEN 'check pair, if they are a matched pair leave them revealed
  50.             IF ABS(ASC(Btn(b1Index).L) - ASC(Btn(b2Index).L)) <> 13 THEN 'no match
  51.                 _DELAY 1
  52.                 Btn(b1Index).O = 0: Btn(b2Index).O = 0
  53.                 nRevealed = nRevealed - 2 'when complete = number of squares then done
  54.                 updateScreen
  55.             END IF
  56.             b1Index = 0: b2Index = 0 'clear box clicks
  57.         END IF
  58.         _LIMIT 60
  59.     LOOP UNTIL nRevealed = nBtns
  60.     s$ = "Completed in" + STR$(INT(TIMER(.001) - tStart!)) + " secs and" + STR$(clickCnt) + " clicks."
  61.     LOCATE 3, (xmax / 8 - LEN(s$)) / 2: PRINT s$
  62.     _DELAY 7
  63.  
  64. SUB updateScreen
  65.     DIM i
  66.     LOCATE 15, 12: PRINT "Letter Pairs to Match:  A   B   C   D   E   F   G   H   I   J   K   L   M"
  67.     LOCATE 16, 12: PRINT "                 with:  N   O   P   Q   R   S   T   U   V   W   X   Y   Z"
  68.     nRevealed = 0 '              (shared) detect how many boxes are revealed
  69.     FOR i = 1 TO nBtns
  70.         DrawButton (i)
  71.         IF Btn(i).O THEN nRevealed = nRevealed + 1
  72.     NEXT
  73.  
  74. SUB initRound 'reassign letters and hide them all
  75.     DIM i, r
  76.     FOR i = nBtns TO 2 STEP -1 ' shuffle stuff in array
  77.         r = INT(i * RND) + 1
  78.         SWAP shuffle(i), shuffle(r)
  79.     NEXT
  80.     FOR i = 1 TO nBtns '       reset or reassign values
  81.         Btn(i).L = shuffle(i): Btn(i).O = 0
  82.     NEXT
  83.  
  84. SUB setUpGame
  85.     DIM i '(main) CONST xmax = 800, ymax = 300, boxSize = 50
  86.  
  87.     CONST xBoxes = 13, yBoxes = 2 '          Board N x M  boxes across, boxes down
  88.     'CONST boxSize = 10                '     Screen drawing topleft box locations
  89.     CONST spacer = 10 '                       for XY calc
  90.     LayoutButtons 0, 0, xmax, ymax, boxSize, boxSize, xBoxes, yBoxes, spacer, &HFFFFCCAA, &HFF000088
  91.     REDIM shuffle(1 TO nBtns) AS STRING ' load shuffle array for shuffling later (shared)
  92.     CONST letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  93.     FOR i = 1 TO nBtns
  94.         shuffle(i) = MID$(letters, i, 1)
  95.     NEXT
  96.  
  97. '2. Button draw for the index of an array Btn() of ButtonType's, assuming standard default font
  98. SUB DrawButton (index AS INTEGER)
  99.     DIM dc AS _UNSIGNED LONG, dbc AS _UNSIGNED LONG, ox, oy, s$
  100.     LINE (Btn(index).X, Btn(index).Y)-STEP(Btn(index).W, Btn(index).H), &HFF000000, BF
  101.     LINE (Btn(index).X, Btn(index).Y)-STEP(Btn(index).W - 3, Btn(index).H - 3), &HFFFFFFFF, BF
  102.     LINE (Btn(index).X + 1, Btn(index).Y + 1)-STEP(Btn(index).W - 3, Btn(index).H - 3), Btn(index).BC, BF
  103.     IF Btn(index).O THEN
  104.         IF 8 * LEN(Btn(index).L) > Btn(index).W - 4 THEN 'string is too long for button
  105.             s$ = MID$(Btn(index).L, 1, INT((Btn(index).W - 4) / 8)) 'fit part of string into button
  106.             ox = 2
  107.         ELSE
  108.             s$ = Btn(index).L: ox = (Btn(index).W - 8 * LEN(Btn(index).L)) \ 2
  109.         END IF
  110.         oy = (Btn(index).H - 16) \ 2
  111.         COLOR &HFF000000, &H0
  112.         _PRINTSTRING (Btn(index).X + ox - 1, Btn(index).Y + oy - 1), s$
  113.         COLOR Btn(index).FC
  114.         _PRINTSTRING (Btn(index).X + ox, Btn(index).Y + oy), s$
  115.         COLOR dc, dbc
  116.     END IF
  117.  
  118. ' 3. Layout buttons
  119. ' this sub will setup button locations for shared Btn() as ButtonType with first button index = 1
  120. ' also shared is nBtns whic will set/reset here
  121. SUB LayoutButtons (areaX AS INTEGER, areaY AS INTEGER, areaW AS INTEGER, areaH AS INTEGER, btnW, btnH,_
  122.     BtnsAcross, BtnsDown, spacer, Fore as _unsigned long, Back as _unsigned long)
  123.     DIM xoffset, yoffset, xx, yy, xSide, ySide, i
  124.     nBtns = BtnsAcross * BtnsDown '               Total btns (shared) in main declares section
  125.     REDIM Btn(1 TO nBtns) AS ButtonType '     ready to rec data (shared) in main declares section
  126.     xoffset = INT((areaW - btnW * BtnsAcross - spacer * (BtnsAcross - 1)) / 2) + areaX
  127.     yoffset = INT((areaH - btnH * BtnsDown - spacer * (BtnsDown - 1)) / 2) + areaY
  128.     xSide = btnW + spacer: ySide = btnH + spacer
  129.     FOR yy = 1 TO BtnsDown '                    set screen XY locations for all boxes
  130.         FOR xx = 1 TO BtnsAcross
  131.             i = i + 1
  132.             Btn(i).X = xoffset + (xx - 1) * xSide
  133.             Btn(i).Y = yoffset + (yy - 1) * ySide
  134.             Btn(i).W = btnW
  135.             Btn(i).H = btnH
  136.             Btn(i).FC = Fore
  137.             Btn(i).BC = Back
  138.         NEXT
  139.     NEXT
  140.  
  141. '4. Button Index Clicked
  142. FUNCTION ButtonIndexClicked
  143.     DIM m, mx, my, mb, i
  144.     mb = _MOUSEBUTTON(1) '            left button down
  145.     IF mb THEN '                      get last place mouse button was down
  146.         WHILE mb '                    wait for mouse button release as a "click"
  147.             m = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  148.         WEND
  149.         FOR i = 1 TO nBtns '         now find which box was clicked
  150.             IF mx > Btn(i).X AND mx < Btn(i).X + Btn(i).W THEN
  151.                 IF my > Btn(i).Y AND my < Btn(i).Y + Btn(i).H THEN
  152.                     ButtonIndexClicked = i: EXIT FUNCTION
  153.                 END IF
  154.             END IF
  155.         NEXT
  156.     END IF
  157.  

I really like how easy it is to get the button that was clicked with this code. I also have button layout almost completely automatic on AI with this new set. As you can see I plan to include images for buttons.
Title: Re: Letter Memory
Post by: bplus on July 24, 2019, 07:22:23 pm
Relatively easy to modify for a Word Matching Game. Here I used QB64 Keywords, symbols and other associated with Basic for 5 X 6 board of matches to make.

Because the matches make more sense, the game plays faster <200 secs for more pairs:
Code: QB64: [Select]
  1. DEFINT A-Z
  2. _TITLE "Word Memory Game" '  by bplus started 2019-07-24
  3. 'This is to extend Memory Series to words and test further Button tools.
  4. 'Along with testing button tools there is an experiment here to see if 2 word pairs that make sense
  5. 'are easier to remember than match A with N and Z with M..., rather arbitrary pairings we did in last game.
  6.  
  7. REM +inder: Button Memory Game
  8. ' The goal here is 2 Fold:
  9. '   Broaden the Memory Game series to more than letters,
  10. '   And develop some potential button library procedures.
  11. ' 1. Button Type
  12. ' 2. Button Draw
  13. ' 3. Buttons Layout  'setup a whole keypad of buttons, assuming base 1 for first index
  14. ' 4. ButtonIndexClicked  'get the button index clicked, assuming base 1 for first index
  15.  
  16. ' ============== Instructions: ========================================================
  17. 'This game uses QB64 keywords or symbols that have complementary word or symbol.
  18. 'Some are obvious no brainers like WHILE is paired with WEND, ( with ) and IF with THEN.
  19. 'Some might might not occur to you, eg I have DIM and AS matched up, see data statements below.
  20.  
  21.  
  22. '1. Button Type common to all buttons
  23. TYPE ButtonType
  24.     X AS INTEGER
  25.     Y AS INTEGER
  26.     W AS INTEGER
  27.     H AS INTEGER
  28.     FC AS _UNSIGNED LONG 'fore color is the color of anything printed
  29.     BC AS _UNSIGNED LONG 'back color  is the color of button
  30.     L AS STRING 'label
  31.     IMG AS LONG 'image handle
  32.     O AS INTEGER 'O stands for On or Off reveal string/img of button function or keep hidden
  33.  
  34. CONST xmax = 800, ymax = 500, sbc = &HFF005500, sfc = &HFFAAAADD 'screen stuff
  35. SCREEN _NEWIMAGE(xmax, ymax, 32)
  36. _SCREENMOVE 360, 60
  37. REDIM SHARED Btn(1 TO 1) AS ButtonType, nBtns 'so setup can set values to these globals
  38. REDIM SHARED shuffle(1 TO 1) AS STRING 'container of strings from data
  39. DIM SHARED nRevealed
  40. DIM i, s$, b1Index, b2Index, tStart!, clickCnt
  41.  
  42. COLOR sfc, sbc: CLS
  43. setUpGame
  44.     tStart! = TIMER(.001)
  45.     initRound
  46.     updateScreen
  47.     DO
  48.         i = ButtonIndexClicked
  49.         IF i THEN 'reveals, click counts only count if they are revealing
  50.             IF b1Index = 0 THEN 'first reveal box
  51.                 IF Btn(i).O <> -1 THEN b1Index = i: Btn(i).O = -1: clickCnt = clickCnt + 1
  52.             ELSE '2nd reveal box
  53.                 IF Btn(i).O <> -1 THEN b2Index = i: Btn(i).O = -1: clickCnt = clickCnt + 1
  54.             END IF
  55.             updateScreen
  56.         END IF
  57.         IF b2Index <> 0 THEN 'check pair, if they are a matched pair leave them revealed
  58.             IF Match(Btn(b1Index).L, Btn(b2Index).L) = 0 THEN 'no match
  59.                 _DELAY 1
  60.                 Btn(b1Index).O = 0: Btn(b2Index).O = 0
  61.                 nRevealed = nRevealed - 2 'when complete = number of squares then done
  62.                 updateScreen
  63.             END IF
  64.             b1Index = 0: b2Index = 0 'clear box clicks
  65.         END IF
  66.         _LIMIT 60
  67.     LOOP UNTIL nRevealed = nBtns
  68.     s$ = "Completed in" + STR$(INT(TIMER(.001) - tStart!)) + " secs and" + STR$(clickCnt) + " clicks."
  69.     LOCATE 3, (xmax / 8 - LEN(s$)) / 2: PRINT s$
  70.     _DELAY 7
  71.  
  72. matchData:
  73. DATA "IF THEN","DO LOOP","WHILE WEND","( )","SUB FUNCTION","SELECT CASE","OPTION _EXPLICIT","FOR NEXT"
  74. DATA "INPUT OUTPUT","X Y","LEFT$ RIGHT$","DIM AS","HELLO WORLD","CSRLIN POS","SIN COS"
  75.  
  76. FUNCTION Match (s1$, s2$)
  77.     DIM i, pair$
  78.     RESTORE matchData
  79.     FOR i = 1 TO 15
  80.         READ pair$:
  81.         IF leftOf$(pair$, " ") = s1$ THEN
  82.             IF rightOf$(pair$, " ") = s2$ THEN Match = -1: EXIT FUNCTION
  83.         ELSE
  84.             IF leftOf$(pair$, " ") = s2$ THEN
  85.                 IF rightOf$(pair$, " ") = s1$ THEN Match = -1: EXIT FUNCTION
  86.             END IF
  87.         END IF
  88.     NEXT
  89.  
  90. SUB updateScreen
  91.     DIM i
  92.     CLS: nRevealed = 0 '              (shared) detect how many boxes are revealed
  93.     FOR i = 1 TO nBtns
  94.         DrawButton (i)
  95.         IF Btn(i).O THEN nRevealed = nRevealed + 1
  96.     NEXT
  97.  
  98. SUB initRound 'reassign letters and hide them all
  99.     DIM i, r
  100.     FOR i = nBtns TO 2 STEP -1 ' shuffle stuff in array
  101.         r = INT(i * RND) + 1
  102.         SWAP shuffle(i), shuffle(r)
  103.     NEXT
  104.     FOR i = 1 TO nBtns '       reset or reassign values
  105.         Btn(i).L = shuffle(i): Btn(i).O = 0
  106.     NEXT
  107.  
  108. SUB setUpGame
  109.     DIM i, pair$ '(main) CONST xmax = 800, ymax = 300, boxSize = 50
  110.     CONST xBtns = 5, yBtns = 6 ' Board N x M  across, down
  111.     CONST spacer = 10 ' space between buttons VVVV sets SHARED nBtns needed in lines after call
  112.     LayoutButtons 0, 0, xmax, ymax, 100, 50, xBtns, yBtns, spacer, &HFFAAAAFF, &HFF000088
  113.     REDIM shuffle(1 TO nBtns) AS STRING ' load shuffle array for shuffling later (SHARED)
  114.     FOR i = 1 TO nBtns STEP 2 'load shuffle with words/symbol pairs
  115.         READ pair$
  116.         shuffle(i) = leftOf$(pair$, " "): shuffle(i + 1) = rightOf$(pair$, " ")
  117.     NEXT
  118.  
  119. '2. Button draw for the index of an array Btn() of ButtonType's, assuming standard default font
  120. SUB DrawButton (index AS INTEGER)
  121.     DIM dc AS _UNSIGNED LONG, dbc AS _UNSIGNED LONG, ox, oy, s$
  122.     LINE (Btn(index).X, Btn(index).Y)-STEP(Btn(index).W, Btn(index).H), &HFF000000, BF
  123.     LINE (Btn(index).X, Btn(index).Y)-STEP(Btn(index).W - 3, Btn(index).H - 3), &HFFFFFFFF, BF
  124.     LINE (Btn(index).X + 1, Btn(index).Y + 1)-STEP(Btn(index).W - 3, Btn(index).H - 3), Btn(index).BC, BF
  125.     IF Btn(index).O THEN
  126.         IF 8 * LEN(Btn(index).L) > Btn(index).W - 4 THEN 'string is too long for button
  127.             s$ = MID$(Btn(index).L, 1, INT((Btn(index).W - 4) / 8)) 'fit part of string into button
  128.             ox = 2
  129.         ELSE
  130.             s$ = Btn(index).L: ox = (Btn(index).W - 8 * LEN(Btn(index).L)) \ 2
  131.         END IF
  132.         oy = (Btn(index).H - 16) \ 2
  133.         COLOR &HFF000000, &H0
  134.         _PRINTSTRING (Btn(index).X + ox - 1, Btn(index).Y + oy - 1), s$
  135.         COLOR Btn(index).FC
  136.         _PRINTSTRING (Btn(index).X + ox, Btn(index).Y + oy), s$
  137.         COLOR dc, dbc
  138.     END IF
  139.  
  140. ' 3. Layout buttons
  141. ' this sub will setup button locations for shared Btn() as ButtonType with first button index = 1
  142. ' also shared is nBtns whic will set/reset here
  143. SUB LayoutButtons (areaX AS INTEGER, areaY AS INTEGER, areaW AS INTEGER, areaH AS INTEGER, btnW, btnH,_
  144.     BtnsAcross, BtnsDown, spacer, Fore AS _UNSIGNED LONG, Back AS _UNSIGNED LONG)
  145.     DIM xoffset, yoffset, xx, yy, xSide, ySide, i
  146.     nBtns = BtnsAcross * BtnsDown '               Total btns (shared) in main declares section
  147.     REDIM Btn(1 TO nBtns) AS ButtonType '     ready to rec data (shared) in main declares section
  148.     xoffset = INT((areaW - btnW * BtnsAcross - spacer * (BtnsAcross - 1)) / 2) + areaX
  149.     yoffset = INT((areaH - btnH * BtnsDown - spacer * (BtnsDown - 1)) / 2) + areaY
  150.     xSide = btnW + spacer: ySide = btnH + spacer
  151.     FOR yy = 1 TO BtnsDown '                    set screen XY locations for all boxes
  152.         FOR xx = 1 TO BtnsAcross
  153.             i = i + 1
  154.             Btn(i).X = xoffset + (xx - 1) * xSide
  155.             Btn(i).Y = yoffset + (yy - 1) * ySide
  156.             Btn(i).W = btnW
  157.             Btn(i).H = btnH
  158.             Btn(i).FC = Fore
  159.             Btn(i).BC = Back
  160.         NEXT
  161.     NEXT
  162.  
  163. '4. Button Index Clicked
  164. FUNCTION ButtonIndexClicked
  165.     DIM m, mx, my, mb, i
  166.     mb = _MOUSEBUTTON(1) '            left button down
  167.     IF mb THEN '                      get last place mouse button was down
  168.         WHILE mb '                    wait for mouse button release as a "click"
  169.             m = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  170.         WEND
  171.         FOR i = 1 TO nBtns '         now find which box was clicked
  172.             IF mx > Btn(i).X AND mx < Btn(i).X + Btn(i).W THEN
  173.                 IF my > Btn(i).Y AND my < Btn(i).Y + Btn(i).H THEN
  174.                     ButtonIndexClicked = i: EXIT FUNCTION
  175.                 END IF
  176.             END IF
  177.         NEXT
  178.     END IF
  179.  
  180. 'old tools from toolbox
  181. FUNCTION leftOf$ (source$, of$)
  182.     IF INSTR(source$, of$) > 0 THEN leftOf$ = MID$(source$, 1, INSTR(source$, of$) - 1)
  183.  
  184. FUNCTION rightOf$ (source$, of$)
  185.     IF INSTR(source$, of$) > 0 THEN rightOf$ = MID$(source$, INSTR(source$, of$) + LEN(of$))
  186.  
  187.  

  [ This attachment cannot be displayed inline in 'Print Page' view ]  
Title: Re: Letter Memory
Post by: bplus on July 24, 2019, 10:26:40 pm
And now Johnno some Akkadian images, Akkadian replaced Sumerian writing with a more uniform and abstract cuneiform.

This is a simple match up of images but Akkadian makes it fun because they all sort of look the same, at first :-))

Code: QB64: [Select]
  1. DEFINT A-Z
  2. _TITLE "Image Memory Game" '  by bplus started 2019-07-24
  3. 'This is to extend Memory Series to images and test further Button tools.
  4.  
  5. ' A VERY BIG THANKS to Steve McNeill !
  6. ' for sharing code to save an image section to a .png file.
  7. ' I was working from a sheet of 40 figures that would not
  8. ' align to any one center and rectangle size. I ended up having to
  9. ' take snapshots of the sections to load the images file by file.
  10.  
  11. REM +inder: Button Memory Game
  12. ' The goal here is 2 Fold:
  13. '   Broaden the Memory Game series to more than letters,
  14. '   And develop some potential button library procedures.
  15. ' 1. Button Type
  16. ' 2. Button Draw
  17. ' 3. Buttons Layout  'setup a whole keypad of buttons, assuming base 1 for first index
  18. ' 4. ButtonIndexClicked  'get the button index clicked, assuming base 1 for first index
  19.  
  20. ' ============== Instructions: ========================================================
  21. ' This game uses images from the Akkadian language. Just keep clicking to match up the
  22. ' images until all the buttons have been exposed.
  23.  
  24. '1. Button Type common to all buttons
  25. TYPE ButtonType
  26.     X AS INTEGER
  27.     Y AS INTEGER
  28.     W AS INTEGER
  29.     H AS INTEGER
  30.     FC AS _UNSIGNED LONG 'fore color is the color of anything printed
  31.     BC AS _UNSIGNED LONG 'back color  is the color of button
  32.     L AS STRING 'label
  33.     IMG AS LONG 'image handle
  34.     O AS INTEGER 'O stands for On or Off reveal string/img of button function or keep hidden
  35.  
  36. CONST xmax = 800, ymax = 600, sbc = &HFF005500, sfc = &HFFAAAADD 'screen stuff
  37. SCREEN _NEWIMAGE(xmax, ymax, 32)
  38. _SCREENMOVE 360, 60
  39. REDIM SHARED Btn(1 TO 1) AS ButtonType, nBtns 'so setup can set values to these globals
  40. REDIM SHARED shuffle(1 TO 1) AS LONG 'container of strings from data
  41. DIM SHARED nRevealed
  42. DIM i, s$, b1Index, b2Index, tStart!, clickCnt
  43.  
  44. COLOR sfc, sbc: CLS
  45. setUpGame
  46.     tStart! = TIMER(.001)
  47.     initRound
  48.     updateScreen
  49.     DO
  50.         i = ButtonIndexClicked
  51.         IF i THEN 'reveals, click counts only count if they are revealing
  52.             IF b1Index = 0 THEN 'first reveal box
  53.                 IF Btn(i).O <> -1 THEN b1Index = i: Btn(i).O = -1: clickCnt = clickCnt + 1
  54.             ELSE '2nd reveal box
  55.                 IF Btn(i).O <> -1 THEN b2Index = i: Btn(i).O = -1: clickCnt = clickCnt + 1
  56.             END IF
  57.             updateScreen
  58.         END IF
  59.         IF b2Index <> 0 THEN 'check pair, if they are a matched pair leave them revealed
  60.             IF Btn(b1Index).IMG <> Btn(b2Index).IMG THEN 'no match
  61.                 _DELAY 1
  62.                 Btn(b1Index).O = 0: Btn(b2Index).O = 0
  63.                 nRevealed = nRevealed - 2 'when complete = number of squares then done
  64.                 updateScreen
  65.             END IF
  66.             b1Index = 0: b2Index = 0 'clear box clicks
  67.         END IF
  68.         _LIMIT 60
  69.     LOOP UNTIL nRevealed = nBtns
  70.     s$ = "Completed in" + STR$(INT(TIMER(.001) - tStart!)) + " secs and" + STR$(clickCnt) + " clicks."
  71.     LOCATE 3, (xmax / 8 - LEN(s$)) / 2: PRINT s$
  72.     _DELAY 10
  73.  
  74. SUB updateScreen
  75.     DIM i
  76.     CLS: nRevealed = 0 '              (shared) detect how many boxes are revealed
  77.     FOR i = 1 TO nBtns
  78.         DrawButton (i)
  79.         IF Btn(i).O THEN nRevealed = nRevealed + 1
  80.     NEXT
  81.  
  82. SUB initRound 'reassign letters and hide them all
  83.     DIM i, r
  84.     FOR i = nBtns TO 2 STEP -1 ' shuffle stuff in array
  85.         r = INT(i * RND) + 1
  86.         SWAP shuffle(i), shuffle(r)
  87.     NEXT
  88.     FOR i = 1 TO nBtns '       reset or reassign values
  89.         Btn(i).IMG = shuffle(i): Btn(i).O = 0
  90.     NEXT
  91.  
  92. SUB setUpGame
  93.     DIM i, ak& '(main) CONST xmax = 800, ymax = 600
  94.     CONST xBtns = 6, yBtns = 4 ' Board N x M  across, down
  95.     CONST spacer = 10 ' space between buttons VVVV sets SHARED nBtns needed in lines after call
  96.     LayoutButtons 0, 0, xmax, ymax, 100, 70, xBtns, yBtns, spacer, &HFFAAAAFF, &HFFFF8844
  97.     REDIM shuffle(1 TO nBtns) AS LONG ' load shuffle array for shuffling later (SHARED)
  98.     FOR i = 1 TO nBtns STEP 2 'load shuffle with words/symbol pairs
  99.         ak& = _LOADIMAGE("akk" + _TRIM$(STR$((i + 1) / 2)) + ".png")
  100.         IF ak& >= -1 THEN 'failed to get image(s)
  101.             CLS
  102.             PRINT "Failed to load image * akk" + _TRIM$(STR$((i + 1) / 2)) + ".png *, Sorry Goodbye!"
  103.             _DISPLAY
  104.             _DELAY 7
  105.             SYSTEM
  106.         END IF
  107.         shuffle(i) = ak&
  108.         shuffle(i + 1) = ak&
  109.     NEXT
  110.  
  111. '2. Button draw for the index of an array Btn() of ButtonType's, assuming standard default font
  112. SUB DrawButton (index AS INTEGER)
  113.     DIM dc AS _UNSIGNED LONG, dbc AS _UNSIGNED LONG, ox, oy, s$
  114.     LINE (Btn(index).X, Btn(index).Y)-STEP(Btn(index).W, Btn(index).H), &HFF000000, BF
  115.     LINE (Btn(index).X, Btn(index).Y)-STEP(Btn(index).W - 3, Btn(index).H - 3), &HFFFFFFFF, BF
  116.     LINE (Btn(index).X + 1, Btn(index).Y + 1)-STEP(Btn(index).W - 3, Btn(index).H - 3), Btn(index).BC, BF
  117.     IF Btn(index).O THEN
  118.         IF Btn(index).IMG THEN
  119.             _PUTIMAGE (Btn(index).X + 8, Btn(index).Y + 8)-STEP(Btn(index).W - 17, Btn(index).H - 17), Btn(index).IMG, 0
  120.         END IF
  121.         IF 8 * LEN(Btn(index).L) > Btn(index).W - 4 THEN 'string is too long for button
  122.             s$ = MID$(Btn(index).L, 1, INT((Btn(index).W - 4) / 8)) 'fit part of string into button
  123.             ox = 2
  124.         ELSE
  125.             s$ = Btn(index).L: ox = (Btn(index).W - 8 * LEN(Btn(index).L)) \ 2
  126.         END IF
  127.         oy = (Btn(index).H - 16) \ 2
  128.         COLOR &HFF000000, &H0
  129.         _PRINTSTRING (Btn(index).X + ox - 1, Btn(index).Y + oy - 1), s$
  130.         COLOR Btn(index).FC
  131.         _PRINTSTRING (Btn(index).X + ox, Btn(index).Y + oy), s$
  132.         COLOR dc, dbc
  133.     END IF
  134.  
  135. ' 3. Layout buttons
  136. ' this sub will setup button locations for shared Btn() as ButtonType with first button index = 1
  137. ' also shared is nBtns whic will set/reset here
  138. SUB LayoutButtons (areaX AS INTEGER, areaY AS INTEGER, areaW AS INTEGER, areaH AS INTEGER, btnW, btnH,_
  139.     BtnsAcross, BtnsDown, spacer, Fore AS _UNSIGNED LONG, Back AS _UNSIGNED LONG)
  140.     DIM xoffset, yoffset, xx, yy, xSide, ySide, i
  141.     nBtns = BtnsAcross * BtnsDown '               Total btns (shared) in main declares section
  142.     REDIM Btn(1 TO nBtns) AS ButtonType '     ready to rec data (shared) in main declares section
  143.     xoffset = INT((areaW - btnW * BtnsAcross - spacer * (BtnsAcross - 1)) / 2) + areaX
  144.     yoffset = INT((areaH - btnH * BtnsDown - spacer * (BtnsDown - 1)) / 2) + areaY
  145.     xSide = btnW + spacer: ySide = btnH + spacer
  146.     FOR yy = 1 TO BtnsDown '                    set screen XY locations for all boxes
  147.         FOR xx = 1 TO BtnsAcross
  148.             i = i + 1
  149.             Btn(i).X = xoffset + (xx - 1) * xSide
  150.             Btn(i).Y = yoffset + (yy - 1) * ySide
  151.             Btn(i).W = btnW
  152.             Btn(i).H = btnH
  153.             Btn(i).FC = Fore
  154.             Btn(i).BC = Back
  155.         NEXT
  156.     NEXT
  157.  
  158. '4. Button Index Clicked
  159. FUNCTION ButtonIndexClicked
  160.     DIM m, mx, my, mb, i
  161.     mb = _MOUSEBUTTON(1) '            left button down
  162.     IF mb THEN '                      get last place mouse button was down
  163.         WHILE mb '                    wait for mouse button release as a "click"
  164.             m = _MOUSEINPUT: mb = _MOUSEBUTTON(1): mx = _MOUSEX: my = _MOUSEY
  165.         WEND
  166.         FOR i = 1 TO nBtns '         now find which box was clicked
  167.             IF mx > Btn(i).X AND mx < Btn(i).X + Btn(i).W THEN
  168.                 IF my > Btn(i).Y AND my < Btn(i).Y + Btn(i).H THEN
  169.                     ButtonIndexClicked = i: EXIT FUNCTION
  170.                 END IF
  171.             END IF
  172.         NEXT
  173.     END IF
  174.  

 


oops! I just noticed something in screen shot. :(

EDIT: yeah the images needed frames, so they still looked like buttons too.