Somone look at code real quick please :)

Started by
7 comments, last by szecs 13 years, 6 months ago
I'm quite sure theres an obvious solution, but I can't seem to find it.
(This is the last thing I have to get working before the code for my falling block game is done.)

This code is supposed to check if a row is full. If it should remove that row.
Simultaneously it should be checking if a row is empty. If the row is empty it moves everything above it down 1 spot.

Note::I tested rowFull() and remove(). Both work properly. (rowFull returns bool if the row specified is full of 2's. Remove changes the row to all 0's.)

"1"s are the border. Or where I will draw the border when I write the GUI.
void gameMap::remap() { //check for empty rows and fall if required.    int y = 19, sum = 0;    for (int j = y; j>=0 ; j--) {        sum = 0;        if (rowFull(j)){            remove(j);        }        for (int i = 1; i < 11; i++) {            sum += map[j];        }        if (sum == 0) {            for (int i = 1; i < 11; i++) {                for (int j = y; j > 0; j--) {                    map[j] = map[j-1];                }            }        }    }


Input gameMap:
1 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 2 2 2 2 2 2 2 2 2 2 11 2 2 2 2 2 2 2 2 2 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 1 1 1 1 1 1 1 1 1 1 1


Output I'm getting:
1 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 0 0 0 0 0 0 0 0 0 0 11 1 1 1 1 1 1 1 1 1 1 1


Assuming that for some reason my program continues to drop rows ontop of the remaped row. so when the 2 2 2 2 2 2 row moves down once, a 0 0 0 0 0 0 row moves ontop of it.

Can't see where its happening though. (Just finished writing the code, and don't want to wait til tomorrow to look at it)

So was hoping that someone else could let me know what they see.
Advertisement
You have two nested "j" variables. Couldn't that be a problem?

That was a real quick look at.
I saw that just after posting, but same problem after correcting it.
//I think that it is legal to use j's like that(not sure).
But it is probably bad style, so I corrected it either way.
Yes, it's OK (although confusing) to have a loop over 'j' inside your loop over 'j'. However, this causes problems with access to the outer 'j', should you need it.

Your logic errors, as far as I can tell, are as follows:

1) You are initializing the inner 'j' with 'y'. You want to initialize it with the outer 'j', so you will have to rename it after all. As it stands, you're moving down every row, not just the ones above the empty row.

2) If you move everything down above an empty row, and then proceed to the next row, that means you skip over a row (the one that was just moved into the row you were just looking at). That row could also be empty or full...

You are trying to do too much at once, anyway. You are going to have to separate the process of removing rows from the process of dropping rows, because eventually you are going to animate the rows being removed and then dropped (right?). So the removal has to happen before the dropping.

You basically want three functions, as follows:

1) Find all full rows. Clear them.

2) Find the bottom-most empty row. Drop every row above that. Return whether or not any blocks actually dropped.

3) Repeatedly call (2) until nothing actually drops. (This is how the animation happens; in the final product, you won't have this function, but instead you'll have to manage some state and have a game loop running that does the appropriate thing according to the state you're in.)
Quote:Original post by Frggr
I saw that just after posting, but same problem after correcting it.
//I think that it is legal to use j's like that(not sure).
But it is probably bad style, so I corrected it either way.


It may be legal (if your compiler says so), but how do you know which "j" is used as the array index?

Anyway, I suggest you to print the array after every steps in the loop with a pause (time or waiting for user input) if it's easy to add. you could see where is goes wrong.

Another thing: these things are easy to fuck up: you alter something that you check afterwards. It's hard to express, but I would decouple the full row check from the advancing down. So do a loop through the whole array, remove full lines THEN advance in a separate loop.

Okay, I'm too tired for this, I'll just copy my solution here:
void DestroyLine(){    int counter;    for( int k = 0; k < 30; k++ )    {            counter = 0;        for( int i = 0; i < 15; i++ )            if( Field[k] == 1 )                counter ++;        if( counter < 15 )            continue;        LineCount ++;        for( int i = 0; i < 15; i++ )        {    Field[k] = 0;                //Sleep(30);            //Display();        }        for( int i = 0; i < 15; i++ )        {                    for( int m = k-1; m >= 0; m-- )            {                Field[m+1] = Field[m];            }        }    }}
Thanks for the advice guys. I'll go fix it up. Shouldn't be too big of a change.

I do have a question though.

How much do you plan before ever writing a program?
I started thinking that it might have been beneficial to write out each class, and their the prototypes of the methods before ever trying to write the code.
This would help me with the problem I have now of my code being all cluttered, and not being able to decide what should be private // public etc.

(Also: In code::blocks how do you get a header file to run on its own (for testing) -- this isnt really important but if someone knows it would be helpful)

[Edited by - Frggr on October 16, 2010 6:40:10 PM]
Quote:
How much do you plan before ever writing a program?

Depends on the language.
I have been planning C++ projects for about 18 years now and haven't got to the implementation yet. Mainly because of its inherent "Doing things right is wrong" syndrome.
In C# on the other hand, I have been able to finish quite a few things.
(Also: In code::blocks how do you get a header file to run on its own (for testing) -- this isnt really important but if someone knows it would be helpful)

You can't test headers on its own, cause compilers only copy the header when you include it, and don't do anything in the header. If you want to test a header, just include it in a .cpp and compile the .cpp
Quote:Original post by Frggr
How much do you plan before ever writing a program?
I started thinking that it might have been beneficial to write out each class, and their the prototypes of the methods before ever trying to write the code.
This would help me with the problem I have now of my code being all cluttered, and not being able to decide what should be private // public etc.


Logic/mechanics: in detail (I can't imagine how can one figure out a tetris without making plans first).

Coding stuff: usually no plans.

This makes me a very effective and fast programmer, with shit code. But I get things to work, maybe at the cost of 3-4 sheets of paper / logic feature. So about 100 (??) sheets of paper per "big" project.

This topic is closed to new replies.

Advertisement