2013-09-14 4 views
1

У меня проблема с программой, которую я сделал недавно. В принципе, это простая версия игры Джона Конвей, но она работает неправильно. Проблема заключается в коде, который считывает состояние ячейки и ее соседей и решает будущее состояние этой ячейки. Вот та часть кода (это немного долго):C игнорирует инструкции «если»

#include<stdio.h> 
#include<conio.h> 

//Game grid size 
#define SIZE 15 

//Cell state (wall is a special state. It protects the other cells from garbage data of the heap memory) 
enum cellState {dead,alive,wall}; 

//Function prototypes 
int** load(int**); 
void process(int**); 

int main(){ 

    //Game grid (2-D matrix) and its memory allocation 
    int** grid; 

    grid=(int**)calloc(SIZE+2,sizeof(int*)); 
    for(int cont=0;cont<SIZE+2;cont++){ 
     *(grid+cont)=(int*)calloc(SIZE+2,sizeof(int)); 
    } 

    load(grid); 
    getch(); 
    process(grid); 
    getch(); 
} 

//Grid loading function 
int** load(int** grid){ 

    int type; 
    srand(12345); 
    for(int cont=0;cont<SIZE+2;cont++){ 
     for(int cont2=0;cont2<SIZE+2;cont2++){ 
      if(cont==0||cont==TAMANO+1||cont2==0||cont2==TAMANO+1){ 
       *(*(grid+cont)+cont2)=wall; 
      } 
      else{ 
       //Cell type decision 
       type=(int)((rand()*2+1)/32767); 
       if(type==dead){ 
        *(*(grid+cont)+cont2)=dead; 
       } 
       else if(type==alive){ 
        *(*(grid+cont)+cont2)=alive; 
       } 
      } 
     } 
    } 
    //Grid impression 
    for(int cont=0;cont<SIZE+2;cont++){ 
     for(int cont2=0;cont2<SIZE+2;cont2++){ 
      if(*(*(grid+cont)+cont2)==wall){ 
       printf("W "); 
      } 
      else if(*(*(grid+cont)+cont2)==dead){ 
       printf(". "); 
      } 
      else if(*(*(grid+cont)+cont2)==alive){ 
       printf("C "); 
      } 
     } 
     printf("\n"); 
    } 
    return(grid); 
} 


void process(int** grid){ 

    //Temporary grid that saves the next state of a cell 
    int** gridTemp; 
    //Generations (turns) counter and live neighbours counter 
    int generations=0,liveNeighbours=0; 
    gridTemp=(int**)calloc(SIZE+2,sizeof(int*)); 
    for(int cont=0;cont<SIZE+2;cont++){ 
     *(gridTemp+cont)=(int*)calloc(SIZE+2,sizeof(int)); 
    } 

    for(int cont=0;cont<SIZE+2;cont++){ 
     for(int cont2=0;cont2<SIZE+2;cont2++){ 
      if(cont==0||cont==SIZE+1||cont2==0||cont2==SIZE+1){ 
       *(*(gridTemp+cont)+cont2)=wall; 
      } 
     } 
    } 

    //Processing loop 
    while(generations<100){ 

     system("cls"); 

     for(int cont=1;cont<SIZE+1;cont++){ 
      for(int cont2=1;cont2<SIZE+1;cont2++){ 
       for(int comp1=-1;comp1<2;comp1++){ 
        for(int comp2=-1;comp2<2;comp2++){ 
         if(comp1==0&&comp2==0) continue; 
         else{ 
          //Here, we read the state of the neighbour cells of a certain cell 
          if(*(*(grid+cont)+cont2)==dead){ 
           if(*(*(grid+cont+comp1)+cont2+comp2)==alive){ 
            liveNeighbours+=1; 
           } 
          } 
          else if(*(*(grid+cont)+cont2)==alive){ 
           if(*(*(grid+cont+comp1)+cont2+comp2)==alive){ 
            liveNeighbours+=1; 
           } 
          } 
         } 
        } 
       } 
       //Future state calculation. Here is where the code fails. This if compares the state of a certain cell and the "dead" enumeration 
       if(*(*(grid+cont)+cont2)==dead){ 
        if(liveNeighbours==3){ 
         *(*(gridTemp+cont)+cont2)==alive; 
        } 
        else{ 
         *(*(gridTemp+cont)+cont2)==dead; 
        } 
       } 
       if(*(*(grid+cont)+cont2)==alive){ 
        //It also fails here. This if checks the value of the liveNeighbours variable 
        if(liveNeighbours>=2&&liveNeighbours<=3){ 
         *(*(gridTemp+cont)+cont2)==alive; 
        } 
        //And here too 
        if(liveNeighbours<2||liveNeighbours>3){ 
         *(*(gridTemp+cont)+cont2)==dead; 
        } 
       } 
       liveNeighbours=0; 
      } 
     } 
     //Here, the program copies the temporary grid onto the normal grid 
     for(int cont=0;cont<SIZE+2;cont++){ 
      for(int cont2=0;cont2<SIZE+2;cont2++){ 
       *(*(grid+cont)+cont2)=*(*(gridTemp+cont)+cont2); 
       if(*(*(grid+cont)+cont2)==wall){ 
        printf("W "); 
       } 
       else if(*(*(grid+cont)+cont2)==dead){ 
        printf(". "); 
       } 
       else if(*(*(grid+cont)+cont2)==alive){ 
        printf("A "); 
       } 
      } 
      printf("\n"); 
     } 
     generations++; 
     getch(); 
    } 
    return; 
} 

