- Home /
Why won't identical 'for' loops work?
Hi all, So I'm making a game in which a player has to move a gem into a board to create matches, similar to Bejeweled. Now, I'm able to detect matching gems above and below using a for loop, but when I do the same for gems to the side, the function just doesn't output anything. Could anyone help me figure out why this is the case?
Notes for the code: The ID of the gems increase from 1-56 from left-right, and IDCheck is the ID of the gem to the sides of which we'll be checking for matches. The board is 8 rows of 7 gems, and finals is the array to hold the IDs of matching gems. Only the loop using var b (gems to the right) won't work.
for (var a = IDCheck+7; a <= 56; a += 7) {
var next1 = GameObject.Find(a.ToString());
if (next1.gameObject.GetComponent.<SpriteRenderer>().sprite == object.gameObject.GetComponent.<SpriteRenderer>().sprite) {
finals.Push(a.ToString());
}
else {
break; }
}
for (var b = IDCheck+1; b <= 56; b ++) {
var next2 = GameObject.Find(b.ToString());
if (next2.gameObject.GetComponent.<SpriteRenderer>().sprite == object.gameObject.GetComponent.<SpriteRenderer>().sprite) {
finals.Push(b.ToString());
}
else {
break; }
}
for (var c = IDCheck-7; c >= 0; c -= 7) {
var next3 = GameObject.Find(c.ToString());
if (next3.gameObject.GetComponent.<SpriteRenderer>().sprite == object.gameObject.GetComponent.<SpriteRenderer>().sprite) {
finals.Push(c.ToString());
}
else {
break; }
}
This is a very, very weird approach to this type of data management. Why you're using ID's or strings is beyond my comprehension, along with the basic nature of what you're trying to accomplish with this code. I can't make heads or tails of what you're doing, but I can say with total confidence that you're making it harder than it needs to be. $$anonymous$$y failure to grasp the question doesn't merit rejecting it, though. Published.
The logic seems fine, and tested fine on my end in a simple scene, I think you have something happening elsewhere in code to prevent 'b' from gathering. Bear in $$anonymous$$d you are not checking leftward, and your "right" directional checks will wrap around to the next row because the limit is set to 56, just in case this could be the issue.
If I may critique, this is very expensive and dangerous code. You're relying on being able to find an object of a given name many times in one method, which is not only an expensive action, but will throw errors if it can't find the object, such as if its name changes or if it is destroyed or deactivated for any reason. Even if you don't plan to do this now and feel certain this won't happen, you're tying your hands unnecessarily. Consider, perhaps, creating a list or array of your objects ahead of time where the index corresponds to the placement. This will avoid having to convert that index to a string as well. GetComponent() is also a little slow, and you're doing this technically 4 times in every for loop iteration (gameObject does GetComponent() behind the scenes). At the very least, I would advise making a sprite var that you will compare everything against before these loops since that doesn't change with any of these iterations. You could also ins$$anonymous$$d use a class that stores a game object reference and a sprite reference in the list to avoid getcomponent entirely. Lastly, and less importantly here, you're using Array(), which is also expensive. I recommend List.
Ok, after not outputting anything I tried reopening the project and adding one for-loop at a time. For the gems to the right, the output, ins$$anonymous$$d of being the ID of gems like when I check to the top, is "CompilerGenerated.CamDragDetector_Update$callable0$70_47"
In regards to AlwaysSunny's comment, sorry if I wasn't clear, but I want to get the ID of the gems that match the user's gem, similar to how Bejewled works except the user has a set of his own to put into the board. I probably am making this harder than it needs to be, but I'm still quite new to Unity as I've only used it for about 2 weeks now.
Answer by ScienceIsAwesome · Jul 25, 2015 at 02:31 AM
I agree that this is definitely not the most efficient or effective way to compare gems, personally I would create a Gem class, give it a gemtype variable for comparison and since you're comparing in straight lines I would just use colliders and raycasts.
That, however, is not an answer to your question. You're methodology with the a and c 'for' loops is sound, within the scope of your approach, the b 'for' loop is set up exactly the same, except it checks the gems to the right and then just continues through all the gems below, as others have pointed out, so if anything it could find too many identical gems. The problem must therefore be elsewhere, but as for fixing the b 'for' loop, I suggest the following:
for (var b = IDCheck+1; b % 7 != 1; b ++)
It checks gems to the right until it reaches the first gem in the next row, something similar would work for left side checking:
for (var d = IDCheck-1; d % 7 != 0; d --)
Answer by TheLagbringer · Jul 25, 2015 at 01:48 AM
The side checking is wrong. The right side search is unbound and will iterate to the end of the array (which is a bit weird since you say it does not return anything ... maybe you should test on more scenarios, or truly the bug is somewhere else), the left side search is missing. Try this:
int leftBound = 7 * (IDCheck / 7) + 1; // note that the division is on integers
int rightBound = leftBound + 6;
for (var b = IDCheck+1; b <= rightBound; b ++) {
// ...
}
for (var d = IDCheck-1; d >= leftBound; d ++) {
// ...
}
Also as others said, consider optimizing the code before proceeding to other scripts. It's quite costly.
Thanks for the reply! I initially did have a system to check if it reached the end of the row, but this code wasn't working so I stripped it down to its bare essentials, which still doesn't work as seen here. I also did factor in going to the left, just didn't include it here because it was identical to the right and still doesn't work.
Your answer
Follow this Question
Related Questions
Why is unity exiting a loop inside a coroutine after its first run through? 1 Answer
More than one row in an array not displaying in a FOR loop 2 Answers
using "for" in Unity Script HELP! 2 Answers
Difference between if statement, while and for loop? 4 Answers
Why is my FOR loop Accelerating each time it is used? 2 Answers