### Author Topic: MAKE5 Board clearing puzzle  (Read 400 times)

0 Members and 1 Guest are viewing this topic.

#### Dav

• Forum Resident
• Posts: 601
##### MAKE5 Board clearing puzzle
« on: January 10, 2021, 08:10:35 PM »
Here's a simple little puzzle game made on a lazy afternoon.  It's a close copy of one I was playing online.  You arrange the big colored balls in a row (5 or more) to erase them.  More balls appear randomly on the board.  Keep clearing the balls to make space on the board.  See how high a score you can get before the board gets full.

- Dav

EDIT: Updated the colors and Game Over box.

Code: QB64: [Select]
1. '=========
2. 'MAKE5.bas
3. '=========
4. 'A board clearing puzzle game.
5. 'Clear the board of balls, score points.
6. 'Coded by Dav, JAN/2021
7.
8. 'Colored balls appear randomly on playing board.
9. 'Move the bigger balls of same color next to each other.
10. 'Make row/column of 5 or more balls to erase them and score.
11.
12. 'Three new balls will appear after every move.
13. 'The small balls will grow into big ones on next move.
14. 'You can place the big balls on top of the smaller ones.
15.
16. 'See how many points you can score before running out of space.
17.
18. '=========================================================
19.
20.
21. SCREEN _NEWIMAGE(600, 650, 32)
22. _TITLE "Make5 Puzzle"
23.
24. '=== define board info
25. DIM SHARED rows, cols, size, score, hiscore
26. rows = 9: cols = 9: size = _WIDTH / cols
27. DIM SHARED box.v(rows * cols), box.s(rows * cols) 'value, size
28. DIM SHARED box.x(rows * cols), box.y(rows * cols) 'x/y's
29.
30. '=======
31. restart:
32. '=======
33.
34. PLAY "MBL32O3CEGEC"
35.
36. score = 0
37.
38. CLS , _RGB(13, 13, 13)
39.
40. bc = 1 'counter
41. FOR c = 1 TO cols
42.     FOR r = 1 TO rows
43.         x = (r * size)
44.         y = 50 + (c * size)
45.         box.x(bc) = x - size
46.         box.y(bc) = y - size
47.         box.v(bc) = 0 'zero means no color, empty box
48.         box.s(bc) = 1 ' 1 = small size piece
49.         bc = bc + 1
50.
51. MakeNewBalls 3, 1 'add 3 big new balls to board
52. MakeNewBalls 3, 2 'add 3 small balls to board
53.
54. '====
55. main:
56. '====
57.
58. selected = 0
59.
60. UpdateBoard
61.
62. second: 'Go back here when making second choice
63.
64.
65.     'wait until mouse button up to continue
66.     WHILE _MOUSEBUTTON(1) <> 0: n = _MOUSEINPUT: WEND
67.
68.     trap = _MOUSEINPUT 'Poll mouse data
69.
70.     'highlight box when a box is selected
71.     IF selected = 1 THEN
72.         LINE (box.x(t) + 2, box.y(t) + 2)-(box.x(t) + size - 2, box.y(t) + size - 2), _RGB(RND * 255, RND * 255, RND * 255), B
73.         LINE (box.x(t) + 3, box.y(t) + 3)-(box.x(t) + size - 3, box.y(t) + size - 3), _RGB(RND * 255, RND * 255, RND * 255), B
74.         LINE (box.x(t) + 4, box.y(t) + 4)-(box.x(t) + size - 4, box.y(t) + size - 4), _RGB(RND * 255, RND * 255, RND * 255), B
75.
76.
77.     'If user clicked mouse
78.
79.         'see where they clicked
80.         mx = _MOUSEX: my = _MOUSEY
81.
82.         'cycle through all Check blocks...
83.         FOR t = 1 TO (rows * cols)
84.
85.             'Block loction...
86.             tx = box.x(t): tx2 = box.x(t) + size
87.             ty = box.y(t): ty2 = box.y(t) + size
88.
89.             'if clicked on a box clicked
90.             IF mx >= tx AND mx <= tx2 THEN
91.                 IF my >= ty AND my <= ty2 THEN
92.
93.                     'if this is a first choice...
94.                     IF selected = 0 THEN
95.
96.                         'only select boxes not empty, with big size balls
97.                         IF box.v(t) <> 0 AND box.s(t) = 2 THEN
98.                             selected = 1
99.                             SOUND 3000, .1 'made a select
100.                             oldt = t
101.                             oldtv = box.v(t) 'save picked box number color
102.                             GOTO second 'now get second choice
103.
104.
105.                     IF selected = 1 THEN 'making second choice
106.
107.                         'if selected an empty box or small ball
108.                         IF box.v(t) = 0 OR box.s(t) = 1 THEN
109.
110.                             'swap 2nd box data
111.                             box.v(t) = oldtv
112.                             box.s(t) = 2
113.                             'erase 1st box data
114.                             box.v(oldt) = 0
115.                             box.s(oldt) = 1
116.                             SOUND 2000, .1
117.                             UpdateBoard
118.                             '===============================
119.
120.                             'Grow small balls
121.                             FOR d = 1 TO rows * cols
122.                                 IF box.v(d) <> 0 AND box.s(d) = 1 THEN box.s(d) = 2
123.
124.                             UpdateBoard
125.
126.                             'check Rows for 5 or more done
127.                             FOR i = 1 TO (rows * cols) STEP 9
128.                                 CheckRow i
129.
130.                             'Check Cols for 5 or more
131.                             FOR i = 1 TO 9
132.                                 CheckCol i
133.
134.                             'See how many boxes left to use...
135.                             howmany = 0
136.                             FOR h = 1 TO rows * cols
137.                                 'empty ones
138.                                 IF box.v(h) = 0 THEN howmany = howmany + 1
139.
140.                             'If not enough spaces left, game over
141.                             IF howmany < 3 THEN
142.                                 LINE (200, 250)-(400, 350), _RGB(0, 0, 0), BF
143.                                 LINE (200, 250)-(400, 350), _RGB(255, 255, 255), B
144.                                 PPRINT 233, 285, 18, _RGB(255, 255, 255), 0, "GAME OVER"
145.                                 PLAY "mbl16o2bagfedc"
146.                                 GOTO restart
147.
148.                             'make 3 more random small balls
149.                             MakeNewBalls 3, 1
150.                             GOTO main
151.
152.
153.                             'if clicked on another big ball instead...
154.                             IF box.s(t) = 2 THEN
155.                                 'clear previous highlighted selection
156.                                 selected = 0
157.                                 UpdateBoard
158.                                 selected = 1
159.                                 oldt = t
160.                                 oldtv = box.v(t) 'save picked box number color
161.                                 SOUND 3000, .1
162.                                 GOTO second
163.
164.
165.
166.
167.
168.
169.
170.     IF INKEY\$ <> "" THEN GOTO restart
171.
172.
173. SUB CheckRow (num)
174.
175.     'space to hold box nums to clear
176.     REDIM nums(9)
177.
178.     'found some to clear flag
179.     rdone = 0
180.
181.     'set place and num
182.     rc = 1
183.     nums(1) = num
184.
185.     'step through the boxes
186.
187.     FOR r = (num + 1) TO (num + 8)
188.
189.         'if this box is same as previous...
190.         IF box.s(r) = 2 AND box.v(r) = box.v(nums(rc)) THEN
191.             'store this box value in nums too
192.             nums(rc + 1) = r
193.             'increase how many so far
194.             rc = rc + 1
195.             'bot same, so reset
196.
197.             IF rdone = 0 THEN
198.                 'no more, so start over from here
199.                 ERASE nums
200.                 REDIM nums(9)
201.                 rc = 1: nums(1) = r
202.                 'no more can exists on line
203.
204.         'if there was 5 or more found
205.         IF rc >= 5 THEN rdone = 1
206.
207.
208.     'if group was found, clear
209.     IF rdone = 1 THEN
210.         PLAY "mbl32o3cdefga"
211.         'step through nums values
212.         FOR d = 1 TO 9
213.             IF nums(d) <> 0 THEN
214.
215.                 score = score + 55 '55 points per ball
216.
217.                 x = box.x(nums(d)): y = box.y(nums(d))
218.                 LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(255, 255, 255), BF
219.                 _DELAY .02: _DISPLAY
220.                 LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(64, 64, 64), BF
221.                 _DELAY .02: _DISPLAY
222.                 box.v(nums(d)) = 0: box.s(nums(d)) = 1
223.
224.     ERASE nums
225.
226.
227. SUB CheckCol (num)
228.
229.     'space to hold box nums to clear
230.     REDIM nums(9)
231.
232.     'found some to clear flag
233.     rdone = 0
234.
235.     'set place and num
236.     rc = 1
237.     nums(1) = num
238.
239.     'step through the boxes
240.
241.     FOR r = (num + 9) TO (rows * cols) STEP 9
242.
243.         'if this box is same as previous...
244.         IF box.s(r) = 2 AND box.v(r) = box.v(nums(rc)) THEN
245.             'store this box value in nums too
246.             nums(rc + 1) = r
247.             'increase how many so far
248.             rc = rc + 1
249.             'bot same, so reset
250.
251.             IF rdone = 0 THEN
252.                 'no more, so start over from here
253.                 ERASE nums
254.                 REDIM nums(9)
255.                 rc = 1: nums(1) = r
256.                 'no more can exists on line
257.
258.         'if there was 5 or more found
259.         IF rc >= 5 THEN rdone = 1
260.
261.
262.     'if group was found, clear
263.     IF rdone = 1 THEN
264.         PLAY "mbl32o3cdefga"
265.         'step through nums values
266.         FOR d = 1 TO 9
267.             IF nums(d) <> 0 THEN
268.                 score = score + 55 'add to score
269.                 x = box.x(nums(d)): y = box.y(nums(d))
270.                 LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(255, 255, 255), BF
271.                 _DELAY .02: _DISPLAY
272.                 LINE (x + 2, y + 2)-(x + size - 2, y + size - 2), _RGB(64, 64, 64), BF
273.                 _DELAY .02: _DISPLAY
274.                 box.v(nums(d)) = 0: box.s(nums(d)) = 1
275.
276.     ERASE nums
277.
278.
279.
280. SUB UpdateBoard
281.
282.     PPRINT 20, 14, 14, _RGB(200, 200, 200), 0, "SCORE:" + LTRIM\$(STR\$(score))
283.     IF score >= hiscore THEN hiscore = score
284.     PPRINT 475, 14, 14, _RGB(200, 200, 200), 0, "HI:" + LTRIM\$(STR\$(hiscore))
285.     PPRINT 220, 10, 20, _RGB(255, 255, 255), 0, "-=MAKE5=-"
286.
287.     '=== draw board based on box values
288.     bc = 1 'counter
289.     FOR cl = 1 TO cols
290.         FOR ro = 1 TO rows
291.             '=== if empty box
292.             IF box.v(bc) = 0 THEN
293.                 LINE (box.x(bc) + 2, box.y(bc) + 2)-(box.x(bc) + size - 2, box.y(bc) + size - 2), _RGB(64, 64, 64), BF
294.                 LINE (box.x(bc) + 2, box.y(bc) + 2)-(box.x(bc) + size - 2, box.y(bc) + size - 2), _RGB(64, 64, 64), BF
295.                 '=== draw color ball
296.                 x2 = box.x(bc) + (size / 2) 'find middle of box
297.                 y2 = box.y(bc) + (size / 2)
298.                 IF box.s(bc) = 1 THEN sz = size / 4 ELSE sz = size / 2
299.                 SELECT CASE box.v(bc)
300.                     CASE IS = 1: r = 255: g = 64: b = 64 'red
301.                     CASE IS = 2: r = 0: g = 128: b = 0 'green
302.                     CASE IS = 3: r = 64: g = 64: b = 255 'blue
303.                     CASE IS = 4: r = 255: g = 255: b = 0 'yellow
304.                     CASE IS = 5: r = 255: g = 255: b = 255
305.                 CIRCLE (x2, y2), sz - 4, _RGB(r, g, b)
306.                 PAINT (x2, y2), _RGB(r, g, b)
307.             bc = bc + 1
308.     _ICON _DISPLAY 'update app icon on taskbar
309.
310. SUB MakeNewBalls (num, ballsize)
311.     'Assign 3 new balls
312.     ball = 0
313.         c = INT((RND * (cols * rows)) + 1)
314.         IF box.v(c) = 0 THEN
315.             box.v(c) = INT((RND * 5) + 1)
316.             box.s(c) = ballsize
317.             ball = ball + 1
318.         IF ball = num THEN EXIT DO
319.
320. SUB PPRINT (x, y, size, clr&, trans&, text\$)
321.     orig& = _DEST
322.     bit = 32: IF _PIXELSIZE(0) = 1 THEN bit = 256
323.     FOR t = 0 TO LEN(text\$) - 1
324.         pprintimg& = _NEWIMAGE(16, 16, bit)
325.         _DEST pprintimg&
326.         CLS , trans&: COLOR clr&
327.         PRINT MID\$(text\$, t + 1, 1);
328.         _CLEARCOLOR _RGB(0, 0, 0), pprintimg&
329.         _DEST orig&
330.         x1 = x + (t * size): x2 = x1 + size
331.         y1 = y: y2 = y + size
332.         _PUTIMAGE (x1 - (size / 2), y1)-(x2, y2 + (size / 3)), pprintimg&
333.         _FREEIMAGE pprintimg&
334.
« Last Edit: January 11, 2021, 08:57:26 PM by Dav »

