- Home /
How destroy a object and it's similars
How can I do a logic to destroy all the red cubes together?
If I count the first index of the matrix [i] and [j] together, they don't group up correctly in either way,just counting each side separately like I did above woked, but doesn't seem that's going to work if I did all sides separately.
I did something like this to test, just countig the "j" side:
void CombineSimilar(int i, int j)
{
//the name of the block tha was hit
int number1 = i;
int number2 = j;
for (; j <= 7; j++)
{
if (j+1<=7 && array[number1, number2].typeOfBlock ==
array[i, j + 1].typeOfBlock)
{
array[i, j + 1].obj.transform.parent =
array[number1, number2].obj.transform;
}
else
break;
}
Destroy(array[number1, number2].obj);
}
Your pictures are nice =D, but what is your question?
Are you asking to destroy all same objects in the same line?
Thanks : ^D. Destroy all the same color objects that are connected with each other.
First of all, use X;Y ins$$anonymous$$d of i;j and number1;number2.
That's clearer in my head, and maybe in yours.
So, if it is not in the same line, check for the flood algorithm. It it is in the same line, just check left and right, and continue if it is the same color.
I did not put in this way because I 'd be confused.
The "i" works like Y top-down, and J like the X Left-right. So if I'd have changed to (X,Y), I'd be confused xD
unfortunately is not in the same line
Answer by hherzog · Mar 04, 2013 at 03:01 PM
The @robertbu's solution throws a stark over flow exeption, if I mix up the @Mikilo's solution with @robertbu's 's works xD
void Fill(int i, int j)
{
List<Block> checkedCells = new List<Block>(); <-- WHERE SHOULD I PUT THIS?
if (CheckBorder(i, j) == false ||
checkedCells.Contains(this.array[i, j]) == true)
return;
checkedCells.Add(array[i, j]);
if ((i < 7) && (array[i, j].typeOfBlock == array[i + 1, j].typeOfBlock))
Fill(i + 1, j);
if ((i > 0) && (array[i, j].typeOfBlock == array[i - 1, j].typeOfBlock))
Fill(i - 1, j);
if((j > 0) && (array[i, j].typeOfBlock == array[i, j - 1].typeOfBlock))
Fill(i, j - 1);
if((j < 7) && (array[i, j].typeOfBlock == array[i, j + 1].typeOfBlock))
Fill(i, j + 1);
}
bool CheckBorder(int x, int y)
{
return (0 <= x && x <= 7 &&
0 <= y && y <= 7);
}
You have 2 choices:
First, you write a third function in which you allocate and call Fill().
void DeleteBlocks(int i, int j)
{
this.checkedCells = new List<Block>();
this.Fill(i, j);
}
Second, you put a null condition before this allocation.
void Fill(int i, int j)
{
if (this.checkedCells == null)
this.checkedCells = new List<Block>();
if (CheckBorder(i, j) == false || checkedCells.Contains(this.array[i, j]) == true)
return;
checkedCells.Add(array[i, j]);
if ((i < 7) && (array[i, j].typeOfBlock == array[i + 1, j].typeOfBlock))
Fill(i + 1, j);
if ((i > 0) && (array[i, j].typeOfBlock == array[i - 1, j].typeOfBlock))
Fill(i - 1, j);
if((j > 0) && (array[i, j].typeOfBlock == array[i, j - 1].typeOfBlock))
Fill(i, j - 1);
if((j < 7) && (array[i, j].typeOfBlock == array[i, j + 1].typeOfBlock))
Fill(i, j + 1);
}
Just remember, checkedCells is just a list in which you save cells that you have already checked.
In your case, you don't need it, because typeOfBlock already have this role.
I'm still here to help you, try and tell me if it works.
$$anonymous$$y code was a generic flood fill algorithm. $$anonymous$$eep it somewhere in memo. =D
Yeah, I know, it's because with this was working xD , but now the same code is throwing stack overflow exception again. <_<
I thought with some extra lines of code before the checking would take it slow a bit, and would work normal .
If I comment two of those "if " like:`
if((j > 0) && (array[i, j].typeOfBlock == array[i, j - 1].typeOfBlock)) Fill(i, j - 1);`
Doesn't appear the error.
I have noticed that your two examples doesn't appear the error either.
Can you show me the full code? I will rewrite it for you. XD
Try this one.
Call fill with the position and the type you want to destroy.
void Fill(int x, int y, Block.TypeOfBlock targetType)
{
if (this.CheckBorder(x, y) == false ||
this.array[x, y].typeOfBlock != targetType)
return;
array[i, j].typeOfBlock = Block.TypeOfBlock.none;
this.Fill(x + 1, y, targetType);
this.Fill(x - 1, y, targetType);
this.Fill(x, y + 1, targetType);
this.Fill(x, y - 1, targetType);
}
XDDD
I'm sorry, but I can't stop laugh. XD
Use this code, and now call Fill with 0 as fourth argument.
void Fill(int x, int y, Block.TypeOfBlock targetType, int deep)
{
if (deep == 5 ||
this.CheckBorder(x, y) == false ||
this.array[x, y].typeOfBlock != targetType)
return;
array[x, y].obj.renderer.enabled = false;
array[x, y].obj.typeOfBlock = Block.TypeOfBlock.none;
print("Deep(" + x + ";" + y + "#" + deep + ") Start");
this.Fill(x + 1, y, targetType, deep + 1);
this.Fill(x - 1, y, targetType, deep + 1);
this.Fill(x, y + 1, targetType, deep + 1);
this.Fill(x, y - 1, targetType, deep + 1);
print("Deep(" + x + ";" + y + "#" + deep + ") End");
}
Answer by poncho · Feb 28, 2013 at 04:28 PM
first you need to make your algorithm to check who are the ones to be destroyed my guess would be elements connected only in the row, then according to this, check in your matrix the first element that got triggered to be destroyed, then check the elements on the same row that are 1 space to his left or his right, make a recursive method to check chained elements of the same type, add all this elements to name array, when finished the elimination check, start a elimination process, i make a game like that so at least the code is on my mind, hope you understand the main idea. tip: always think the step by step of what you need to do, keep thinking on the steps that are in the mid of what you think till there is no more else to do, thats the way to do fine algorithms
If I understand your algo, it is a line destroyer. He is looking for a multiline destroyer.
Check this link, this is what you are looking for: http://en.wikipedia.org/wiki/Flood_fill
I thought about one solution: Checking the left and right side of it. Then check the underneath him, and again, check the right and left side of this block. And so on.
I'm happy you understand the flood fill. Except one thing, flood fill also checks toward the top. But, in your algo, you need to keep a list of already checked cells. Do that and you will find your Graal.
Edit: Do you want the algo? (Not the code, but the logic structure)
the picture said it needed only horizontal destroy, i made a game where it destroyed every object of the same color on each side, so cutting this to make it only left and right was the option, np for the tip, and flood fill is fun =D
Answer by robertbu · Mar 01, 2013 at 12:31 AM
This should do it. I'm int a bit of a rush and obviously cannot test it without recreating more of your game. The first line assumes you have 7 rows. Let me know of any problems:
void CombineSimilar(int i, int j) {
if (array[i,j].obj != null) {
Destroy (array[i,j].obj);
array[i,j].obj = null;
array[i, j].typeOfBlock = Block.TypeOfBlock.none;
}
if ((i < 7) && (array[i, j].typeOfBlock == array[i + 1, j].typeOfBlock))
CombineSimilar (i+1, j);
if ((j > 0) && (array[i, j].typeOfBlock == array[i, j-1].typeOfBlock))
CombineSimilar(i, j-1);
if ((j < 7) && (array[i, j].typeOfBlock == array[i, j+1].typeOfBlock))
CombineSimilar(i, j+1);
}
Answer by Mikilo · Mar 01, 2013 at 03:25 PM
Flood fill algorithm (Pseudo C#):
Cell[,] grid; // Allocate this one of course!
List<Cell> checkedCells; // Allocate too
void Fill(int x, int y)
{
this.checkedCells.Add(this.grid[x, y]);
// Do your stuff here
if (this.CheckBorder(x + 1, y) == true && this.checkedCells.Contains(this.grid[x + 1, y]) == false)
this.Fill(x + 1, y);
if (this.CheckBorder(x - 1, y) == true && this.checkedCells.Contains(this.grid[x - 1, y]) == false)
this.Fill(x - 1, y);
if (this.CheckBorder(x, y + 1) == true && this.checkedCells.Contains(this.grid[x, y + 1]) == false)
this.Fill(x, y + 1);
if (this.CheckBorder(x, y - 1) == true && this.checkedCells.Contains(this.grid[x, y - 1]) == false)
this.Fill(x, y - 1);
}
bool CheckBorder(int x, int y)
{
return (minX <= x && x < maxX &&
minY <= y && y < maxY);
}
Not so pseudo code... XD
Or this version (Less optim, but less code):
Cell[,] grid; // Allocate this one of course!
List<Cell> checkedCells; // Allocate too
void Fill(int x, int y)
{
if (this.CheckBorder(x, y) == false ||
this.checkedCells.Contains(this.grid[x, y]) == true)
return;
// Do your stuff here
this.checkedCells.Add(this.grid[x, y]);
this.Fill(x + 1, y);
this.Fill(x - 1, y);
this.Fill(x, y + 1);
this.Fill(x, y - 1);
}
bool CheckBorder(int x, int y)
{
return (minX <= x && x < maxX &&
minY <= y && y < maxY);
}
I hope that will be enough.
Good day.