2D Array with Restricted bounds

I have a 2D bool array with 400 elements with a random assortment of spaces " " and asterisks '*' where '*' is true and " " is false. I need to create a function that will take in two arguments that will locate a single element. This element will be the center of restricted 3x3 bounds within the 400 elements. So, let's say the argument sent in is centered at [1][8], then the left over elements will be:

[0][7], [0][8], [0][9]
[1][7], center, [1][9]
[2][7], [2][8], [2][9]

Let's say elements [1][7] and [1][9] have an '*' so they are bool true.
Does anyone have any suggestions on how to restrict bounds checking in this manner so I can iterate through and count the number of true values? I should also point out that if the 3x3 grid has its center located at a very corer of the 400 element grid then only 3 possible elements will exist for true or false values. Also, I have a requiremnt to go with the bounds checking that says: "This function must use assert to exit the program if the row or column is out-of-bounds."

Output example that I am testing on.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  01234567890123456789
 0            *  **
 1*   **   *       * *
 2
 3  * *       *     *
 4  *              *
 5         *        *
 6**               *
 7 * *     *       *
 8     **   *   *  * *
 9*  *   *   * *
10        *     * ***
11 *       *****     *
12  *  * *         *
13    **   *  **
14 * *   ****        *
15   *             **
16    *** * **      *
17  *          ** *
18      *       *
19*  *            **
I should also point out another requirement:

" In this function you must use your "get()" function to access the matrix, instead of accessing your 2D array data member directly. So, if your data member is named "m", you'll say "get(row, col)" instead of "m[row][col]". This will be a safer programming practice, since the get() function will do range checking for you (i.e., it will make sure that row and col are not out-of-bounds of the 2D array)."

My get function:
Need to add, "This function must use assert to exit the program if the row or column is out-of-bounds." Not sure how?
1
2
3
4
int boolMatrix::get(int row, int col)const
{
	return array[row][col];
}

With assert.
1
2
3
4
5
int boolMatrix::get(int row, int col)const
{
	assert(row>=0 && row<ROW_MAX && col>=0 && col<COL_MAX);
	return array[row][col];
}


Without assert.
1
2
3
4
5
6
7
int boolMatrix::getChecked(int row, int col)const
{
	if (row>=0 && row<ROW_MAX && col>=0 && col<COL_MAX) {
		return get(row,col);
	}
	return 0;
}


