2014-12-03 2 views
0

Я в процессе кодирования настольной игры Connect-N, и я почти закончен и прошел поиск неисправностей. Моя проблема заключается в том, что после изменения некоторых вещей моя игра вылетает, когда компьютер воспроизводит свое движение, если ширина слишком велика, чем высота. Здесь задействованы две функции, поэтому я вставлю их оба.Connect-N Board Game, сбой при ширине >> Высота

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. Если этого не происходит, он пропускает столбец и проверяет следующее. Он заканчивается, когда он завершает проверку последнего столбца. Если есть только один законный ход, он будет играть в него. Если их больше, он будет выбирать случайный индекс из массива законных ходов (я запускаю 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." 

Еще раз , мой вопрос: почему моя программа сбой, если ширина больше, чем высота, когда компьютер играет?

Спасибо.

Редактировать: Я нашел решение, и я глуп.

I realloc'd во время цикла while. Переключатель должен быть первым, что находится вне цикла while.

ответ

1

Ответ для будущих программистов, которые могут иметь эту проблему:

Обратите внимание на

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

имеет перераспределить внутри него. Перераспределить следует перенести сразу за его пределами, например, так

while (columncheck <= columns - 1) 
     { 
       if (spaces[columncheck][0] == 0) 
         { 
         arrayoflegalmoves[legalmoveindex] = columncheck; 
         ++legalmoveindex; 
         ++columncheck; 
         } 
       else 
         { 
         ++columncheck; 
         } 
     } 
     arrayoflegalmoves = realloc(arrayoflegalmoves, (legalmoveindex) * sizeof(int)); 
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 
Смежные вопросы