Match-3 piece generation/removal

Godot Version



Hi folks. I’m creating a pretty straightforward Match-3 style game based on a tutorial I found. I’ve run into two problems, which seem related, that I’ve been troubleshooting for several days. I’m hoping to get some help resolving them. I understand generally what I’m doing but have a learning disability that makes troubleshooting difficult for me sometimes. I feel like I’ve just been going in circles with this. Please let me know if I can provide any other info that would be helpful. I wasn’t sure about uploading my whole project but tried to provide at least the most relevant code.

First, one of the features is an assortment of bomb, or blast, pieces that are generated based on certain conditions (for instance, when 4 or 5 pieces are matched). Basically, out of the matched pieces, one is made into a piece for subsequent moves. I want to limit the generated blast pieces so that there are only 2 on the board at any given time. The feature works at first glance but upon destruction of the two pieces that have been generated, no more are created. So (not here but in the function I use to refill the columns after pieces have been removed), I reset the count for the blast piece to 0 when the board refills, after the blast pieces have been destroyed. The problem is that resetting breaks the counter and allows more than 2 pieces to be created. Either the number of pieces is limited without their regeneration after initial removal, or there’s no cap and many blast pieces can be accrued by the player very quickly.

func make_blast(blast_type, color):
	if blast_count < max_blasts:
		## iterate over current_matches
		for i in current_matches.size():
			## cache variables for later...
			var current_column = current_matches[i].x
			var current_row = current_matches[i].y
			if all_pieces[current_column][current_row] == piece_one and piece_one.color == color:
				## make piece_one a blast
				damage_special(current_column, current_row)
				emit_signal("check_goal", piece_one.color)
				piece_one.matched = false
				change_blast(blast_type, piece_one)
				blast_count += 1
			if all_pieces[current_column][current_row] == piece_two and piece_two.color == color:
				## make piece_two a blast
				damage_special(current_column, current_row)
				emit_signal("check_goal", piece_two.color)
				piece_two.matched = false
				change_blast(blast_type, piece_two)
				blast_count += 1

Second, when pieces are matched, the rest of the board is iterated over to chain together any other matches that might exist due to empty spaces being filled. I’d also like to limit those, in order to avoid massive domino reactions. I’ve tried a couple different things in terms of helper functions, if statements, and so on. Ideally I want to be able to make a match, have 2 or 3 matches be chained due to new collisions, and then have the search for pieces stop so that the user can then initiate a new match.

     ## player matches pieces in rows, columns, adjacent (T/L shape) and based on 
     ## color 
func find_blasts():
	if !color_blast_used:
		## iterate over the current_matches array
		for i in current_matches.size():
			## store values for the match being made
			var current_column = current_matches[i].x
			var current_row = current_matches[i].y
			if all_pieces[current_column][current_row] != null:  ## Check if the piece exists
				var current_color = all_pieces[current_column][current_row].color
				var col_matched = 0
				var row_matched = 0
				var match_count = 0 ## count how many matches there are
				## iterate over the current matches to check if column, row, and color are the same
				for j in current_matches.size():
					var this_column = current_matches[j].x
					var this_row = current_matches[j].y
					if all_pieces[this_column][this_row] != null:  ## Check if the piece exists
						var this_color = all_pieces[this_column][this_row].color
						if this_column == current_column and current_color == this_color:
							col_matched += 1
							match_count += 1
						if this_row == current_row and this_color == current_color:
							row_matched += 1
							match_count += 1
					if match_count >= 3:  ## if there are more than three auto-chain matches after user match, stop looking for matches
				## 0 is an adjacent blast, 1 is a column, 2 is a row, 3 is color
				if col_matched == 5 or row_matched == 5:
					make_blast(3, current_color)
				elif col_matched >= 3 and row_matched >= 3:
					make_blast(0, current_color)
				elif col_matched == 4:
					make_blast(1, current_color)
				elif row_matched == 4:
					make_blast(2, current_color)