1. Hello Guest! It's with a heavy heart that we must announce the removal of the Legacy GMC Archive. If you wish to save anything from it, now's the time! Please see this topic for more information.
    Dismiss Notice

GML [SOLVED] How is this returning '19' twice?

Discussion in 'Programming' started by TheouAegis, Dec 4, 2019.

  1. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,126
    Code:
    var i=0;
    var row = y-2 + LINEINDEX;
    if median(row,0,size.FIELDHEIGHT-1)==row {
        var cell = row * size.FIELDWIDTH;
        while i<size.FIELDWIDTH {
            if !FIELD[i + cell] {
                LINES[LINEINDEX] = 0;
                break;
            }
            i++;
        }
    }
    
    if i == size.FIELDWIDTH {
        audio_play_sound(5,2,0);
        LINECOUNT++;
        LINES[LINEINDEX] = row;
    }
    
    LINEINDEX++;
    if LINEINDEX < 4
        return 0;
    
    From my Tetris clone. I can't figure out what's making this block of code glitch out. It seems like whenever row is equal to size.FIELDHEIGHT-1, there is a slight chance for the next iteration to also set row to size.FIELDHEIGHT-1. This shouldn't be happening at all! The result of this glitch is it causes 2 lines to get cleared when only one is complete. And if Y goes up each step but y never changes, then no two indexes of LINES should ever be the same! It's one thing if rows 18 and 19 got cleared while LINES[2] showed 18 and LINES[3] showed 19, but both LINES[2] and LINES[3] are showing 19 even though row 18 is clearly getting cleared! WTF?!

    Now, I have a hunch the reason row 18 is getting cleared is because of the next state, which handles the dropping of all the rows down to fill the deleted rows. Maybe -- just possibly maybe -- the row in LINES[2] gets cleared, the row above it drops down, then the row in LINES[3] gets cleared and since it's the same row, it looks like two rows got cleared when in fact it was only one row getting cleared twice. BUT... How the hell is row 19 getting added to LINES[] twice in the first place?!

    Here is how the bottom 4 rows appear in the array. The array looks fine to me -- values never shift and a piece placed in the last cell sets the last index in the array as expected.

    1,0,0,0,0,1,1,0,1,1,
    1,0,0,0,0,1,1,0,1,1,
    1,0,0,0,0,1,1,0,1,1,
    1,1,1,1,1,1,1,0,1,1
    { {
    1,0,0,0,0,1,1,1,1,1,
    1,0,0,0,0,1,1,1,1,1,
    1,0,0,0,0,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1
    { {
    0,0,0,0,0,0,0,0,0,0,
    1,0,0,0,0,1,1,1,1,1,
    1,0,0,0,0,1,1,1,1,1,
    1,1,1,1,1,1,1,1,1,1
    { {
    0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,
    0,0,0,0,0,0,0,0,0,0,
    1,1,1,1,1,1,1,1,1,1

    This is a snapshot of the array after a piece is placed. The green numbers represent the piece just placed. In the second set, you can see that I placed a vertical I piece to clear the bottom row. In the third frame, you see that one row was cleared as expected and then I placed a horizontal piece. (Note: It seems to always be the horizontal pieces on the bottom row that cause the issue.) In the fourth frame, you can see that two rows were cleared instead of just one. When that happens, LINES[] has two indexes both showing the same row.

    Does anyone have any idea why this code is wigging out seemingly so randomly?
     
  2. Homunculus

    Homunculus Member

    Joined:
    Jun 20, 2016
    Posts:
    817
    I'm a bit lost, I really can't figure out what this piece of code is supposed to do and its context. When is this code run, and what's the expected result (I guess it is supposed to clear one line, and therefore is called in a loop)? Why is row dependent on the y position of the calling instance?
     
  3. NightFrost

    NightFrost Member

    Joined:
    Jun 24, 2016
    Posts:
    2,008
    Can't see anything wrong at first glance. That code is just the column iterator though, we don't see what steps through rows to check them, so there could be something funky there. But I also notice the use of y-value like Homunculus. While LINEINDEX increases every call, the LINES array gets the value of rows, which is a function of both y and LINEINDEX. Should it be possible for y to change between script calls, LINES could get the same rows value twice (or more).

    EDIT - Also wondering, if LINES array does not get fully reset, it could carry residual values to next step and act on them to delete additional rows.
     
    TheouAegis likes this.
  4. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,126
    y never changes outside state 1 (this is state 3).

    State 1 moves the piece, state 2 places the piece into the field array, which is what FIELD[] is, and state 3 checks if lines are complete.

    size.FIELDWIDTH is 10 and size FIELDHEIGHT is 20. FIELD[] runs from 0 to 199, with 0 being the top-left and 199 being the bottom-right.

    State 3 runs over 4 steps dictated by LINEINDEx, which is set to 0 at the end of state 2. If I do clear LINES[], it's in another state, but LINEINDEX is always from 0 to 4, so that shouldn't be the issue.

    Obviously LINEINDEX is increasing fine, because it does equal 4 and move on to the rest of the code. So somehow y-2+LINEINDEX==y-2+LINEINDEX+1.

    Also, y only runs from 0 to size.FIELDHEIGHT too. It just keeps track of the row the active piece is on. Rendering is done via draw_sprite() calls.

    Originally the code clamped row, so I assumed that was causing the issue. I changed it to the version you see here then cleared the cache, but that didn't change anything. If anything, it made the glitch happen less often.

    I will double check my Draw code tonight, but I doubt I will find anything there. I think LINEINDEX is only referenced in states 3 and 4 exclusively. I verified LINES[] is getting filled in the correct order.a

    I output the value of LINES when LINEINDEX equals 4 before state 4 is ever run to actually read the values of LINES[]. Every time no lines are cleared, it reads {0,0,0,0} and every time any lines are cleared, it reads the correct values, such as {0,0,18,0} if row 18 was the line cleared.

    Update: Once I got home from work and had something to eat, I checked my Draw code. Nothing there modifies any of the variables in state 3. So then I output to the console the value of y and LINEINDEX every step of state 3. In every single case -- including when the glitch happened -- state 3 was run for 4 frames and the output console would always display
    To make sure I didn't confuse myself, I made sure to place a vertical piece, before I placed a horizontal piece (which glitches), which is where the '18' came from above. That way I'd know if there was any repeating. But there was never any repeating. Even when '19' was getting written to LINES[] twice, the output still showed the correct y and LINEINDEX values. Again, it seemed very random to me; it took me many attempts to intentionally cause the glitch before I finally got it to happen again. I'm stumped!!
     
    Last edited: Dec 5, 2019 at 7:12 AM
  5. TheouAegis

    TheouAegis Member

    Joined:
    Jul 3, 2016
    Posts:
    7,126
    OMG YOU'RE RIGHT! :eek:

    I started to write a long post about some odd values I was getting that ultimately showed LINES[3] was not getting cleared sometimes. Then at the end of what I typed, I realized I should go back and re-analyze the code again. And I think I found the culprit:
    if median(row,0,size.FIELDHEIGHT-1)==row {
    If y-2+LINEINDEX is equal to size.FIELDHEIGHT, LINES[3] will never get reset! OMG total facepalm moment for me there. Thanks for the extra thought processes! :D

    (found another error in my project: i never actually initialized LINES anywhere :confused:)
     
    Last edited: Dec 5, 2019 at 8:42 AM

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice