2015-03-09 4 views
2

У меня возникла проблема, когда мой стек C# будет принимать значение push, но затем перезаписывает ранее существующие элементы в стеке с новым значением.Проблема с вызовом стека на C#

Вот кусок конструктору для справки:

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 

Проблема возникает в если блоке к концу этого метода (жаль, что это все-таки некрасиво, я нахожусь в середине отладки и уберу это, как только у меня есть то, что работает :)):

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 

толчок вызов выполняется только один раз, но когда я смотрю его на отладчик, после запуска этой линии, количество увеличивается на 1, но каждый элемент стек теперь идентичен. Кто-нибудь сталкивался с этим поведением раньше? Где я иду не так?

+0

Я думаю, что добавление большего количества кода из метода было бы полезно :) – Szab

+1

Szab удалил свой предыдущий комментарий, но проблема почти в том, что вы модифицируете массив, который вы вставляете в стек вместо создания отдельного массива. Нажатие на стек не создает новую копию массива. – JLRishe

+0

Ahh. Вероятно, я ошибся. Было бы лучше скопировать массив во временный и нажать на него? – Joe

ответ

4

В вашем коде есть много ошибок из-за того, как вы лечите nextPos и curPos.

В частности, эта линия:

nextPos = currPos; 

Здесь вы назначаете nextPos быть тот же массив, как curPos, так что если вы измените один, то другой будет модифицироваться вместе с ним. И если вы нажмете один на стек, а затем измените один, массив в стеке будет изменен вместе с ним.

Решение, которое я предложил бы использовать неизменный тип данных для ваших позиций, а не массив (который не особенно хорошо подходит для координат в любом случае):

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); 
    } 
} 

Таким образом, когда вам нужно с переходом на новую точку, вы можете создать новую вместо модификации существующего:

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

Это должно помочь вам держать ручку на ваши ценности и сохранить их от перезаписи друг друга в разные стороны.

+0

Фантастический. Я поменял эту строку на: currPos.CopyTo (nextPos, 0); Это, похоже, решило проблему. Огромное спасибо. :) – Joe

Смежные вопросы