Author Topic: TriQuad Puzzle  (Read 4761 times)

0 Members and 1 Guest are viewing this topic.

Offline bplus

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

 
TriQuad Puzzle.PNG

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: TriQuad Puzzle
« Reply #1 on: October 14, 2019, 02:21:04 pm »
I remember a puzzle very similar to this many years ago... It was a 'brain drain' then as well... It's just gone 5am and the 'brain drain' is more pronounced... Made even worse by no coffee yet... lol

I managed to work out a 3x3 puzzle in under 2 minutes.... I know! I'm as surprised as you are!

I'm not big on games where I have to 'over think', but THIS one, I like... Great job. Well done! :D
Logic is the beginning of wisdom.

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: TriQuad Puzzle
« Reply #2 on: October 14, 2019, 05:25:28 pm »
Thanks Johnno, yeah with this puzzle you can choose the level of difficulty by choosing number of squares per side.

And it should be familiar from Rick3137 post long ago at Naalaa.

Offline Ashish

  • Forum Resident
  • Posts: 630
  • Never Give Up!
    • View Profile
Re: TriQuad Puzzle
« Reply #3 on: October 16, 2019, 12:12:14 pm »
Good game! What does "[B+=MGA]" means in your code?
if (Me.success) {Me.improve()} else {Me.tryAgain()}


My Projects - https://github.com/AshishKingdom?tab=repositories
OpenGL tutorials - https://ashishkingdom.github.io/OpenGL-Tutorials

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: TriQuad Puzzle
« Reply #4 on: October 16, 2019, 12:35:55 pm »
Good game! What does "[B+=MGA]" means in your code?

It means at SmallBASIC forum I used my initials as my Avatar name, MGA.

When I signed on at BP.org, I decided to change my avatar name to B+ then at JB B+, + was not allowed so it became bplus there... so [MGA = B+ = bplus] M is for Mark.

Also at JB they put all labels between [ ]  so that's where the square brackets came from :)

Offline johnno56

  • Forum Resident
  • Posts: 1270
  • Live long and prosper.
    • View Profile
Re: TriQuad Puzzle
« Reply #5 on: October 16, 2019, 04:37:02 pm »
Would it not have been simpler to use just, "M"? Like in "Men in Black" and "James Bond...."? lol
Logic is the beginning of wisdom.