Reputation: 67
I am trying to loop through my 2D array which is of type Cell Cell m_grid[9][9]
- when the current value in the array is not equal to the value that is in the row, column or 3x3 block of the array, I need to add this to my int m_candidateList[9]
array. The 2D array itself contains an unsolved sudoku puzzle in a 9x9 format.
How do I access the rows, columns of the 2D array so I can check them against the current value that the array is at in the loop?
This is in my SudokuPuzzle.cpp file where I am wanting to get the current puzzle value and check it against all the values in that row, column and 3x3 block of the sudoku puzzle.
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
//if number doesn't appear in row
//if number doesn't appear in col
//if number doesn't appear in 3x3
//add number to candidate list
}
}
My Cell.cpp which holds data member for each individual value in the puzzle
Cell::Cell(void) {}
Cell::~Cell(void) {}
void Cell::SetValue(int value)
{
m_value = value;
if (m_value = 0)
{
m_given = true;
}
}
And Cell.h
#pragma once
class Cell
{
public:
Cell(void);
~Cell(void);
void SetValue(int n);
private:
int m_candidateList[9];
int m_value;
bool m_given;
};
Upvotes: 1
Views: 75
Reputation: 409
Most of this answer is just taken from the user that commented.
I can see that you have have a setter function SetValue(int n) but to be able to access what you already have stored then you will also need a setter function so that you can make a call to your Cell object and have access to this value. Let's call this setter function getValue().
Notice that getValue returns a boolean but could assign a value to the int passed by reference. This allows us to use the getValue function to do 2 things, firstly it checks that a value has been assigned to this Cell, and secondly if the value has been assigned then you pass it back via the variable that you passed a reference.
Cell.cpp
Cell::Cell(void) {}
Cell::~Cell(void) {}
void Cell::SetValue(int value)
{
m_value = value;
if (m_value = 0)
{
m_given = true;
}
}
bool Cell::getValue(int& n)
{
if(m_given)
n = m_value;
return m_given;
}
void Cell::insertCandidate(int n)
{
m_candidateList[m_candidate_counter++] = n;
}
Cell.h
#pragma once
class Cell
{
public:
Cell(void);
~Cell(void);
void SetValue(int n);
bool getValue(int& n);
void insertCandidate(int n);
private:
int m_candidate_counter = 0;
int m_candidateList[9];
int m_value;
bool m_given;
};
Now using the getter you are able to loop through the 2d array of cells as you now have a getter function.
SudokuPuzzle.cpp
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
for (int number = 1; number <= 9; number++)
{
if(!exists_in_row(number, i) &&
!exists_in_column(number, j) &&
!exists_in_square(number, i, j))
{
m_grid[i][j].insertCandidate(number);
return;
}
}
}
}
You will also need to create the helper functions. E.g. in SudokuPuzzle.cpp
bool SudokuPuzzle::exists_in_row(int number, int row)
{
int number_from_cell = 0;
for (int col = 0; col < 9; ++col)
{
if(m_grid[row][col].GetValue(number_from_cell) && number_from_cell == number)
return true;
}
return false;
}
bool SudokuPuzzle::exists_in_column(int number, int col)
{
int number_from_cell = 0;
for (int row = 0; row < 9; ++row)
{
if(m_grid[row][col].GetValue(number_from_cell) && number_from_cell == number)
return true;
}
return false;
}
bool SudokuPuzzle::exists_in_square(int number, int row, int col)
{
int row_start = 3*(row/3);
int col_start = 3*(col/3);
int number_from_cell = 0;
for (int r = 0; r < 3; ++r)
{
for (int c = 0; c < 3; ++c)
{
if (m_grid[row][col].GetValue(number_from_cell) && number_from_cell == number)
return true;
}
}
return false;
}
Also you are making your life a bit difficult by creating the Cell object and having a 2D array of Cells. The answer would have probably been a lot more straight forward if you just used a type int m_grip[9][9]. Also for m_candiateList I didn't make any change to this data type but please look into std::set to avoid storing duplicates and also avoiding memory problems. E.g. Imagine you don't add protection code and you try to access m_candidateList[10], this will give you a segmentation fault.
Upvotes: 1
Reputation: 87944
So I'll just try to outline the logic. I'll ignore the Cell
class because I don't have full details of it and I'll just assume your grid is an array of integers.
The thing that is really important is to break up what is quite a complex piece of code into separate functions. That will make the code easier to write, easier to debug and easier to understand.
Here's my take, only suggestions
for (int row = 0; row < 9; row++)
{
for (int col = 0; col < 9; col++)
{
for (int number = 1; number <= 9; number++)
{
if (!number_in_row(number, row) &&
!number_in_column(number, col) &&
!number_in_square(number, row, col))
{
add_number_to_candidates(number, row, col);
}
}
}
}
bool number_in_row(int number, int row)
{
for (int col = 0; col < 9; ++col)
if (m_grid[row][col] == number)
return true;
return false;
}
Function number_in_column
is very similar. Number_in_square
is the most complex one.
bool number_in_square(int number, int row, int col)
{
// calculate start of 3x3 square
int row_start = 3*(row/3);
int col_start = 3*(col/3);
for (int r = 0; r < 3; ++r)
for (int c = 0; c < 3; ++c)
if (m_grid[row_start + r][col_start + c] == number)
return true;
return false;
}
I've left out the add_number_to_candidates
function as I'm not sure how to write that with the information given. Hopefully it will be clear to you.
I hope that gives you some ideas. All code completely untested.
Upvotes: 2