Использование Dev-C++ инструмент отладки, я был в состоянии видеть, что код не в точках я пометил. Просто он игнорирует код в этих инструкциях if, даже если условие выполнено.

Я также перестраиваю этот код пару раз и пробовал его в другом компиляторе, и он также терпит неудачу. Turbo-C++ говорит, что код в плохом, если инструкции не имеет никакого эффекта.

+2

Вот почему: слишком много уровней вложенных блоков предполагалось плохой практикой кодирования - трудно для ошибок –

+1

Не ответ на ваш вопрос, но подсказка для жизни: не имеет никакого интервала между операторами, приведениями и сравнениями или после запятых делает ваш код почти не читается. –

+0

Также не ответ, но почему вы используете эту нелепую нотацию '* (grid + cont)' вместо 'grid [cont]'? – Blastfurnace

ответ

6

В фрагменте кода:

    if(liveNeighbours==3){ 
            *(*(gridTemp+cont)+cont2)==alive; 
            } 
          else{ 
            *(*(gridTemp+cont)+cont2)==dead; 
            } 

Вы не присваивая значение «живой» или «мертвый» к клетке - вы проверяете, если он равен (из-за == сравнения). Я уверен, что это не то, что вы намереваетесь делать?

то же самое происходит и в другом месте, где «если заявление не может»:

   if(liveNeighbours>=2&&liveNeighbours<=3){ 
            *(*(gridTemp+cont)+cont2)==alive; 
            } 
          //And here too 
          if(liveNeighbours<2||liveNeighbours>3){ 
            *(*(gridTemp+cont)+cont2)==dead; 
            } 

Я думаю, что замена этих четырех == знаков с = поможет.

+0

@WhozCraig Yup - я нашел их и добавил их, когда вы писали свой комментарий. Благодарю. – Floris

+0

Ничего себе. Теперь работает. Я хочу, чтобы в будущем компиляторы были достаточно умны, чтобы рассказать нам о наших ошибках. Большое спасибо :-) – Yxuer

+4

@Yxuer Они * умнее для таких вещей. Например, Mine помечены всеми четырьмя строками выше с предупреждениями, поскольку «код не имеет эффекта» и «результат логической оценки отбрасывается». Включите предупреждения компилятора и * учтите их *. – WhozCraig

Смежные вопросы