开发者

Determining valid adjacent cells of a square stored as an array

开发者 https://www.devze.com 2022-12-16 20:31 出处:网络
I have an array (of 9 elements, say) which I must treat as a (3 by 3) square. For the sake of simplifying the question, this is a one-based array (ie, indexing starts at 1 instead of 0).

I have an array (of 9 elements, say) which I must treat as a (3 by 3) square. For the sake of simplifying the question, this is a one-based array (ie, indexing starts at 1 instead of 0).

My goal is to determine valid adjacent squares relative to a starting point.

In other words, how it's stored in memory: 1 2 3 4 5 6 7 8 9

How I'm treating it:

7 8 9

4 5 6

1 2 3

I already know how to move up and down and test for going out of bounds (1 >= current_index <= 9)

edit: I know the above test is overly general but it's simple and works.

//row_size = 3, row_step is -1, 0 or 1 depending on if we're going left,
//staying put or going right respectively.
current_index += (row_size * row_step); 

How do I test for an out of bounds condition when going left or right? Conceptually I know it involves determining if 3 (for example) is on the same row as 4 (or if 10 is even within the same square as 9, as an alternate example, given that multiple squares are in the same array back to back), but I can't figure out how to determine that. I imagine there's a modulo in there somewhere, but where?

Thanks very much,

Geoff

Addendum:

Here's the resulting code, altered for use with a zero-based array (I cleaned up the offset code present in the project) which walks adjacent squares.

bool IsSameSquare(int index0, int index1, int square_size) {
  //Assert for square_size != 0 here
  return (!((index0 < 0) || (index1 < 0))
      && ((index0 < square_size) && (index1 < square_size)))
      && (index0 / square_size == index1 / square_size);
}
bool IsSameRow(int index0, int index1, int row_size) {
  //Assert for row_size != 0 here
  return IsSameSquare(index0, index1, row_size * row_size)
  && (index0 / row_size == index1 / row_size);
}
bool IsSameColumn(int index0, int index1, int row_size) {
  //Assert for row_size != 0 here
  return IsSameSquare(index0, index1, row_size * row_size)
     开发者_C百科 && (index0 % row_size == index1 % row_size);
}

//for all possible adjacent positions
for (int row_step = -1; row_step < 2; ++row_step) {
  //move up, down or stay put.
  int row_adjusted_position = original_position + (row_size * row_step);
  if (!IsSameSquare(original_position, row_adjusted_position, square_size)) {
    continue;
  }
  for (int column_step = -1; column_step < 2; ++column_step) {
    if ((row_step == 0) & (column_step == 0)) { continue; }
    //hold on to the position that has had its' row position adjusted.
    int new_position = row_adjusted_position;

    if (column_step != 0) {
      //move left or right
      int column_adjusted_position = new_position + column_step;
      //if we've gone out of bounds again for the column.
      if (IsSameRow(column_adjusted_position, new_position, row_size)) {
        new_position = column_adjusted_position;
      } else {
        continue;                          
      }
    } //if (column_step != 0)
    //if we get here we know it's safe, do something with new_position
    //...
  } //for each column_step
} //for each row_step


This is easier if you used 0-based indexing. These rules work if you subtract 1 from all your indexes:

  • Two indexes are in the same square if (a/9) == (b/9) and a >= 0 and b >= 0.
  • Two indexes are in the same row if they are in the same square and (a/3) == (b/3).
  • Two indexes are in the same column if they are in the same square and (a%3) == (b%3).


There are several way to do this, I'm choosing a weird one just for fun. Use modulus.

Ase your rows are size 3 just use modulus of 3 and two simple rules.

If currPos mod 3 = 0 and (currPos+move) mod 3 = 1 then invalid
If currPos mod 3 = 1 and (currPos+move) mod 3 = 0 then invalid

this check for you jumping two a new row, you could also do one rule like this

if (currPos mod 3)-((currPos+move) mod 3)> 1 then invalid

Cheers


You should be using a multidimensional array for this.

If your array class doesn't support multidimensional stuff, you should write up a quick wrapper that does.

0

精彩评论

暂无评论...
验证码 换一张
取 消