Having trouble computing the number of occupied neighbors each cell in the array has. Any help would be greatly appreciated.

Array[rows][cols-1]
 Array[rows+1][cols-1]
 Array[rows-1][cols]
 Array[rows][cols]
 Array[rows+1][cols]
 Array[rows-1][cols+1]
 Array[rows][cols+1]
 Array[rows+1][cols+1]

Recommended Answers

All 16 Replies

Given we are at position (x,y) in a 2d Cell environment, its neighbors are

N[x][y+1]
N{x+1][y+1]
N[x+1][y]
N[x+1][y-1]
N[x][y-1]
N[x-1][y-1]
N[x-1][y]
N[x-1][y+1]

that assumes that the position (x,y) are not in the edge of the Array

Assuming you have some function IsOccupied that returns true if the cell is occupied and the array of cells is stored in a 2D array, N , then you could do something like:

int neighbours = 0;
for( int i = row - 1; i <= row + 1; ++i ){
   for( int j = col - 1; j <= col + 1; ++j ){
      neighbours += IsOccupied( N[i][j] ) ? 1 : 0;
   }
}

Assuming you have some function IsOccupied that returns true if the cell is occupied and the array of cells is stored in a 2D array, N , then you could do something like:

int neighbours = 0;
for( int i = row - 1; i <= row + 1; ++i ){
   for( int j = col - 1; j <= col + 1; ++j ){
      neighbours += IsOccupied( N[i][j] ) ? 1 : 0;
   }
}

Would it return the number of neighbors each cell has or just the fact that it has neighbors?

Given we are at position (x,y) in a 2d Cell environment, its neighbors are

N[x][y+1]
N{x+1][y+1]
N[x+1][y]
N[x+1][y-1]
N[x][y-1]
N[x-1][y-1]
N[x-1][y]
N[x-1][y+1]

that assumes that the position (x,y) are not in the edge of the Array

Error checking would help with stepping out of the bounds of the array, how would I get the number of neighbors each cell has?

Basically if the cells surrounding the cell being checked has a * it is considered a neighbor and it should move on to check the next cell. I need it to show how many neighbors each cell has. Then execute a series of statements based upon how many neighbors the cell has.I have tried many times but I am getting no where.

