Search code examples
c#backtrackingsudoku

How to store unique copy of object in a list, in this case a semi solved jagged array of sudoku cells


How can I store data (list<list<objects>>) in a way that I can access a previous state?

This is for a Sudoku solver written in c#. I have tried generating a "higher level" list (List<List<List<object>>>) and storing in this, however it seems this list only stores a pointer or reference to my object since changes later down the line also seem to affect the stored instances.

void publics() // only in void for display purpose, acctualy declared in class
{
    List<List<Cell>> SBoard = new List<List<Cell>>(); // list used in calculations

    List<List<List<Cell>>> BoardListBackup = new List<List<List<Cell>>>(); // list to store SBoards

    int GuessLevel = 0; // to keep track of how many guesses
}
    void guess()
    {
        BoardListBackup.Add(SBoard); // store current board
        Console.WriteLine("stored copy of board");

        for (int i=0;i<9;i++)
        {
            for(int j=0;j<9;j++)
            {
                if (SBoard[i][j].Value == "0")
                {
                    BoardListBackup.Add(SBoard); // possibly saves an instance of list at current state
                    SBoard[i][j].Value = SBoard[i][j].Possibly[0].ToString(); // guess first possible value of first unfilled cell
                    GuessLevel++;
                    UpdatePossibleValues();
                    Console.WriteLine("Guessing [{0}],[{1}] = {2}", i, j, SBoard[i][j].Possibly[0].ToString());
                    PrintBoardValues();
                    if (error == false)
                    {
                        InsertObvious();
                    }
                    else if (error == true)
                    {
                        Console.WriteLine("Bad guess, reverting board");
                        SBoard = BoardListBackup[GuessLevel - 1]; // what is the problem here??? Board is not rewerting?
                        BoardListBackup.RemoveAt(BoardListBackup.Count-1); // uncertain of syntax here
                        SBoard[i][j].RemovePossible(SBoard[i][j].Possibly[0].ToString()); // remove wrong guess from options
                        GuessLevel--;
                        PrintBoardValues();
                    }
                }
            }
        }

When error == true I expect SBoard to revert to the state saved in BoardListBackup[GuessLevel-1] but it just remains in it's current state. So far i'm thinking the only solution is to save as text file but since I have to save both cell values and possible values for individual strings I feel it would be a difficult logic.


Solution

  • this list only stores a pointer or reference to my object

    Except for value types, most instances are, under the hood, references to a memory location. The name may change but the underlying reference does not. Technically everything is a reference to memory, but reference types in C# don't change while value types get new reference locations as they change.

    I expect SBoard to revert to the state saved ...

    What state is actually saved? There is no code to do an actual save/snapshot, for it only does updates, nothing is literally saved.

    How can I store data (list>) in a way that I can access a previous state?

    You will need to create a copy constructor of the class you want to store, and store it in a LIFO stack object. Then when you need to, go back, walk back/pop the stack to the state you want.


    See C# Stack to get you started.