Connect-N棋盘游戏,当宽度>>时崩溃高度

时间:2014-12-03 21:45:07

标签: c cygwin

我在编写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;
        }

第一个函数将板分配为矩阵宽度*用户通过命令行传入的高度。然后,它将板上的每个空间初始化为零,然后将列,行和空间存储到我创建的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];
        }
}

此第二个功能旨在使计算机随机选取电路板上的一列。它通过检查每列中顶行的值来完成此操作。如果那里存在零,它将把这个值存储在合法移动的数组中,然后递增legalmoveindex。如果没有,它会跳过列并检查下一列。它在完成检查最后一列时结束。如果只有一个合法的举动,它将发挥它。如果还有更多,它将从合法移动数组中选择一个随机索引(我在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循环之外的第一件事。

2 个答案:

答案 0 :(得分: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));

答案 1 :(得分:0)

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