检查二维阵列中点的上、下、左、右两个空间的最佳方法



我在C#中有一个5x5 2D数组。我需要检查数组上、下、右和左的2个空格。最好的方法是什么?try-catch语句用于当它必须检查一个可能越界的点时。

这就是我到目前为止所拥有的,它有效,但它看起来很草率。

bool[,] boardSpaces = new bool[5, 5] { 
    { true, true, true, true, true }, 
    { true, true, true, true, true },
    { true, true, true, true, true },
    { true, true, true, true, true },
    { true, true, true, true, true } 
};

for (int x = 0; x < 5; x++)
{
    for (int y = 0; y < 5; y++)
    {
        if (boardSpaces[x, y] == false)
        {
            try
            {
                if (boardSpaces[x - 1, y] == true && boardSpaces[x - 2, y] == true)
                {
                    validMoveRemaining = true;
                    break;
                }
            }
            catch { }
            try
            {
                if (boardSpaces[x + 1, y] == true && boardSpaces[x + 2, y] == true)
                {
                    validMoveRemaining = true;
                    break;
                }
            }
            catch { }
            try
            {
                if (boardSpaces[x, y - 1] == true && boardSpaces[x, y - 2] == true)
                {
                    validMoveRemaining = true;
                    break;
                }
            }
            catch { }
            try
            {
                if (boardSpaces[x, y + 1] == true && boardSpaces[x, y + 2] == true)
                {
                    validMoveRemaining = true;
                    break;
                }
            }
            catch { }
        }
    }
}

使用算术边界检查而不是异常处理。您已经有了矩阵的行和列索引以及维度。你为什么不简单地假设呢?

if(x - 2 >= 0 && x + 2 < matrixWidth)
{
  //...
}
if(y - 2 >= 0 && y + 2 < matrixHeight)
{
  //...
}

你甚至可以用它做一个复合布尔表达式:

validMoveRemaining =
  !board[x,y] && (
    (x >= 2 && board[x - 1, y] && board[x - 2, y]) ||
    (x < boardWidth - 2 && board[x + 1, y] && board[x + 2, y]) ||
    (y >= 2 && board[x, y - 1] && board[x, y - 2]) ||
    (y < boardHeight - 2 && board[x, y + 1] && board[x, y + 2])
  );

给你!:)

差不多了。你肯定需要2个"fors"。您可以通过添加更多的检查来提高性能,例如,您不需要在第1列和第2列上选择左侧,因为没有2个左侧位置,所以您只需要检查右侧。同样的逻辑适用于行,所以在第[1,1]行中,您只需要右下方进行检查。通过这种方式,您可以删除尝试捕获。

此外,你还必须检查,因为它是一个很小的矩阵,也许额外的检查会使它比全循环慢。

根据更清晰的规范进行编辑

public bool CanMove(int x, int y)
{
    if ( checkBeforeX(x, y) )
        return true;
    if ( checkAfterX(x, y) )
        return true;
    if ( checkBeforeY(x, y) )
        return true;
    if ( checkAfterY(x, y) )
        return true;
    return false;
}
private bool checkBeforeX(int x, int y)
{
    return x>=2 ? boardSpaces[x-1, y] && boardSpaces[x-2, y] : false;
}
private bool checkAfterX(int x, int y)
{
    return x<=2 ? boardSpaces[x+1, y] && boardSpaces[x+2, y] : false;
}
private bool checkBeforeY(int x, int y)
{
    return y>=2 ? boardSpaces[x, y-1] && boardSpaces[x, y-2] : false;
}
private bool checkAfterY(int x, int y)
{
    return y<=2 ? boardSpaces[x, y+1] && boardSpaces[x, y+2] : false;
}

为阵列添加边界的最佳性能方法

  bool[,] boardSpaces = new bool[9, 9] {  
    { false, false, false, false, false, false, false, false, false },  
    { false, false, false, false, false, false, false, false, false },  
    { false, false, true, true, true, true, true, false, false },  
    { false, false, true, true, true, true, true, false, false  }, 
    { false, false, true, true, true, true, true, false, false  }, 
    { false, false, true, true, true, true, true, false, false  }, 
    { false, false, true, true, true, true, true, false, false  },  
    { false, false, false, false, false, false, false, false, false },  
    { false, false, false, false, false, false, false, false, false },  
  };
  const int left = 2;
  const int right = left + 5;
  const int top = 2;
  const int bottom = top + 5;
  for (int x = left; x < right; x++)
  {
    for (int y = top; y < bottom; y++)
    {
      ..
    }
  } 

可读性的最佳方式比添加方向

  var directions = new[] 
  {
     new { dx = -1, dy = 0 }, 
     new { dx = +1, dy = 0 }, 
     new { dx = 0, dy = -1 }, 
     new { dx = 0, dy = +1 } 
  };
  for (int x = left; x < right; x++)
  {
    for (int y = top; y < bottom; y++)
    {
      foreach (var direction in directions)
      {
        if (boardSpaces[x + direction.dx, y + direction.dy] 
           && boardSpaces[x + 2 * direction.dx, y + 2 * direction.dy])
        {
          validMoveRemaining = true;
          break;
        } 
      }
      //..
    }
  } 

最新更新