#### Dimster

• Seasoned Forum Regular
• Posts: 472
##### Re: MAKE5 Board clearing puzzle
« Reply #1 on: January 11, 2021, 09:43:32 AM »
Hi Dav.. The balls wouldn't erase for me. Is it a complete block of 25 large balls (ie 5 x 5) or does just a row a/o column of 5 large balls cause it to erase?

#### bplus

• Forum Resident
• Posts: 6567
• What could possibly go wrong?
##### Re: MAKE5 Board clearing puzzle
« Reply #2 on: January 11, 2021, 09:47:56 AM »
They weren't erasing for me either until I realized might be difference between yellow and green. ;-))

#### Dav

• Forum Resident
• Posts: 601
##### Re: MAKE5 Board clearing puzzle
« Reply #3 on: January 11, 2021, 09:52:37 AM »
You have make a line of 5 or more balls of the same color to erase them.

- Dav

#### bplus

• Forum Resident
• Posts: 6567
• What could possibly go wrong?
##### Re: MAKE5 Board clearing puzzle
« Reply #4 on: January 11, 2021, 10:01:54 AM »
Too close for detecting differences specially right after I get up:

#### Dav

• Forum Resident
• Posts: 601
##### Re: MAKE5 Board clearing puzzle
« Reply #5 on: January 11, 2021, 10:06:00 AM »
Yeah, I think I should adjust the colors again - on my old laptop it's sometimes hard to tell close colors apart unless I'm viewing the screen at the perfect angle.

