Author Topic: MARBLE RING TRINKET  (Read 3003 times)

0 Members and 1 Guest are viewing this topic.

Offline Rubidium

  • Newbie
  • Posts: 10
    • View Profile
MARBLE RING TRINKET
« on: October 29, 2020, 07:11:52 pm »
Just finished making this lil toy~

It's a marble sliding ring puzzle.

 
Capture.PNG


Code: QB64: [Select]
  1. 'RING-PUZZLE-TRINKET
  2. SCREEN _NEWIMAGE(700, 400, 32)
  3. DIM col&(20) 'marble colors
  4. DIM LMAP(30) 'Full marble layout
  5. DIM KMAP(2, 20) 'Solution layout
  6. DIM RINGMAP(2, 20) 'RING layout
  7.  
  8. '///////////SOUNDS////////////////////////////////
  9. snda& = _SNDOPEN("SFX/rotate.wav", "sync")
  10. sndb& = _SNDOPEN("SFX/final.wav", "sync")
  11. sndc& = _SNDOPEN("SFX/correct.wav", "sync")
  12. sndd& = _SNDOPEN("SFX/iMAC.wav", "sync")
  13. snde& = _SNDOPEN("SFX/error.wav", "sync")
  14. _SNDPLAY sndd& 'on initial only
  15.  
  16. '///////////CONSTANTS/////////////////////////////
  17. r = 140 'ring radius
  18. mr = 15 'marble radius
  19. n = 6 'number of marbles PER RING *!make this even
  20. q = (_PI(1) / n) 'half angle between marbles
  21. d = r * COS(q) 'ring center offset from CENTRIX
  22. CENTRIX = 350 'x axis center of RING SYSTEM
  23. CENTRIY = 200 'y axis center of RING SYSTEM
  24. mt = (2 * n) - 2 'marble total
  25. BLK& = _RGB(0, 0, 0)
  26. WHT& = _RGB(255, 255, 255)
  27.  
  28.  
  29. '//////////ASSIGN COLOR TO MARBLES////////////////
  30. FOR i = 1 TO mt
  31.     w = (i / mt) - (1 / mt)
  32.     GOSUB w_rainbow 'Linear Rainbow mixer using "w" input
  33.     col&(i) = colr& 'color of marble ID
  34.     LMAP(i) = i 'Initialize MARBLE ID LOCATIONS
  35.  
  36. GOSUB LOADA
  37. GOSUB LOADB
  38.  
  39. 'SET SOLUTION KMAP AS INITIAL LAYOUT
  40. FOR i = 1 TO n
  41.     KMAP(1, i) = i
  42. FOR i = 1 TO n
  43.     KMAP(2, i) = RINGMAP(2, i)
  44.  
  45.  
  46. '/////////SCRAMBLE via RANDOM OPERATIONS///////
  47. DIFFICULTY = 5 'minimum number of moves needed to solve
  48. 'try 10,20,50,100!!!
  49. FOR k = 1 TO DIFFICULTY 'DIFFICULTY OF SCRAMBLE
  50.     scramble = INT(RND * 2)
  51.     IF scramble = 0 THEN GOSUB ARSWIRL
  52.     IF scramble = 1 THEN GOSUB BRSWIRL
  53.  
  54.  
  55. '//////////////INITIAL DISPLAY///////////////////////
  56. CIRCLE (CENTRIX - d, CENTRIY), r, _RGB(50, 100, 100)
  57. CIRCLE (CENTRIX + d, CENTRIY), r, _RGB(150, 100, 100)
  58. GOSUB LOADA
  59. GOSUB LOADB
  60.  
  61. FOR k = 1 TO 2 'RINGID
  62.     FOR i = 1 TO n 'number of marbles per ring
  63.         u = 0 - (_PI(1) * (i) / (.5 * n)) + q
  64.         marblex = r * COS(u)
  65.         marbley = r * SIN(u)
  66.         IF k = 1 THEN dd = d
  67.         IF k = 2 THEN dd = -d
  68.  
  69.         '////////////////DRAW MARBLES//////////////////////
  70.         CIRCLE (CENTRIX - dd + marblex, CENTRIY + marbley), mr, col&(RINGMAP(k, i))
  71.         PAINT (CENTRIX - dd + marblex, CENTRIY + marbley), col&(RINGMAP(k, i))
  72.         CIRCLE (CENTRIX - dd + marblex, CENTRIY + marbley), mr, WHT&
  73.  
  74.         '////////////////DRAW ARCS/////////////////////////
  75.         FOR s = 1 TO 3
  76.             CIRCLE (CENTRIX - dd + (marblex * .3), CENTRIY + (marbley * .3)), (mr * 3) + s, col&(KMAP(k, i)), ABS(u + .3), ABS(u - .3), 1
  77.         NEXT s
  78.  
  79.         COLOR BLK&, col&(RINGMAP(k, i))
  80.         IF RINGMAP(k, i) < 10 THEN P = 2 ELSE P = 6
  81.         _PRINTSTRING (CENTRIX - dd + marblex - P, CENTRIY + marbley - 5), _TRIM$(STR$(RINGMAP(k, i)))
  82.  
  83.         GOSUB DRAWLEDS
  84.     NEXT i
  85.  
  86. COLOR WHT&, BLK&
  87. LOCATE 1, 1, 1
  88. _SNDPLAY sndb&
  89. PRINT "READING DISCS..."
  90. FOR i = 1 TO 7
  91.     LOCATE 1, 17
  92.     IF (i MOD 2) THEN PRINT "Û" ELSE PRINT " "
  93.     _DELAY .5
  94.  
  95. LOCATE 1, 1
  96. _SNDPLAY snde&
  97. PRINT "ERROR DISC OUT OF SYNC!": _DELAY 2
  98. LOCATE 1, 1
  99. PRINT "MANUAL SYNC REQUIRED!  ": _DELAY 2
  100. LOCATE 1, 1
  101. PRINT "LEFT CLICK : counter-clockwise"
  102. PRINT "RIGHT CLICK: clockwise"
  103.  
  104.  
  105.  
  106.  
  107. 'MOUSE CAPTURE LOOP
  108.     z = _MOUSEINPUT
  109.     IF _MOUSEBUTTON(1) OR _MOUSEBUTTON(2) THEN 'click trigger
  110.         IF _MOUSEBUTTON(1) THEN RSWIRL = 1 'clockwise operation
  111.         IF _MOUSEBUTTON(2) THEN LSWIRL = 1 'counter-clockwise operation
  112.         DO 'clear out inputs
  113.             z = _MOUSEINPUT
  114.         LOOP UNTIL (_MOUSEBUTTON(2) = 0) AND (_MOUSEBUTTON(1) = 0)
  115.  
  116.         IF RSWIRL THEN dir = -.015: A = 0: B = -1
  117.         IF LSWIRL THEN dir = .015: A = 0: B = 1
  118.  
  119.         IF (_MOUSEX - CENTRIX) < 0 THEN RINGID = 1 ELSE RINGID = 2
  120.         GOSUB rotate
  121.  
  122.         GOSUB SHOWMAP 'show LEDS
  123.  
  124.         '//////////////////////ZOLVED///////////////////////////
  125.         win = 0 'count ON LEDS
  126.         FOR i = 1 TO n
  127.             FOR k = 1 TO 2
  128.                 IF RINGMAP(k, i) = KMAP(k, i) THEN win = win + 1
  129.             NEXT
  130.         NEXT
  131.         IF win = (2 * n) THEN GOTO final
  132.  
  133.     END IF
  134.  
  135. LOADA:
  136. FOR i = 1 TO n 'load marbles onto RING A
  137.     RINGMAP(1, i) = LMAP(i)
  138.  
  139. LOADB:
  140. FOR i = 1 TO n - 1 'load marbles onto RING B
  141.     j = i + (n / 2) 'n MUST BE EVEN! for this part to work
  142.     IF j > n THEN j = j - n
  143.     RINGMAP(2, j) = LMAP(n + i - 1)
  144. RINGMAP(2, (n / 2)) = LMAP(1)
  145.  
  146. DRAWLEDS:
  147. IF RINGMAP(k, i) = KMAP(k, i) THEN 'DRAW ON
  148.     CIRCLE (CENTRIX - dd + (marblex * .5), CENTRIY + (marbley * .5)), mr * .5, col&(KMAP(k, i)), , , 1
  149.     PAINT (CENTRIX - dd + (marblex * .5), CENTRIY + (marbley * .5)), col&(KMAP(k, i))
  150.     CIRCLE (CENTRIX - dd + (marblex * .5), CENTRIY + (marbley * .5)), mr * .5, WHT&, , , 1
  151. ELSE 'DRAW OFF
  152.     CIRCLE (CENTRIX - dd + (marblex * .5), CENTRIY + (marbley * .5)), mr * .5, BLK&, , , 1
  153.     PAINT (CENTRIX - dd + (marblex * .5), CENTRIY + (marbley * .5)), BLK&
  154.     CIRCLE (CENTRIX - dd + (marblex * .5), CENTRIY + (marbley * .5)), mr * .5, col&(KMAP(k, i)), , , 1
  155.  
  156. SHOWMAP: 'Just shows LEDS actually
  157. GOSUB LOADA
  158. GOSUB LOADB
  159.  
  160. FOR k = 1 TO 2
  161.     FOR i = 1 TO n
  162.         u = 0 - (_PI(1) * (i) / (.5 * n)) + q
  163.         marblex = r * COS(u)
  164.         marbley = r * SIN(u)
  165.  
  166.         IF k = 1 THEN dd = d
  167.         IF k = 2 THEN dd = -d
  168.  
  169.         GOSUB DRAWLEDS
  170.     NEXT i
  171.  
  172.  
  173. '///////////////RING ROTATION ANIMATION////////////////////////////
  174. rotate:
  175. _SNDPLAY snda&
  176.  
  177. IF RINGID = 1 THEN dd = d: GOSUB LOADA
  178. IF RINGID = 2 THEN dd = -d: GOSUB LOADB
  179.  
  180. FOR u = A TO B STEP dir
  181.     FOR i = 1 TO n '// erase former marble positions
  182.         LINE (CENTRIX - dd + marblex(i) - mr - 2, CENTRIY + marbley(i) - mr - 2)-(CENTRIX - dd + marblex(i) + mr + 2, CENTRIY + marbley(i) + mr + 2), BLK&, BF
  183.     NEXT i
  184.  
  185.     t = u * 2 * q 'update radian of rotation
  186.  
  187.     CIRCLE (CENTRIX - dd, CENTRIY), r, _RGB(100 - dd, 100, 100)
  188.     FOR i = 1 TO n '// draw marbles
  189.         marblex(i) = r * COS(t - (_PI(1) * i / (.5 * n)) + q)
  190.         marbley(i) = r * SIN(t - (_PI(1) * i / (.5 * n)) + q)
  191.  
  192.         COLOR BLK&, col&(RINGMAP(RINGID, i))
  193.         CIRCLE (CENTRIX - dd + marblex(i), CENTRIY + marbley(i)), mr, col&(RINGMAP(RINGID, i))
  194.         PAINT (CENTRIX - dd + marblex(i), CENTRIY + marbley(i)), col&(RINGMAP(RINGID, i))
  195.  
  196.         IF RINGMAP(RINGID, i) < 10 THEN P = 2: ELSE P = 6
  197.         _PRINTSTRING (CENTRIX - dd + marblex(i) - P, CENTRIY + marbley(i) - 5), _TRIM$(STR$(RINGMAP(RINGID, i)))
  198.         CIRCLE (CENTRIX - dd + marblex(i), CENTRIY + marbley(i)), mr, WHT&
  199.     NEXT i
  200.     _DELAY .02
  201. NEXT u 'animation complete
  202.  
  203. 'INDEX ROTATION OPERATION SELECTION
  204. IF RSWIRL AND RINGID = 1 THEN GOSUB ARSWIRL
  205. IF LSWIRL AND RINGID = 1 THEN GOSUB ALSWIRL
  206. IF RSWIRL AND RINGID = 2 THEN GOSUB BRSWIRL
  207. IF LSWIRL AND RINGID = 2 THEN GOSUB BLSWIRL
  208.  
  209.  
  210.  
  211. '///////////////FINAL ANIMATION////////////////////////////
  212. final:
  213. _SNDPLAY sndc&
  214. _DELAY 1.3
  215. _SNDPLAY sndb&
  216. CLS: PAINT (1, 1), _RGB(0, 0, 0)
  217. GOSUB LOADA
  218. GOSUB LOADB
  219. FOR u = 0 TO 1 STEP .015
  220.     FOR k = 1 TO 2
  221.         IF k = 1 THEN dd = d: tt = tq: l = 2
  222.         IF k = 2 THEN dd = -d: tt = -tq: l = -2
  223.  
  224.         CIRCLE (CENTRIX - dd - tt, CENTRIY), r, BLK&
  225.         FOR i = 1 TO n '// erase former marble positions
  226.             marblex(i) = r * COS((l * t) - (_PI(1) * i / (.5 * n)) + q)
  227.             marbley(i) = r * SIN((l * t) - (_PI(1) * i / (.5 * n)) + q)
  228.             LINE (CENTRIX - dd + marblex(i) - mr - 2 - tt, CENTRIY + marbley(i) - mr - 2)-(CENTRIX - dd + marblex(i) + mr + 2 - tt, CENTRIY + marbley(i) + mr + 2), BLK&, BF
  229.             LINE (CENTRIX - dd + (marblex(i) * .5) - (mr * .6) - tt, CENTRIY + (marbley(i) * .5) - (mr * .6))-(CENTRIX - dd + (marblex(i) * .5) + (mr * .6) - tt, CENTRIY + (marbley(i) * .5) + (mr * .6)), BLK&, BF
  230.         NEXT i
  231.  
  232.     NEXT k
  233.  
  234.     tq = tq + 1.3 'horizontal motion
  235.     t = -u * 2 * q 'update radian of rotation
  236.  
  237.  
  238.     FOR k = 1 TO 2
  239.         IF k = 1 THEN dd = d: tt = tq: l = 2
  240.         IF k = 2 THEN dd = -d: tt = -tq: l = -2
  241.  
  242.         CIRCLE (CENTRIX - dd - tt, CENTRIY), r, _RGB(100 - dd, 100, 100)
  243.         FOR i = 1 TO n '// draw marbles
  244.             marblex(i) = r * COS((l * t) - (_PI(1) * i / (.5 * n)) + q)
  245.             marbley(i) = r * SIN((l * t) - (_PI(1) * i / (.5 * n)) + q)
  246.  
  247.             COLOR BLK&, col&(KMAP(k, i))
  248.             CIRCLE (CENTRIX - dd + marblex(i) - tt, CENTRIY + marbley(i)), mr, col&(KMAP(k, i))
  249.             PAINT (CENTRIX - dd + marblex(i) - tt, CENTRIY + marbley(i)), col&(KMAP(k, i))
  250.  
  251.             IF RINGMAP(k, i) < 10 THEN P = 2: ELSE P = 6
  252.             _PRINTSTRING (CENTRIX - dd + marblex(i) - P - tt, CENTRIY + marbley(i) - 5), _TRIM$(STR$(KMAP(k, i)))
  253.             CIRCLE (CENTRIX - dd + marblex(i) - tt, CENTRIY + marbley(i)), mr, WHT&
  254.  
  255.             '////LEDS
  256.             CIRCLE (CENTRIX - dd + (marblex(i) * .5) - tt, CENTRIY + (marbley(i) * .5)), mr * .5, col&(KMAP(k, i)), , , 1
  257.             PAINT (CENTRIX - dd + (marblex(i) * .5) - tt, CENTRIY + (marbley(i) * .5)), col&(KMAP(k, i))
  258.             CIRCLE (CENTRIX - dd + (marblex(i) * .5) - tt, CENTRIY + (marbley(i) * .5)), mr * .5, WHT&, , , 1
  259.  
  260.         NEXT i
  261.     NEXT k
  262.     _DELAY .039
  263. COLOR _RGB(0, 200, 250), _RGB(0, 50, 100)
  264. _PRINTSTRING (CENTRIX - (6 * 8) - 3, CENTRIY), "DISCS SYNCED!"
  265.  
  266. '====================================================
  267. '==========-  SOLUTION FOUND END  -==================
  268. '====================================================
  269.  
  270.  
  271. '////////////////////////////////////////////////////
  272. '/////      INDEX ROTATION OPERATIONS           /////
  273. '////////////////////////////////////////////////////
  274. 'ROTATION OPERATION on LMAP SEGMENTS
  275.  
  276. ARSWIRL: 'CLOCKWISE on RING A
  277. temp = LMAP(n)
  278. FOR i = n TO 2 STEP -1
  279.     LMAP(i) = LMAP(i - 1)
  280. LMAP(1) = temp
  281. RSWIRL = 0
  282.  
  283. ALSWIRL: 'COUNTER-CLOCKWISE on RING A
  284. temp = LMAP(1)
  285. FOR i = 1 TO (n - 1) STEP 1
  286.     LMAP(i) = LMAP(i + 1)
  287. LMAP(n) = temp
  288. LSWIRL = 0
  289.  
  290. BRSWIRL: 'CLOCKWISE on RING B
  291. temp = LMAP(mt)
  292. FOR i = mt TO (n + 1) STEP -1
  293.     LMAP(i) = LMAP(i - 1)
  294. LMAP(n) = LMAP(1)
  295. LMAP(1) = temp
  296. RSWIRL = 0
  297.  
  298. BLSWIRL: 'COUNTER-CLOCKWISE on RING B
  299. temp = LMAP(n)
  300. FOR i = n TO (mt - 1) STEP 1
  301.     LMAP(i) = LMAP(i + 1)
  302. LMAP(mt) = LMAP(1)
  303. LMAP(1) = temp
  304. LSWIRL = 0
  305.  
  306.  
  307. '/////////////////////LINEAR RAINBOW////////////////////////////////////////////
  308. w_rainbow: 'converts single variable ru=(0 to 1) into a mixture blending from R to G to B
  309. t.col = INT(w * 1530) ' converts ru=(0,1) TO (0,1530)
  310. colr& = _RGB(0, 0, 0) 'default if ru out of range
  311. IF t.col >= (0 * 255) AND t.col < (1 * 255) THEN colr& = _RGB(255, t.col - (0 * 255), 0) 'R*/G-phase 0   = RED
  312. IF t.col >= (1 * 255) AND t.col < (2 * 255) THEN colr& = _RGB(t.col - (255 * 1), 255, 0) 'G*\R-phase 255 = RG
  313. IF t.col >= (2 * 255) AND t.col < (3 * 255) THEN colr& = _RGB(0, 255, t.col - (2 * 255)) 'G*/B-phase 510 = GREEN
  314. IF t.col >= (3 * 255) AND t.col < (4 * 255) THEN colr& = _RGB(0, (4 * 255) - t.col, 255) 'B*\G-phase 765 = GB
  315. IF t.col >= (4 * 255) AND t.col < (5 * 255) THEN colr& = _RGB(t.col - (4 * 255), 0, 255) 'B*/R-phase 1020= BLUE
  316. IF t.col >= (5 * 255) AND t.col <= (6 * 255) THEN colr& = _RGB(255, 0, (6 * 255) - t.col) 'R*\B-phase 1275= BR
  317.  
  318.  

 

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: MARBLE RING TRINKET
« Reply #1 on: October 29, 2020, 07:56:07 pm »
Nice Puuzzle!

Are the colors supposed to match the inside of the wheels?

Offline Rubidium

  • Newbie
  • Posts: 10
    • View Profile
Re: MARBLE RING TRINKET
« Reply #2 on: October 29, 2020, 08:29:08 pm »
oops, I should include the purpose huh?
Thanks Bplus, Yes, the colors should match the inner colored LEDs so it can be solved

Offline bplus

  • Global Moderator
  • Forum Resident
  • Posts: 8053
  • b = b + ...
    • View Profile
Re: MARBLE RING TRINKET
« Reply #3 on: October 29, 2020, 09:08:08 pm »
;-)) sometimes lack of instructions can be part of the puzzle, this one is probably like that. You left enough visual clues I think.


Offline Richard Frost

  • Seasoned Forum Regular
  • Posts: 316
  • Needle nardle noo. - Peter Sellers
    • View Profile
Re: MARBLE RING TRINKET
« Reply #4 on: October 29, 2020, 10:33:22 pm »
Very nice.   Freaked me out thinking there was a command
I'd never seen (LMAP) until I realized it's an array.

Should keep cats busy for eternity too.

It works better if you plug it in.