for(row=0; row<22; row++)
{
 for(int col=0; col<80; col++)
 {
 if(Array[row][col-1] = '*'
  {
       [row][col]++;
   }
 if(Array[row+1][col-1] = '*'
    {
        [row]++ [col]++;
        }
 if(Array[row-1][col] = '*'
    {
        [row][col]++;
       }
 if(Array[row][col]  = '*'
    {
        [row][col]++;
    }
 if(Array[row+1][col] = '*'
    {
        [row][col]++;
       }
 if(Array[row-1][col+1] = '*'
    {
        [row][col]++;
    }
 if(Array[row][col+1] = '*'
    {
        [row][col]++;
      }
 if(Array[row+1][col+1] = '*'
    {
        [row][col]++;
        }

One thing that you need to remember is that not every location has all eight "neighbor" locations. For example, if you have a 3x3 array called "values", and you are at values[0][0], you will only have 3 "neighbors", they will be values[0][1], values[1][0], and values[1][1]. The remaining 5 "neighbor" locations will be invalid array elements and attempting to access them should cause a program error.

Additionally, the element values[1][1] will be the only element in this particular array that has 8 neighbors; all other elements will be edge locations and will have either 3 or 5 neighbors depending on if it's a "corner" location or not. Where those neighbors are located in relation to the current element depends on where the current element is located in the overall matrix/array:

  • Elements on the left edge will have neighbors to the immediate right, (values
  • [col+1]) and directly above and below, again depending on the "corner" condition.
  • Elements on the right edge will have neighbors to the immediate left, (values
  • [col-1]) and directly above and below, depending on the "corner" condition.

The first thing you need to do is check to see if your current location is an edge location. Then, you can use that information to control the limits of your search.

One thing that you need to remember is that not every location has all eight "neighbor" locations. For example, if you have an array called "values", and you are at values[0][0], you will only have 3 "neighbors", they will be values[0][1], values[1][0], and values[1][1]. The remaining 5 "neighbor" locations will be invalid array elements and attempting to access them should cause a program error.

The first thing you need to do is check to see if your current location is an edge location. Then, you can use that information to control the limits of your search.

I have the two for loops at the top to make sure it does not go outside of the array. I need it to calculate the number of neighbors each cell has and take that number and execute some other statements based of the number of neighbors so far here is the code I have so far:

for(row=0; row<22; row++)
{
 for(int col=0; col<80; col++)
 {
 if(inf[row][col-1] = '*'{
  neighbors++;
if(inf[row+1][col-1] = '*'{
   neighbors++; }
if(inf[row-1][col] = '*'{
    neighbors++; }
 if(inf[row][col]  = '*'{
    neighbors++; }
 if(inf[row+1][col] = '*'{
    neighbors++; }
 if(inf[row-1][col+1] = '*'{
    neighbors++; }
 if(inf[row][col+1] = '*'{
    neighbors++; }
 if(inf[row+1][col+1] = '*'{
    neighbors++; }

I have the two for loops at the top to make sure it does not go outside of the array. I need it to calculate the number of neighbors each cell has and take that number and execute some other statements based of the number of neighbors so far here is the code I have so far:

for(row=0; row<22; row++)
{
 for(int col=0; col<80; col++)
 {
 if(inf[row][col-1] = '*'{
  neighbors++;
if(inf[row+1][col-1] = '*'{
   neighbors++; }
if(inf[row-1][col] = '*'{
    neighbors++; }
 if(inf[row][col]  = '*'{
    neighbors++; }
 if(inf[row+1][col] = '*'{
    neighbors++; }
 if(inf[row-1][col+1] = '*'{
    neighbors++; }
 if(inf[row][col+1] = '*'{
    neighbors++; }
 if(inf[row+1][col+1] = '*'{
    neighbors++; }

Unfortunately, no. The problem is that you, in fact, are going outside the limits of your array. Under normal circumstances, the format of your for loops is correct, but this is a different situation because you are manipulating the values of your loop control variables (by adding and subtracting 1) inside the loop.

When row=0 all your conditions that reference a "row-1" element go outside the limits of the array by attempting to access inf[-1][*]. The same is true when col = 0, you are trying to access inf[*][-1].
You also have similar issues when you are at the upper limits. When row=21, you are attempting to access inf[22][*] and when col=79, you are attempting to access inf[*][80] which are not technically legal locations.

Unfortunately, no. The problem is that you, in fact, are going outside the limits of your array. Under normal circumstances, the format of your for loops is correct, but this is a different situation because you are manipulating the values of your loop control variables (by adding and subtracting 1) inside the loop.

When row=0 all your conditions that reference a "row-1" element go outside the limits of the array by attempting to access inf[-1][*]. The same is true when col = 0, you are trying to access inf[*][-1].
You also have similar issues when you are at the upper limits. When row=21, you are attempting to access inf[22][*] and when col=79, you are attempting to access inf[*][80] which are not technically legal locations.

okay, I understand now. How can I fix this problem?

You're going to have to add more conditions to your detection statements. You are most likely going to have to use the Logical operators (AND '&&' and OR '||') to expand the conditions in your if statements.

Make sure you take the time to think about it more, it may be possible to group your statements in some logical fashion and save yourself some code.

I noticed that your counter is a single variable. You may want to consider doing something more like this:

const int ROWS = 10, COLS = 20;  //set the constants to the appropriate values for your program

char Array[ROWS][COLS] = {'\0'};      //declare the data array
int neighborCounts[ROWS][COLS] = {0}; //declare a counter array

This will allow you to keep a unique counter for each location in your data array, which it sounds like you need.

You can do that like this.

1st of all initialize 2 arrays like this:
dx[8]={1,-1,0,0,1,1,-1,-1}
dy[8]={0,0,1,-1,1,-1,1,-1}

assume that your current position is x,y;

declare 2 integers;
nx,ny;

do a for to catch all the neighborhoods:

for(int i=0;i<8;i++)
{
  nx=x+dx[i];
  ny=y+dy[i];
  if(nx<n && nx>=0 && ny>=0 && ny<m)
  {
      do what you want to do
  }
}

where n is the number of rows, m is the number of columns.

You can do that like this.

1st of all initialize 2 arrays like this:
dx[8]={1,-1,0,0,1,1,-1,-1}
dy[8]={0,0,1,-1,1,-1,1,-1}

assume that your current position is x,y;

declare 2 integers;
nx,ny;

do a for to catch all the neighborhoods:

for(int i=0;i<8;i++)
{
  nx=x+dx[i];
  ny=y+dy[i];
  if(nx<n && nx>=0 && ny>=0 && ny<m)
  {
      do what you want to do
  }
}

where n is the number of rows, m is the number of columns.

This still has the same array boundary issues that the OP's original code did, it just causes them in a different way. This is how I addressed it:

//...

//declare needed constants
const int ROWS = 10, COLS = 20;

int main() {
  //...

  char Array[ROWS][COLS] = {'\0'};      //declare the data array
  int neighborCounts[ROWS][COLS] = {0}; //declare a counter array

  //...

  for (int y = 0; y < ROWS; ++y) {      //begin y for
    for (int x = 0; x < COLS; ++x) {    //begin x for
      int xLeft = x, xRight = x, yTop = y, yBottom = y; //declare and initialize limiters

      //prep your x limits
      if ((x == 0) && (x <= (COLS-2))) {        //check for left edge
        ++xRight;   //adjust right limiter
      } else if ((x == (COLS-1)) && (x > 0)) {  //check for right edge
        --xLeft;    //adjust left limiter
      } else {                                  //any other location
        ++xRight;   //adjust right limiter
        --xLeft;    //adjust left limiter
      }

      //prep your y limits
      if ((y == 0) && (y <= (ROWS-2))) {        //check for top edge
        ++yBottom;  //adjust bottom limiter
      } else if ((y == (ROWS-1)) && (y > 0)) {  //check for bottom edge
        --yTop;     //adjust top limiter
      } else {                                  //any other location
        ++yBottom;  //adjust bottom limiter
        --yTop;     //adjust top limiter
      }

      //begin neighbor detection
      for (int cy = yTop; cy <= yBottom; ++cy) {    //begin cy for, execute from top limit to bottom limit
        for (int cx = xLeft; cx <= xRight; ++cx) {  //begin cx for, execute from left limit to right limit
          if ((cy==y)&&(cx==x)) {                   //begin neighbor detection if
            continue;                               //do nothing if this is the element being analyzed
          } else if (Array[cy][cx] == '*') {        //if this is a populated neighbor,
            ++(neighborCounts[y][x]);               //increment the appropriate counter
          } //end neighbor detection if             //otherwise, do nothing

        }   //end cx for
      }     //end cy for

    }       //end x for
  }         //end y for

  //...

  return 0;
}

Notice how I detect the edge conditions, then I set the limits of the search based on whether it's an edge condition or not. Once I've established the limits of the search, I use a for loop to perform the actual search.

You can do that like this.

1st of all initialize 2 arrays like this:
dx[8]={1,-1,0,0,1,1,-1,-1}
dy[8]={0,0,1,-1,1,-1,1,-1}

assume that your current position is x,y;

declare 2 integers;
nx,ny;

do a for to catch all the neighborhoods:

for(int i=0;i<8;i++)
{
  nx=x+dx[i];
  ny=y+dy[i];
  if(nx<n && nx>=0 && ny>=0 && ny<m)
  {
      do what you want to do
  }
}

where n is the number of rows, m is the number of columns.

Actually, I think I may need to apologize. I took another look. It depends on what n and m are, but this just might work.

Actually, I think I may need to apologize. I took another look. It depends on what n and m are, but this just might work.

Take another look.

I am tagging nx and ny with the coords of the neighborhood, after that I check if they are in borders.

Take another look.

I am tagging nx and ny with the coords of the neighborhood, after that I check if they are in borders.

That would be why I reposted. It took me a bit, but I realized what you were doing.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.