- Dav

#### Dimster

• Seasoned Forum Regular
• Posts: 472
##### Re: MAKE5 Board clearing puzzle
« Reply #6 on: January 11, 2021, 03:31:38 PM »
Thanks Dav - Works great. Not sure where my mind was - so obvious now that the game called for 5 of the same color. Sometimes the obvious is so hard to spot.

#### bplus

• Forum Resident
• Posts: 6567
• What could possibly go wrong?
##### Re: MAKE5 Board clearing puzzle
« Reply #7 on: January 11, 2021, 08:31:54 PM »
@Dav  and surely you meant to change the colors in 9PM edit?

Here is distinctive set:
Code: QB64: [Select]
1.                     CASE IS = 1: r = 255: g = 64: b = 64 'red
2.                     CASE IS = 2: r = 0: g = 128: b = 0 'green
3.                     CASE IS = 3: r = 64: g = 64: b = 255 'blue
4.                     CASE IS = 4: r = 255: g = 255: b = 0 'yellow
5.                     CASE IS = 5: r = 255: g = 255: b = 255
6.

Hey Dav, if I set up 4 going horizontal and 4 vertical and then put the 5th for both where they meet, shouldn't that clear both, 9 pieces?

Green at the meeting place:

« Last Edit: January 11, 2021, 08:51:02 PM by bplus »

