-1

I am coding chess, and have made a class called BoardObject to store board states, so I can have a list of them, making a history of the game. BoardObject has a field called boardValues, which is a 2D array which stores the values of each square on the board.

In my while loop where the game is played, if the user input passes my validity checks, the move they enter is passed into a method called movePieceTrad. During movePieceTrad, the list boardHistory is changed in some way to update with the move just made. Here's the problem: nowhere in movePieceTrad is boardHistory or any boardObject addressed. I have looked through with ctrl+f, every reference to boardHistory is in the main method.

In the code below, when I debug, lastInBoardHistory2 is different from what lastInBoardHistory1 was before movePieceTrad, but lastInBoardHistory1 also changes when I go through movePieceTrad, which makes no sense once again. What is going on?

lastInBoardHistory1 = boardHistory[boardHistory.Count - 1].getBoardValues();
movePieceTrad(arr[0], arr[1]);
lastInBoardHistory2 = boardHistory[boardHistory.Count - 1].getBoardValues();

Here is the code for the BoardObject class

namespace chess_v1
{
    class BoardObject
    {
        private int[,] boardValues;
        public int[,] possibleEnPassants;
        public int[,] castlePiecesMoved;
        public int turn = 0;

        public BoardObject(int[,] squareValues, int[,] pep, int[,]castleInfo, int inputTurn)
        {
            boardValues = squareValues;
            possibleEnPassants = pep;
            castlePiecesMoved = castleInfo;
            turn = inputTurn;
        }

        public int[,] getBoardValues()
        {
            return boardValues;
        }
    }
}
ProgrammingLlama
  • 36,677
  • 7
  • 67
  • 86
apc518
  • 193
  • 1
  • 4
  • 12
  • Please add the code for `movePieceTrad` – Zer0 Mar 11 '20 at 04:49
  • 1
    Arrays are [reference types](https://stackoverflow.com/questions/5057267/what-is-the-difference-between-a-reference-type-and-value-type-in-c). `lastInBoardHistory1` and `lastInBoardHistory2` presumably point to the same object in memory. – ProgrammingLlama Mar 11 '20 at 04:49
  • movePieceTrad contains most of the functionality in the entire program, it'd be a lot to paste in. What I can tell you is that the value of lastInBoardHistory1 doesn't change during movePieceTrad, I've put a watch on it and stepped through – apc518 Mar 11 '20 at 05:30
  • 1
    _"movePieceTrad contains most of the functionality in the entire program, it'd be a lot to paste in"_ -- **then don't**. It is your job, as the person asking the question, to take the time to construct a good [mcve] that illustrates your question. Likely this will turn out to be a duplicate of all the other "I'm reusing a reference type instance instead of creating a new instance for each value" questions already here. But if you think your question is different from that, you need to provide better context. See also [ask] and especially the articles linked at the bottom of that page. – Peter Duniho Mar 11 '20 at 05:44
  • Possible duplicate of https://stackoverflow.com/questions/4978989/adding-items-to-a-list-of-objects-results-in-duplicate-objects-when-using-a-ne – Peter Duniho Mar 11 '20 at 05:45
  • yes, this question is ultimately one of those "I'm reusing a reference type instance instead of creating a new instance for each value" but if I wanted to ask that question, I would have had to know how reference types work already, which is what I didn't know, hence the question. – apc518 Mar 11 '20 at 05:53

1 Answers1

1

Alright, I've solved it.

When constructing a BoardObject, I passed in the input 2D arrays and simply set them equal to my field 2D arrays in BoardObject. Since 2D arrays are arrays of references to places in memory rather than self-contained arrays of arrays, this meant that ultimately I was simply passing along the references in my main method board to the fields in each BoardObject. So, when I moved a piece (changing values within the main method's board) the BoardObject, actually every BoardObject, also changed.

The fix is that instead of passing in the reference arrays in the constructor of BoardObject, I pass in the values with nested for loops. I have tested the functionality that was supposed to have worked before this issue, and everything is working great now!

This is the new BoardObject code; I didn't have to change anything outside of this:

namespace chess_v1
{
    class BoardObject
    {
        public int[,] boardValues = new int[8,8];
        public int[,] possibleEnPassants = new int[8,2];
        public int[,] castlePiecesMoved = new int[2,3];
        public int turn = 0;

        public BoardObject(int[,] squareValues, int[,] pep, int[,]castleInfo, int inputTurn)
        {
            for (int i = 0; i < 8; i++)
            {
                for (int k = 0; k < 8; k++)
                {
                    boardValues[i, k] = squareValues[i, k];
                }
            }
            for (int i = 0; i < 8; i++)
            {
                for (int k = 0; k < 2; k++)
                {
                    possibleEnPassants[i, k] = pep[i, k];
                }
            }
            for (int i = 0; i < 2; i++)
            {
                for (int k = 0; k < 3; k++)
                {
                    castlePiecesMoved[i, k] = castleInfo[i, k];
                }
            }
            turn = inputTurn;
        }
    }
}
apc518
  • 193
  • 1
  • 4
  • 12