【问题标题】:C++ display possible bishop moves in an empty chess boardC++ 在空棋盘中显示可能的象棋移动
【发布时间】:2021-06-04 17:59:42
【问题描述】:

此任务要求在棋盘 (8 x 8) 中显示可能的象棋移动,如下所示:

x = 4, y = 4
1 0 0 0 0 0 1 0,
0 1 0 0 0 1 0 0,
0 0 1 0 1 0 0 0,
0 0 0 2 0 0 0 0,
0 0 1 0 1 0 0 0,
0 1 0 0 0 1 0 0,
1 0 0 0 0 0 1 0,   
0 0 0 0 0 0 0 1

Image for clear understanding

    #include <iostream>

using namespace std;

int main() {
int array[8][8], x , y;

for (int i = 0; i < 8; i++)
{
    for (int j = 0; j < 8; j++)
    {
        array[i][j] = 0;
    }
}

cout << "Input x coordinate: ";
cin >> x;

cout << "Input y coordinate: ";
cin >> y;

for (int i = 0; i < 8; i++) 
    { // 1st diagonal
        array[x + i][y + i] = 1;
        array[x - i][y - i] = 1;
    }

    for (int i = 0; i < 8; i++) 
    { // 2nd diagonal
        array[x + i][y - i] = 1;
        array[x - i][y + i] = 1;
    }

array[x][y] = 2;

for (int i = 0; i < 8; i++) //Cout
{
    for (int j = 0; j < 8; j++)
    {
        cout << array[i][j];
    }
    cout << endl;
}

return 0;
}

它似乎只适用于第一个对角线

【问题讨论】:

    标签: c++ chess


    【解决方案1】:

    这比 C++ 更像是一个算法/数学答案。

    假设网格的左下角为原点(即i = 0, j = 0),网格右上角的坐标为i=7, j=7

    i=0, j=0 上的主教可以在这两行上击中任何内容:

    i = ji = - j

    当您将主教放在x, y 而不是0,0 时,这些行变为:

    i - x = j - yi - x = - (j - y)

    现在,您可以迭代矩阵中的所有点并检查哪些点满足线方程:

    int main() {
      int x, y;
    
      std::cout << "Input x coordinate: ";
      std::cin >> x;
    
      std::cout << "Input y coordinate: ";
      std::cin >> y;
    
      int array[8][8];
    
      for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
          if ((i - x == j - y) || (i - x == -(j - y))) {
            array[i][j] = 1;
          } else {
            array[i][j] = 0;
          }
        }
      }
    
      array[x][y] = 2;
    
      // We should print the matrix from top to bottom.
      // j represents the y coordinate, and i represents the x coordinate.
      for (int j = 7; j >= 0; j--) {
        for (int i = 0; i < 8; i++) {
          std::cout << array[i][j];
        }
        std::cout << std::endl;
      }
      return 0;
    }
    
    

    【讨论】:

      【解决方案2】:

      当我运行它时,它看起来对两个对角线都有效。有一个小错误可能会搞砸。您需要像这样添加边界检查:

          for (int i = 0; i < 8; i++) 
          { // 1st diagonal
              if (x + i < 8 && y + i < 8)
                  array[x + i][y + i] = 1;
      
              if (x - i >= 0 && y - i >= 0)
                  array[x - i][y - i] = 1;
          }
      
          for (int i = 0; i < 8; i++) 
          { // 2nd diagonal
              if (x + i < 8 && y - i >= 0)
                  array[x + i][y - i] = 1;
      
              if (x - i >= 0 && y + i < 8)
                  array[x - i][y + i] = 1;
          }
      

      如果没有这些边界检查,您将访问数组边界之外的元素,并且可能会弄乱数组中的其他条目。还有其他方法可以进行边界检查,但这可能是最简单的。

      为了说明问题,假设x = 4,然后在i = 5 时处于for 循环中。当您使用array[x - i] 对数组进行索引时,它将与array[-1] 相同。当你索引一个负值的数组时,你会弄乱错误的内存。

      【讨论】:

        【解决方案3】:

        我将从一个非常简单的案例开始。

        假设我们要绘制大小为 4x4 的对角矩阵:

         i  0 1 2 3
        j   
        0   1 0 0 0
        1   0 1 0 0
        2   0 0 1 0
        3   0 0 0 1
        

        在以下情况下我们有一个非零值:

        i = j   (I)
        

        现在,假设我们水平移动这条对角线,使第一行的非零值位于 X0。 例如,对于 X0 = 1:

              X0
        
         i' 0 1 2 3
        j'  
        0   0 1 0 0
        1   0 0 1 0
        2   0 0 0 1
        3   0 0 0 0
        

        平移后的坐标为:

        i' = i + X0 (II)
        

        垂直移动 Y0

        j' = j + Y0 (III)
        

        通过 (I) 中的 (II) 和 (III) 我们有:

        i' - X0 = j' - Y0   (IV)
        

        现在我们对反对角矩阵做同样的事情:

         i  0 1 2 3
        j   
        0   0 0 0 1
        1   0 0 1 0
        2   0 1 0 0
        3   1 0 0 0
        

        在以下情况下我们有一个非零值:

        j = 3 - i   (V)
        

        水平移动 X0 我们有:

        i' = -3 + i + X0    (VI)
        

        垂直移动 Y0:

        j' = j + Y0         (VII)
        

        (V)中的(VI)和(VII):

        j' - Y0 = X0 - i'   (VIII)
        

        代码只需要检查(IV)和(VIII):

        #include <iostream>
        using namespace std;
        
        int main()
        {
            int array[8][8] = {0,};
        
            int x = 0;
            int y = 0;
            
            cout << "Input x coordinate: ";
            cin >> x;
            
            cout << "Input y coordinate: ";
            cin >> y;
            
            for (int j = 0; j < 8; j++)
                for (int i = 0; i < 8; i++) 
                    if (   i - x == j - y
                        || j - y == x - i)
                        array[j][i] = 1;
            
            array[y][x] = 2;
        
            for (int j = 0; j < 8; j++)
            {
                for (int i = 0; i < 8; i++)
                    cout << array[j][i];
                cout << endl;
            }
            
            return 0;
        }
        

        请注意,矩阵是按照约定 array[lines][columns] 绘制的,因此要设置笛卡尔坐标,我们编写 array[y][x]

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-12-06
          • 1970-01-01
          • 1970-01-01
          • 2021-12-25
          相关资源
          最近更新 更多