#### Dav

• Forum Resident
• Posts: 601
##### Re: MAKE5 Board clearing puzzle
« Reply #8 on: January 11, 2021, 09:03:19 PM »
Those colors look perfect, @bplus. I edited the code and put them in.  Thanks!

Yes, you are correct - the game should be set up to clear both of those, but I didn't get around to coding it in.  Made the same mistake with the 10x10 puzzle.  I will get working on it when I get back home tonight.

Edit: also, the original game i was playing only allowed pieces to move if they had a clear path. The only way i can figure to do that is adapt a floodfill routine i used for another puzzle.  I may do that.  I was reading about shortest path algos, but they are a bit beyond my understanding at the moment.

- Dav
« Last Edit: January 11, 2021, 09:17:05 PM by Dav »

#### bplus

• Forum Resident
• Posts: 6567
• What could possibly go wrong?
##### Re: MAKE5 Board clearing puzzle
« Reply #9 on: January 11, 2021, 09:43:23 PM »
Quote
Edit: also, the original game i was playing only allowed pieces to move if they had a clear path. The only way i can figure to do that is adapt a floodfill routine i used for another puzzle.  I may do that.  I was reading about shortest path algos, but they are a bit beyond my understanding at the moment.

There are different kinds of paths:
Any path as long as it goes from A to B no matter how round about or a path that has to fit inside the rectangle that contains the 2 cells at corners (which makes sense to me for this game)?

