Joe
Joe

Reputation: 23

C# stack push call issue

I'm having an issue where my C# stack will accept a pushed value but then overwrite the previously existing elements in the stack with the new value as well.

Here's a chunk of the constructor for reference:

 public class MazNav                    //handles processing and navigation
{
    private Maze m;
    private static Stack<int[]> path;
    private int[] currCell;
    private int visCell;
    private Random rng;

    //constructor
    public MazNav(Maze mz)
    {
        m = mz;                                         //assigns this object to a maze
        path = new Stack<int[]>();                      //initialize the stack
        currCell = m.getStart();                        //starts the pathfinding at start cell
        visCell = 1;                                    //initializes the visited cells count
        path.Push(currCell);                            //adds this cell to the stack
        rng = new Random();                               //initializes the randomizer

The problem occurs in the if block towards the end of this method (sorry it's still ugly; I'm in the middle of debugging and will clean this up once I have something that works :) ):

 public void buildMaze()
    {
        //variables to represent the current cell
        int[] currPos;              //coordinates
        int nextDir = 0;                 //direction towards next cell

        //variables to represent the next cell
        int[] nextPos;              //coordinates
        int backDir = 0;                //holds direction towards previous cell

        bool deadEnd = false;       //flags true when a backtrack is required
        bool outOfBounds = false;   //flags true when a move would leave the array

        while (visCell < m.getTotCells())       //while the number of visited cells is less than the total cells
        {
            if (path.Count > 0)     // if there is something in the stack
            {
                currPos = path.Peek();                          //check the current coordinates
                nextPos = currPos;                              //movement will happen one cell at a time; setting next cell coordinates the same as current allows easy adjustment
                nextDir = findNextUnv(currPos);                    //find the direction of the next cell to check
                deadEnd = false;
                outOfBounds = false;

                switch (nextDir)
                {
                    case 0: //North
                        if (nextPos[0] - 1 >= 0)
                        {
                            nextPos[0]--;
                            backDir = 2;
                        }
                        else
                        {
                            outOfBounds = true;
                        }
                        break;

                    case 1: //East
                        if (nextPos[1] + 1 < m.getCols())
                        {
                            nextPos[1]++;
                            backDir = 3;
                        }
                        else
                        {
                            outOfBounds = true;
                        }
                        break;

                    case 2: //South
                        if(nextPos[0] + 1 < m.getRows())
                        {
                            nextPos[0]++;
                            backDir = 0;
                        }
                        else
                        {
                            outOfBounds = true;
                        }
                        break;

                    case 3: //West

                        if (nextPos[1] - 1 >= 0)
                        {
                            nextPos[1]--;
                            backDir = 1;
                        }
                        else
                        {
                            outOfBounds = true;
                        }
                        break;

                    case 99: //dead end
                        try
                        {
                            deadEnd = true;
                            path.Pop();
                            currPos = path.Peek();
                            int diff;


                            if (currPos[0] == nextPos[0])
                            {
                                diff = currPos[1] - nextPos[1];
                                if (diff == -1)
                                {
                                    backDir = 3;
                                }
                                else if (diff == 1)
                                {
                                    backDir = 1;
                                }
                            }
                            else if (currPos[1] == nextPos[1])
                            {
                                diff = currPos[0] - nextPos[0];
                                if (diff == -1)
                                {
                                    backDir = 2;
                                }
                                else if (diff == 1)
                                {
                                    backDir = 0;
                                }
                            }
                            m.getCell(nextPos[0], nextPos[1]).setBck(backDir, true);
                        }
                        catch (Exception) { }

                        break;                           
                }
                    if (!deadEnd && !outOfBounds)
                        {
                            m.getCell(currPos[0], currPos[1]).setWal(nextDir, false);
                            m.getCell(nextPos[0], nextPos[1]).setWal(backDir, false);
                            path.Push(nextPos);
                            visCell++;
                        }
            }
        }

    }e

The push call is only executed once but when I watch it on the debugger, after that line runs, the count increases by 1 but every element in the stack is now identical. Has anyone come across this behavior before? Where am I going wrong?

Upvotes: 2

Views: 173

Answers (1)

JLRishe
JLRishe

Reputation: 101680

There are a lot of bugs in your code because of the way you are treating nextPos and curPos.

In particular, this line:

nextPos = currPos;

Here you are assigning nextPos to be the same array as curPos, so if you modify one, the other one will be modified along with it. And if you push one on to the stack and then modify either one, the array on the stack will be modified along with it.

The solution I would suggest is to use an immutable data type for your positions, rather than an array (which isn't particularly well suited for coordinates anyway):

internal struct Point
{
    internal int X { get; private set; }
    internal int Y { get; private set; }

    internal Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    internal Point NewX(int deltaX)
    {
        return new Point(X + deltaX, Y);
    }

    internal Point NewY(int deltaY)
    {
        return new Point(X, Y + deltaY);
    }
}

This way, when you need to transition to a new point, you can create a new one instead of modifying an existing one:

if (nextPos.X - 1 >= 0)
{
    nextPos = nextPos.NewX(-1);
    backDir = 2;
}

This should help you to keep a handle on your values and keep them from overwriting each other every which way.

Upvotes: 4

Related Questions