Sudoku validator for display a larger grid

I have an issue with my Sudoku checker... two questions actually... I will give you the code so far as to what I have.

void printMenu();
bool readGrid(string fName, int grid[9][9]); //function to load and read the input files
int displayGrid(int grid[][9]); //function to display grid
bool checkColumns (int grid[][9]); //function to check columns for duplicates
bool checkRow (int grid[][9]); //function to check rows for duplcates
bool checkMini (int grid[][9]); // function to check minigrids for duplicates



int main()
{

int grid[9][9]; //9X9 grid

string fName; //file name
char choice = '*';
while (choice != 'Q')
{
printMenu();
cin >> choice;
switch (toupper(choice))
{
case 'L' : cout << "Enter file name" << endl;
cin >> fName; //enter file name
if( !readGrid(fName, grid)) //if function readGrid returns a false scenario
cout << "invalid file input!" << endl;
break;
case 'D' : displayGrid (grid);
break;
case 'R' : if (!checkRow(grid)) //if function checkRow returns a false scenario, it will output the required message as coded in the function
break;
else
cout << "All Rows are correct." << endl; //message to ouput for the true scenario
break;
case 'C' : if(!checkColumns(grid)) ////if function checkColumnsreturns a false scenario, it will output the required message as coded in the function
break;
else
cout << "All Columns are correct." << endl; //message to output for the true scenario
break;
case 'M' : if (!checkMini(grid))
break;
else
cout << "All Minigrids are correct."<< endl; //message to output for the true scenario
case 'Q' : break;
default : cout << "Invalid option " << endl; cin.ignore(100,'\n');
}

}

return 0;
}


void printMenu()
{
cout << "\n\tSudoku Checker " << endl << endl;
cout << "\t L\t Load file " << endl;
cout << "\t D\t Display " << endl;
cout << "\t C \t Check columns " << endl;
cout << "\t R \t Check rows " << endl;
cout << "\t M \t Check minigrids" << endl;
cout << "\t Q\t Quit " << endl;
cout << " Rows and columns are labelled from 0 to 8 " << endl;
cout << endl;
}

bool readGrid(string fName, int grid[9][9])
{
ifstream fileName;

fileName.open(fName.c_str());

if (! fileName) //if file doesn't not exist
return false;

while (! fileName.eof()) //if file is detected, fill in the array for grid
{
for (int i = 0; i < 9; i++)
for (int j = 0; j < 9; j++)
fileName >> grid[i][j];
}
return true;
}


int displayGrid(int grid[][9])
{
for (int row = 0; row < 9; row++) //2D array to go through both rows and columns
{
for (int col = 0; col < 9; col++)
{
cout << grid[row][col] << " "; //fill in the sudoku grid (seperated by a space)
}
cout << endl;
}
}

bool checkRow (int grid[][9])
{
bool status = true; //a status check
for (int row = 0; row<9; row++) // go through the rows of the 9X9 grid)
{
for (int check =1; check <9; check++) //a check variable to compare the rows
{
int occurance = 0; // a flag
for (int column = 0; column <9; column++) //go through each column of the 9X9 grid)
{
if (grid[row][column] == check) // if the cell matches the number in the check variable
{
occurance++; //increase the occurance flag to output the result
}
}
if (occurance > 1) //if there are more than one occurances
{
cout << "Row " << row << " is incorrect!" << endl;
status = false;
}
}

}
return status;
}


bool checkColumns (int grid[][9])
{
bool status2 = true; //a status check
for (int column = 0; column<9; column++) // go through the columns of the 9X9 grid)
{
for (int check =1; check <9; check++) //a check variable to compare the columns
{
int occurance = 0;
for (int row = 0; row<9; row++) // go through the rows of the 9X9 grid)
{
if (grid[row][column] == check) // if the cell matches the number in the check variable
{
occurance++;
}
}
if (occurance > 1)
{
cout << "Column " << column << " is incorrect!" << endl;
status2 = false;
}
}

}
return status2;
}


bool checkMini (int grid[][9])
{
bool status3= true;
int container[9];

for (int row = 0; row < 9; row++)
{
for (int column = 0; column < 9; column ++)
{

{
int occurances = 0;
int MiniCol = (column/3)*3; //calculates the minigrids for column (the 3 cells)
int MiniRow = (row/3)*3; // calculates the minigrids for the row (the 3 cells)

for (int nextRow = 0; nextRow < MiniRow +3; nextRow++) //loop to go through the 3X3 minigrids
{
for (int nextCol = 0; nextCol < MiniCol + 3; nextCol++)
{
container[9] == grid[row][column];
{
if (grid[nextRow][nextCol] == container[9])
{
occurances++;
}
}
}

if (occurances > 1)
{
cout << "Incorrect minigrid starting at row " << row << " column " << column << "."<< endl;
status3 = false;
}

}

}

return status3;
}
}
}

my question is, notice how we are asked to input a file. I get a file that looks like this

5 8 9 6 4 7 2 1 3
6 2 4 3 1 9 5 7 8
1 3 7 5 8 2 9 6 4
9 5 8 7 3 1 4 2 6
2 7 1 4 6 8 3 5 9
4 6 3 9 2 5 1 8 7
3 1 2 8 7 4 6 9 5
8 4 5 2 9 6 7 3 1
7 9 6 1 5 7 8 4 2
5 8 9 6 4 7 2 1 3
6 2 4 3 1 9 5 7 8
1 3 7 5 8 2 9 6 4
9 5 8 7 3 1 4 2 6
2 7 1 4 6 8 3 5 9
4 6 3 9 2 5 1 8 7
3 1 2 8 7 4 6 9 5
8 4 5 2 9 6 7 3 1
7 9 6 1 5 7 8 4 2

Well they are two similar grids, but the point it, that the file extends beyond 81 grids. I need to a) cut the grid so that its 9X9, but when I do it with the current code (printGrid) it gives me the second half of the grid, and I need the first half of the grid. I know i will need to add an if case to the printGrid function, but not sure what... my take is that I should do something like

(if grid[row][col] > 81)
{
cout << grid[row][col]

}

but there I need to know how to compute the first half of the grid and not the bottom half, which is what the program is doing.


Also, the second question is: I will need to compute scenarios where there are other characters in the grid (a, b, c d, %, # etc), it will say invalid characters. The plan is to change the int's to char

Would something like
(if !(grid[row][col] >0 && < 9)
cout << " invalid character detected.";

be right?
On your first problem. The source of that problem is in your readGrid function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool readGrid(string fName, int grid[9][9])
{
  ifstream fileName;

  fileName.open(fName.c_str());

  if (! fileName) //if file doesn't not exist
    return false;

  while (! fileName.eof()) //if file is detected, fill in the array for grid
  {
    for (int i = 0; i < 9; i++)
      for (int j = 0; j < 9; j++) 
        fileName >> grid[i][j];
  }
  return true;
}


this code will continue reading the file in, and repeatedly filling in your 9x9 grid until eof has been reached. Once it has looped through the grid once, it's going to start looping through it again if eof has not been reached. When the function finally returns, your 9x9 grid will be populated with the last 81 values read in, not the first.

Your eof check should be nested inside the two for loops (As an if() check, not a while loop), and once you've filled in the full 9x9 grid, you return from the function, even if you haven't reached eof. You should also have code in place to return false if you reach eof before filling in the entire grid.

On the second question, if you change from type int to type char, just check that the value is <= 9. Chars cannot be negative, so there's no need for a lower bound check. And the check should be inclusive, since 9 is a valid entry. "< 9" will return false if the entry is 9.
Last edited on
Topic archived. No new replies allowed.