As for the 3x3 thing, perhaps
1
2
3
4
5
6
int threebythree(int cRow, int cCol ) {
  for ( int r = cRow - 1 ; r <= cRow+1 ; r++ ) {
    for ( int c = cCol - 1 ; c <= cCol+1 ; c++ ) {
    }
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <iostream>
#include <iomanip>
#include <vector>
#include <random>

class Matrix
{
public:
    int get( int x, int y) const;
    Matrix();  // constructor
    friend std::ostream & operator << ( std::ostream &, const Matrix & ); 
private:
    std::vector<std::vector<bool>> mMatrix;
    std::default_random_engine  mEngine;
    std::uniform_int_distribution<> mDistribution;

};

Matrix::Matrix()
: mMatrix( 20, std::vector<bool>(20, false))
, mEngine( std::random_device{}())
, mDistribution(0,4)
{
    for (std::size_t row = 0; row <  mMatrix.size(); ++row)
        for (std::size_t col = 0; col < mMatrix[row].size(); ++col)
            if (mDistribution( mEngine ) == 0)
                mMatrix[row][col] = true;
}

std::ostream & operator << (std::ostream & os, const Matrix & matrix)
{
    auto & m = matrix.mMatrix;
    os << "   ";
    for (std::size_t col = 0; col < m[0].size(); ++col)
        os << std::setw(3) << col;
        
    for (std::size_t row = 0; row < m.size(); ++row)
    {
        os << std::endl << std::setw(3) << row;
        for (std::size_t col = 0; col < m[row].size(); ++col)
        {
            if (m[row][col])
                os <<std::setw(3) << '*';
            else os << std::setw(3) << ' ';
        }
    }
    os << std::endl;
    return os;
}
int Matrix::get( int x, int y) const
{
    int & row = y;
    int & col = x;
    auto & m = mMatrix;
    
    if ( row < 0 || row > m.size()-1 || col < 0 || col < m[0].size()-1)
        exit( EXIT_FAILURE );
        
    int sum = 0;    
    
    sum += m[row][col];    // middle field
    
    if (col > 0)              // left field
        sum += m[row][col-1];
        
    if (col < m[0].size()-1)  // right field
        sum += m[row][col+1];
        
    if (row > 0)               // upper field
        sum += m[row-1][col];
    
    if (row < m.size()-1)         // lower field
        sum += m[row+1][col];
        
        
        
    if (row > 0 && col > 0)  // top left field
        sum += m[row-1][col-1];
        
    if (row > 0 && col < m[0].size()-1)  // top right field
        sum += m[row-1][col+1];
        
    if (row < m.size()-1 && col > 0)    // bottom left field
        sum += m[row+1][col-1];
        
    if (row < m.size()-1 && col < m[0].size()-1) // bottom right field
        sum += m[row+1][col+1];
        
    return sum;
}

int main()
{
    Matrix matrix;
    std::cout << matrix;
}
Last edited on
My get() function works if I call it from main to check if a single element is true (prints 1) or false (prints 0). However, if I call it from withing the 3x3 function, which is named neighborCount(), then I am displaying a single zero when there are two '*' located in the 3x3 grid located where [1][8] is the center. I feel that the code within neighborCount() is good , but not sure. Is there a problem with the code within the neighborCount() function or is there something wrong with the way I am communicating data between the different functions?

To clarify the column number labels above which repeat 0-9 and again 0-9. That is only couted that way and the real values for array iterating are 0-19 which is const int NUM_ROWS. So, the element I positioned as the center of the 3x3 is actually [1][18], and you can see that there are two '*' on either side of that element that I am testing on so I should get a count of two, and the rest of the 3x3 grid around [1][18] are spaces so they should be false.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
// In main
matrix1.print();
cout << matrix1.neighborCount(1,18);

}




boolMatrix::boolMatrix()
{
	for (int row = 0; row < NUM_ROWS; row++) {
		for (int col = 0; col < NUM_COLS; col++) {

			array[row][col] = { false };
			array[row][col] = rand() % 100 > 80;
		}
	}
}



void boolMatrix::print()
{
	cout << setw(3);
	for (int col = 0; col < NUM_ROWS - 10; col++) {
		cout << col;
	}
	for (int col = 0; col < NUM_ROWS - 10; col++) {
		cout << col;
	}
	cout << endl;
	
	for (int row = 0; row < NUM_ROWS; row++) 
	{
		cout << setw(2) << row;
		for (int col = 0; col < NUM_COLS; col++) {

			if (array[row][col] == false) {
				cout << " ";
			}
			else cout << "*";
		}
		cout << endl;
	}
	
}





int boolMatrix::neighborCount(int row, int col)
{
	int True = 0;
	for (int i = row - 1; i <= row + 1; i++) {
		for (int j = col - 1; j <= col + 1; j++) {

			if (get(i, j) == true)
				True++;

			return True;
		}
	}
}





int boolMatrix::get(int row, int col)const
{
	assert(row >= 0 && row < NUM_ROWS && col >= 0 && col < NUM_COLS);
	return array[row][col];
}








Last edited on
@ nuderobmonkey, I missed your code until I refreshed my page. I appreciate all the code but unfortunately there are things in your code that I have not covered in class yet such as vectors, and std. Also, the get function is supposed to get the value of a single element and return it, and the neighborCount function is supposed to call get.


Instructions for a couple of the functions:

get: return the current contents of a single array element. Use arguments to indicate the row and column of the array element that should be returned. This function must use assert to exit the program if the row or column is out-of-bounds.

neighborCount:Given two arguments that indicate the row and column of a particular cell in the matrix, this function returns the number of neighbors that have the value "true". Most positions in the grid have 8 neighbors like the center square in a tic-tac-toe game. The four corner positions have only 3 neighbors each. The remaining positions around the edge of the grid have 5 neighbors each. This function must use assert to exit the program if the row or column is out-of-bounds.

Additional neighborCount() Requirement: In this function you must use your "get()" function to access the matrix, instead of accessing your 2D array data member directly. So, if your data member is named "m", you'll say "get(row, col)" instead of "m[row][col]". This will be a safer programming practice, since the get() function will do range checking for you (i.e., it will make sure that row and col are not out-of-bounds of the 2D array).
Last edited on
Sorry @stoneJax, I forgot that this is the beginners forum so I apologize me for my code (which would be better understand by an advanced programmer. But I invite you, feeling free to ask if something is unclear to you or where you want some further explanations. If it would be still too hard for you, trying to understand my code, you could ignore the most stuff of that. The core stuff (so what matters for getting a solution) is the in my Matrix::get() method.

Btw: I'm a hobby coder with no schooling at programming, but I learned the most C++ stuff from the great book from Bjarne Stroustrup: "Programming: Principles and Practice using C++" second edition:
https://www.amazon.com/Programming-Principles-Practice-Using-C-ebook/dp/B00KPTEH8C/ref=sr_1_2?keywords=bjarne+stroustrup&qid=1554627491&s=gateway&sr=8-2

Sorry for my bad Englisch knowledge (that's the reason why I rather serve here at the forum with code than with good explainations).
I've heard of that book and would like to check it out sometime. At the moment school pretty much consumes me.

In trying to match my instructions, I went over your code in the get function to see if I can make sense of it enough to translate the concepts to my neighborCount function and then call get to identify if an element is true or not but I couldn't make sense of it enough.

Would you be able to look at the last code I pasted and tell me where it is wrong? Does it look like it has potential in going in the right direction?

Looks ok :)

But your boolMatrix::get() function is not good. That's because the 'assert' will compiled away if you compile without debug flags.
Last edited on
This should work:
1
2
3
4
5
6
int boolMatrix::get(int row, int col) const
{
    if (row >= 0 && row < NUM_ROWS && col >= 0 && col < NUM_COLS)
        return array[row][col];
    else return 0;
}

Sorry, I overlooked that your requirement forces you for using 'assert' if your boolMatrix::get() method detects 'out of range' values :(
I got the last code I pasted above to work. Turns out that I had my return statement in the wrong location.

Now I am trying to add one final touch to this function. Let's say the argument [0][0] comes in as the center of the 3x3 matrix. That means the first row and the first column are out of bounds and there are only four elements left in bounds. I am trying to use an if statement to control the counter and I got it to work for the [0][0] element. However, it does not work if I send arguments to make the center of the 3x3 matrix to be located in the three other corners of of the 20x20 matrix.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int boolMatrix::neighborCount(int row, int col)
{
	int True = 0;
	for (int i = row - 1; i <= row + 1; i++) {
		for (int j = col - 1; j <= col + 1; j++) {
                         
                        if ((i >= 0 && i <= NUM_ROWS) && (j >= 0 && j <= NUM_COLS)) {
				if (get(i, j) == true)
				True++;
			}
			

			
		}
	}
        return True;
}
I figured it out. Just had to remove a couple of the equal signs in the if statement.
Topic archived. No new replies allowed.