Can you only move horizontally or vertically or allow diagonal?

I bet those little circles have the purpose to block your paths.

I was thinking this game reminds me of Click O' Mania again you had it by another crazy name some time ago and Tetris again and 10x10 :)

Anyway the image to remember in shortest pathfinding is to imagine an ever increasing square qrid around your start cell the first group represent the first step you can take, 4 or 8 neighbors depending on stepping rules the 2nd 1 cell larger on all sides is the second step... continue outward until the board is covered. For each cell in the new frame not stepped on yet you see where you can step to from there. You make a temp array and label all places you can visit in 1 step and then label all places where you can visit in 2 steps.... keep going until you hit your target cell or can't step anywhere else from where you've been. When you hit your target cell you backtrack 9, 8, 7, 6... 1, start.

https://www.qb64.org/forum/index.php?topic=410.msg2878#msg2878
« Last Edit: January 11, 2021, 09:45:19 PM by bplus »

#### Dav

• Forum Resident
• Posts: 601
##### Re: MAKE5 Board clearing puzzle
« Reply #10 on: January 11, 2021, 10:47:52 PM »
Thanks you, @bplus.  I'll chew on that a while.  And thanks for the link - I had forgotten about that one.  (the original game only allow Hor/vert, not diag).

Back home.  Will get cracking on it...

- Dav
« Last Edit: January 11, 2021, 11:10:44 PM by Dav »