0

We are creating the Towers of Hanoi game in a console window. We are supposed to use a Dictionary> to hold the game pieces. I have it declared outside of main as a global. When I call the static void function drawboard(Dictionary<char, Stack<int>>. No matter what I try, a local variable name System.Collections.Generic.Dictionary<TKey, TValue>.this[TKey].get returned. When I watch the variable it is displayed as $ReturnValue1, and it is overwriting my original dictionary. What is happening, and how do I stop it, or at least work around it.

I have tried creating clones of the dictionary and passing them through drawboard, but it still overrides the original. I have tried changing the scope of the dictionary, and I have tried adding modifiers to the dictionary like protected, private, ect. I have also jumped through several hoops and made my drawboard a little more complicated than it currently is trying to get around this problem. I can simplify it easily enough if I can figure out the root of my problem.

--declaration--

 static Dictionary<char, Stack<int>> towers = new Dictionary<char, Stack<int>>();
            towers.Add('A', new Stack<int> { });
            for (int x = 4; x > 0; x--)
            {
                towers['A'].Push(x);
            } 
            towers.Add('B', new Stack<int> { }); 
            towers.Add('C', new Stack<int> { });

---draw board function---

static void printboard(Dictionary<char, Stack<int>> t)
    { 
        Stack<int> A = t['A'];
        Stack<int> B = t['B'];
        Stack<int> C = t['C'];


        for (int y = 0; y < 5; y++)
        {
            if (y == 4)
            {
                Console.Write("----------\n" +
                              "A   B   C\n");
            }
            else
            {
                if (A.Count == 0)
                    Console.Write("|" + "   ");
                else
                {
                    Console.Write(A.Pop() + "   ");
                }
                if (B.Count == 0)
                    Console.Write("|" + "   ");
                else
                {
                    Console.Write(B.Pop() + "   ");
                }
                if (C.Count == 0)
                    Console.Write("|" + "   ");
                else
                {
                    Console.Write(C.Pop() + "   ");
                }
                Console.Write("\n");
            }
        }
    }

The code is supposed to pass the dictionary by value, pop out values from the local copy of the dictionary and print them out to the console window, without affecting the original towers Dictionary.

  • Possible duplicate of [Passing Objects By Reference or Value in C#](https://stackoverflow.com/questions/8708632/passing-objects-by-reference-or-value-in-c-sharp) – Kelvin Lai May 28 '19 at 01:31
  • What you are doing here is passing the reference, which without a doubt, on modification will change values. What to want to do is create a Deep Copy and perform manipulations over that. – Rakshith Murukannappa May 28 '19 at 04:45
  • But i though u needed to use the ref modifier or out modifier. How did I pass it by reference? – Steven Schoor May 28 '19 at 05:14
  • @StevenSchoor can u share the code where you are invoking the `drawboard` function? – akg179 May 28 '19 at 05:44
  • printboard(towers); drawboard was a mistake name i made in the post. its name is printboard in all the code. – Steven Schoor May 28 '19 at 06:01

1 Answers1

0

Create a Dictionary type variable and assign a copy of the original dictionary towers to it and then pass this new variable to your printboard method. Something like this:

var copiedTowers = new Dictionary<char, Stack<int>>(towers);
printboard(copiedTowers);

This can also be implemented as:

printboard(new Dictionary<char, Stack<int>>(towers));

Also, within the printboard method, while initializing the variable Stack<int> A, follow the same approach to copy contents of dictionary value. Like this:

Stack<int> A = new Stack<int>(t['A']);
Stack<int> B = new Stack<int>(t['B']);
Stack<int> C = new Stack<int>(t['C']);
akg179
  • 1,287
  • 1
  • 6
  • 14
  • Tried that already i think, but your implementation is a bit different so I will try it real fast. – Steven Schoor May 28 '19 at 06:20
  • Nope, it still somehow references the original Dictionary and returns to it. – Steven Schoor May 28 '19 at 06:22
  • returns it from where? – akg179 May 28 '19 at 06:23
  • Like i said in the OP, I don't know exactly how it is doing it, as the printboard function starts using the data from my dictionary in any sort of way, it is changing the original dictionary. a local variables shows up when I start trying to copy the data to some other stack, array, dictionary, ect called iSystem.Collections.Generic.Dictionary.this[TKey].get returned. when I add a watch tot he variable, this variables shows up as $ReturnValue1 – Steven Schoor May 28 '19 at 06:26
  • can u please share the code of `printboard` method in the post? – akg179 May 28 '19 at 06:27
  • added it to the OP, but i don't think it uses anything complex. It originally just used the argument t. Passing the stacks in t to the local stacks was a failed attempt to solve the problem. – Steven Schoor May 28 '19 at 06:32
  • @StevenSchoor edited my answer. Please try initializing the `Stack` local variables within the `printboard` method in the same way. – akg179 May 28 '19 at 06:56
  • Thank you the final edit worked. So I did not initialize the new stacks correctly. Lesson learned – Steven Schoor May 28 '19 at 07:02