【问题标题】:Connect-N Board Game, crashing when Width is >> HeightConnect-N 棋盘游戏,当宽度为 >> 高度时崩溃
【发布时间】:2014-12-04 09:18:13
【问题描述】:

我正在编写一个 Connect-N 棋盘游戏,我几乎完成了并且已经完成了故障排除。我现在的问题是,在更改了一些内容后,如果宽度比高度大太多,我的游戏会在计算机播放移动时崩溃。这里涉及到两个函数,所以我将它们都粘贴了。

Board
*AllocateBoard(int columns, int rows)
        {
        int **array= malloc(sizeof(int *) *columns);
        int r = 0;
        for ( r = 0; r < columns; ++r)
                {
                array[r] = malloc(sizeof(int) * rows);
                }
        int j = columns - 1;
        int k = rows - 1;
        int m = 0;
        int n = 0;
        for ( m = 0; m < j; ++m)
                {
                for ( n = 0; n < k; ++n)
                        {
                        array[m][n] = 0;
                        }
                }
        Board *board = malloc(sizeof(Board));
        board->columns = columns;
        board->rows = rows;
        board->spaces = array;
        return board;
        }

第一个函数将板分配为用户通过命令行传入的矩阵宽度 * 高度。然后它将板上的每个空间初始化为零,然后将列、行和空间存储到我创建的板结构中。然后它返回棋盘。

int
computerMakeMove(Board *board)
{       int RandIndex = 0;
        int **spaces = board->spaces;
        int columns = board->columns;
        int *arrayoflegalmoves = malloc(sizeof(int) * (columns));
        int columncheck = 0;
        int legalmoveindex = 0;
        while (columncheck <= columns - 1)
        {
                if (spaces[columncheck][0] == 0)
                        {
                        arrayoflegalmoves[legalmoveindex] = columncheck;
                        ++legalmoveindex;
                        ++columncheck;
                        }
                else
                        {
                        ++columncheck;
                        }
                arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
        }
        if (legalmoveindex == 1)
        {
                return arrayoflegalmoves[0];
        }
        else
        {
                RandIndex = rand() % (legalmoveindex);
                return arrayoflegalmoves[RandIndex];
        }
}

第二个函数旨在让计算机随机选择棋盘上的一列。它通过检查每列中顶行的值来做到这一点。如果那里有一个零,它将把这个值存储在一个合法移动的数组中,然后它增加合法移动索引。如果没有,它会跳过该列并检查下一个。它在完成检查最后一列时结束。如果只有一个合法的移动,它将播放它。如果还有更多,它将从合法移动数组中选择一个随机索引(我在 main 中运行 srand),然后返回该值。它只会尝试在法律委员会上玩,所以这不是问题。但是,我非常有信心这个函数会出现问题,因为我将函数调用如下

  printf("Taking the computers move.\n");
        {printf("Taking computer's move.");
         computermove = computerMakeMove(playerboard);
         printf("Computer's move successfully taken.\n");
         playerboard = MakeMove(playerboard, computermove, player);
         printf("Computer's board piece successfully played.\n");
         system("clear");
         displayBoard(playerboard);
         ...;
        }

它会打印出来

Aborted (core dumped)

打印后立即

"Taking computer's move."

再一次,我的问题是:为什么我的程序在计算机播放时宽度大于高度时会崩溃?

谢谢。

编辑:我找到了解决方案,但我很愚蠢。

我在 while 循环中重新分配。 realloc 应该是 while 循环之外的第一件事。

【问题讨论】:

    标签: c cygwin


    【解决方案1】:

    任何可能遇到此问题的未来程序员的答案:

    注意

    while (columncheck <= columns - 1)
            {
                    if (spaces[columncheck][0] == 0)
                            {
                            arrayoflegalmoves[legalmoveindex] = columncheck;
                            ++legalmoveindex;
                            ++columncheck;
                            }
                    else
                            {
                            ++columncheck;
                            }
                    arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
            }
    

    里面有一个 realloc。 realloc 应该立即移到它之外,就像这样

    while (columncheck <= columns - 1)
            {
                    if (spaces[columncheck][0] == 0)
                            {
                            arrayoflegalmoves[legalmoveindex] = columncheck;
                            ++legalmoveindex;
                            ++columncheck;
                            }
                    else
                            {
                            ++columncheck;
                            }
            }
            arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
    

    【讨论】:

      【解决方案2】:
      it is unusual to have the columns be the first index in an array.
      having the first index of an array be columns leads to confusion
      
      
      // suggest using camel case for all variable names, for readability
      
      Board *AllocateBoard(int columns, int rows)
      {
          int **array= malloc(sizeof(int *) *columns); // add check that malloc successful
          int r = 0;
      
          for ( r = 0; r < columns; ++r)
          {
              array[r] = malloc(sizeof(int) * rows); // <-- add: check that malloc successful
          }
      
          int j = columns - 1; // this results in last column not initialized
          int k = rows - 1;    // this results in last row of each column not initialized
          int m = 0; // column loop counter
          int n = 0; // row loop counter
      
          for ( m = 0; m < j; ++m)
          {
              for ( n = 0; n < k; ++n)
              {
                      array[m][n] = 0;
              }
          }
      
          Board *board = malloc(sizeof(Board)); // <-- add: check if malloc successful
          board->columns = columns;
          board->rows = rows;
          board->spaces = array;
          return board;
      } // end function: AllocateBoard
      
      
      // why is this only looking at the first row of each column?
      int computerMakeMove(Board *board)
      {
          int RandIndex = 0;
          int **spaces = board->spaces;
          int columns = board->columns;
          int *arrayoflegalmoves = malloc(sizeof(int) * (columns)); // <-- add check that malloc successful
          int columncheck = 0;
          int legalmoveindex = 0;
      
          while (columncheck <= columns - 1)// should be: for(; columncheck < columns; columncheck++ )
          {
              if (spaces[columncheck][0] == 0)
              { // then first row of column is zero
                  arrayoflegalmoves[legalmoveindex] = columncheck;
                  ++legalmoveindex;
                  ++columncheck; // <-- remove this line
              }
      
              else // remove this 'else' code block
              {
                  ++columncheck;
              } // end if
      
              arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int));
              // <-- 1) use temp int*, in case realloc fails
              // <-- 2) if realloc successful, update arrayoflegalmoves
              // <-- 3) the code is not checking each row of each column,
              //        so the original malloc is more than plenty
              //        so why bother to realloc
              // <-- 4) if legalmoveindex is 0 then realloc returns NULL
          } // end while
      
          // in following, what about when zero moves found? probably should return NULL
          if (legalmoveindex == 1)
          { // only one column[row0] found to contain 0
              return arrayoflegalmoves[0];
          }
      
          else
          {
              RandIndex = rand() % (legalmoveindex);
              return arrayoflegalmoves[RandIndex]; // if zero moves found, this returns a
                                                   // de-reference to address 0
                                                   // which would result in a seg fault event
          } // end if
      } // end function: computerMakeMove
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-01-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多