-3

The problem here is, that emptyRow and emptyCol variables somehow do not tend to work and are always equal 0, even when I actually assign them values at initialization! As well, do you see any mistakes that I could have made here?

Here's the code:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }
    // Declaration of Fields, used to conjoin methods
    RichTextBox[,] Grid = new RichTextBox[9, 9];
    int emptyRow, emptyCol;

    private void Form1_Load(object sender, EventArgs e)
    {
        // Creating a grid of Textboxes, for further use in a solving algorithm
        // and setting alignment to center for all boxes
        int i = 0;
        for (int row = 0; row < 9; row++)
        {
            for (int col = 0; col < 9; col++)
            {
                i++;
                Control[] foundControls = this.Controls.Find("Grid" + i.ToString(), false);
                foreach (Control currentControl in foundControls)
                {
                    if (currentControl.GetType() == typeof(RichTextBox))
                    {
                        RichTextBox currentRichTextBox = (RichTextBox)currentControl;
                        Grid[row, col] = currentRichTextBox;
                        currentRichTextBox.SelectionAlignment = HorizontalAlignment.Center;
                    }
                }
            }
        }
    }
    bool SolveSudoku()
    {
        FindUnassignedLocation();
        for (int num = 1; num <= 9; num++)
        {
            if (NoConflicts(emptyRow, emptyCol, num))
            {
                Grid[emptyRow, emptyCol].Text = num.ToString();
                return true;
            }
        }
        return false;
    }
    // Method to determine wether any fields are empty and if so, returning the first found
    bool FindUnassignedLocation()
    {
        for (int row = 0; row < 9; row++)
        {
            for (int col = 0; col < 9; col++)
            {
                if (Grid[row, col].Text == "")
                {
                    emptyRow = row;
                    emptyCol = col;
                    return true;
                }
            }
        }
        return false;
    }
    // Check if there are any conflicts in row or col or box
    bool NoConflicts(int row, int col, int num)
    {
        return !UsedInRow(row, num) && !UsedInCol(col, num) &&
            !UsedInBox(row - row % 3, col - col % 3, num);
    }
    // Check if there are any conflicts in row 
    bool UsedInRow(int row, int num)
    {
        for (int col = 0; col < 9; col++)
        {
            if (Grid[row, col].Text == num.ToString())
            {
                return true;
            }
        }
        return false;
    }
    // Check if there are any conflicts in column
    bool UsedInCol(int col, int num)
    {
        for (int row = 0; row < 9; row++)
        {
            if (Grid[row, col].Text == num.ToString())
            {
                return true;
            }
        }
        return false;
    // Check if there are any conflicts in box
    }
    bool UsedInBox(int boxStartRow, int boxStartCol, int num)
    {
        for (int row = 0; row < 3; row++)
        {
            for (int col = 0; col < 3; col++)
            {
                if (Grid[row + boxStartRow, col + boxStartCol].Text == num.ToString())
                {
                    return true;
                }
            }
        }
        return false;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        SolveSudoku();
    }

}

}

  • 2
    StackOverflow is not a service for debugging your buggy code. What you should do is: write out **by hand** all the steps you think your program should take for a *simple* case that does not work. Then follow along in the debugger each one of those steps. When your written-by-hand list does not match the observed behavior, that's where the bug is. – Eric Lippert Jun 24 '13 at 18:47
  • 1
    Eric's advice is absolutely spot on here, especially with a program of this nature that naturally lends itself to being broken down into smaller, manageable chunks of logic. Doing as suggested will help the structure of your program, and once your intended behaviour is clear in your mind, your bugs will stand out. – Chris Jun 24 '13 at 18:54
  • And so I did many times before posting here, but couldnt still understand why my two global variables emptyRow and emptyCol don't take assigned values, but stay the same. – Kamilczak020 Jun 24 '13 at 19:07
  • @Kamilczak020: have you actually added a breakpoint inside the innermost if() in FindUnassignedLocation()? Maybe the RichTextBox's Text property has some whitespace that should be cleared first. –  Jun 24 '13 at 19:15
  • @sgorozco: I checked for it, it does not. After I run the Solve method for the first time, it inputs the value in first box, but then, even if method FindUnassignedLocation finds the next empty column in row 1, it does not transfer it to emptyCol variable. – Kamilczak020 Jun 24 '13 at 19:21
  • I actually copypasted your code. I created a form with the RichTextBox grid using the _GridX_ nomenclature, and it is working as expected. The `emptyRow` and `emptyCol` fields are being set and retain their values across calls. So it must be something you are not posting. Aren't you recreating the form after processing? If that's the case, then the global variables (class fields would be their proper name) will be reset to either their declaration values, or to their default value if no declaration value is stated. –  Jun 24 '13 at 19:51
  • @sgorozco: That was it! Thank you a lot, i didn't notice that. – Kamilczak020 Jun 24 '13 at 21:11

1 Answers1

1

I've found a few errors in your code:

Line:26 Control[] controlsFound = this.Controls.Find("Grid" + i.ToString(), false); The variable controlsFound is never used. It seems to me like you should be using it in the foreach loop below.

I think your main problem is the call to FindUnassignedLocation(); It returns a bool, but you are not checking it. It should probably be:

bool SolveSudoku()
{
    if (FindUnassignedLocation())
    {
        for (int num = 1; num <= 9; num++)
        {
            if (NoConflicts(emptyRow, emptyCol, num))
            {
                Grid[emptyRow, emptyCol].Text = num.ToString();
                return true;
            }
        }
    }
    return false;
}
Richard Seal
  • 4,248
  • 14
  • 29
  • Oh right I posted the version with wrong name there. But my main problem which as far as I think shouldn't exist, is that (as enclosed in question ) two global variables dont tend to work properly. – Kamilczak020 Jun 24 '13 at 19:04