Question

I am writing a Tetris clone, which is the largest project I have really done. In implementing the row deletion code, I have begun recieving a stack overflow exception. I think it probably has something to do with my huge collections or horribly inefficient use of Linq. Here is the specific method that is causing the issue:

void MoveAllAboveDown(int row)
    {
        List<Block> newBlockList = new List<Block>();
        for (int rowCheck = row; rowCheck > _VertOffset; --rowCheck)
        {
            for (int i = _HorizOffset; i < _HorizOffset + _Width; ++i)
            {
                //If the spot above this is filled
                if (_blockList.Where(block => block.Contains(new Vector2(i, rowCheck - 1))).ToList().Count > 0)
                {
                    //insert block here
                    newBlockList.Add(new Block(new Vector2(i, rowCheck), new[,] { { true } }, Color.Black, _texture));
                }
                else
                {
                    var list = _blockList.Where(tempBlock => tempBlock.Contains(new Vector2(i, rowCheck - 1))).ToList();
                    if (list.Count > 0)
                        list.ElementAt(0).Delete(new Vector2(i, rowCheck - 1));
                }
            }
        }
        for (int rowToDelete = row; rowToDelete > _VertOffset; --rowToDelete)
        {
            DeleteRow(rowToDelete);
        }
        foreach (Block block in newBlockList)
        {
            _blockList.Add(block);
        }
    }

I'll attach the entire source if I can figure out how (even using a separate site if I have to).

If you feel like it, I really wouldn't mind if someone were to look at the entire code base and tell me what I do write and wrong (like naming conventions, algorithms, etc.). Obviously this is not what the site is for, but I figured I'd throw this in since I am attacking the code base anyway.

Edit: Here is the main game file: http://pastebin.com/PqVAS56U
Here is the rest of the code: http://pastebin.com/JjBKZgwN

Edit2: I believe this is a stack trace:

'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Users\Patrick\Desktop\OldComp\Users\patrick\Documents\Visual Studio 2010\Projects\Tetris\Tetris\Tetris\bin\x86\Debug\Tetris.exe', Symbols loaded.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\Microsoft.Xna.Framework.Game\v4.0_4.0.0.0__842cf8be1de50553\Microsoft.Xna.Framework.Game.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\Microsoft.Xna.Framework.Graphics\v4.0_4.0.0.0__842cf8be1de50553\Microsoft.Xna.Framework.Graphics.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_32\Microsoft.Xna.Framework\v4.0_4.0.0.0__842cf8be1de50553\Microsoft.Xna.Framework.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Xna.Framework.Input.Touch\v4.0_4.0.0.0__842cf8be1de50553\Microsoft.Xna.Framework.Input.Touch.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Drawing\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Drawing.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System\v4.0_4.0.0.0__b77a5c561934e089\System.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Windows.Forms\v4.0_4.0.0.0__b77a5c561934e089\System.Windows.Forms.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\Microsoft.Xna.Framework.GamerServices\v4.0_4.0.0.0__842cf8be1de50553\Microsoft.Xna.Framework.GamerServices.dll'
'Tetris.exe' (Managed (v4.0.30319)): Loaded 'C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Core\v4.0_4.0.0.0__b77a5c561934e089\System.Core.dll', Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

Process is terminated due to StackOverflowException.
The program '[7484] Tetris.exe: Managed (v4.0.30319)' has exited with code 0 (0x0).
Was it helpful?

Solution

I don't see you decrementing the value of row that you are passing to MoveAllAboveDown() and then into DeleteRow(). Your DeleteRow() function again calls MoveAllAboveDown() with same row number.

So they will keep on calling each other until StackOverflow.

OTHER TIPS

Without tracing the rest of the code, I suspect part of it is the use of row instead of rowToDelete in:

for (int rowToDelete = row; rowToDelete > _VertOffset; --rowToDelete)
{
    // DeleteRow(row); // Woops! Typo
    DeleteRow(rowToDelete);
}

Edit: If not there, then it is likely in DeleteRow.

I think the reason you're getting a stack trace, is that MoveAllAboveDown(int row) calls DeleteRow(int row) which calls MoveAllAboveDown(int row) creating an infinite loop, as pointed out already by cornerback84.

Here's a couple of other tips:

  • What you edited into the question was not the stack trace, but the trace output.
    • Stack trace means a print out of the call stack, which will show the nested currently executing methods.
    • To view the call stack select Debug > Windows > Call Stack, in the Visual Studio menu.
    • To copy the call stack for pasting into questions, click on "Copy exception details" in the Exception Assistant Dialog Box
  • Since you asked for comment on naming conventions etc., I'd recommend checking out:
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top