2017-01-15 9 views
-1

私はConwayのGame of LifeシミュレーションでこのCコードを書いています。これは、ユーザーが入力として文字を入力する場合を除いて、完全に機能します。これまで私が行ってきたことです。たとえば、任意の文字を入力した場合。 *または/プログラムが入力を要求すると、プログラムはフリーズしたり、無限ループに入ります。誰かが私に助けてくれますか?私はバグを取り除くために可能な限りすべての方法でコードを微調整しましたが、すべて無駄にしました。入力がフリーズするのはなぜですか?

#include "stdio.h" //for all basic functions 
#include "stdlib.h"//for exit function 
#include "time.h" //for random seed 
#include "windows.h" //for Sleep function 
#include "conio.h" //for _kbhit function 
#define scanf_s scanf //typing scanf_s is tedious compared to typing scanf 

void neighbour_manager();//custom function to calculate neighbours and make a cell alive or dead accordingly 
void generation_printer();//custom function to print the generations after selecting seed type 

//initializing all variables 
int generation; 
char fill_char; 
char array[35][85]; 
char array1[35][85]; 
char live = '+';//using + sign for live cells 
char dead = ' ';//using blank spaces for dead cells 
char n; 
char random_seed[3]={' ','+','\0'};//for random seed i.e. (case:12) 
//SEEDS 
char block[2][2] = {{'+','+'}, {'+','+'}}; 
char boat[3][3] = {{'+','+',' '}, {'+',' ','+'}, {' ','+',' '}}; 
char loaf[4][4] = {{' ','+','+',' '},{'+', ' ', ' ', '+'},{' ', '+', ' ', '+'},{' ', ' ', '+', ' '}}; 
char beehive[3][4] = {{' ','+','+',' '},{'+', ' ', ' ', '+'},{' ', '+', '+', ' '}}; 
char blinker[1][3] = {{'+', '+','+'}}; 
char beacon[4][4] = {{'+','+',' ',' '},{'+',' ',' ',' '},{' ',' ',' ','+'},{' ',' ','+','+'}}; 
char toad[2][4] = {{' ','+','+','+'},{'+','+','+',' '}}; 
char pulsar[15][15] = { 
          {' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '}, 
          {' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '}, 
          {' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '}, 
          {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}, 
          {'+','+','+',' ',' ','+','+',' ','+','+',' ',' ','+','+','+'}, 
          {' ',' ','+',' ','+',' ','+',' ','+',' ','+',' ','+',' ',' '}, 
          {' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '}, 
          {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}, 
          {' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '}, 
          {' ',' ','+',' ','+',' ','+',' ','+',' ','+',' ','+',' ',' '}, 
          {'+','+','+',' ',' ','+','+',' ','+','+',' ',' ','+','+','+'}, 
          {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}, 
          {' ',' ',' ',' ','+','+',' ',' ',' ','+','+',' ',' ',' ',' '}, 
          {' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '}, 
          {' ',' ',' ',' ','+',' ',' ',' ',' ',' ','+',' ',' ',' ',' '} 
          }; 
char glider[3][3] = {{' ','+',' '},{' ',' ','+'},{'+','+','+'}}; 
char spaceship[4][5] = {{'+',' ',' ','+',' '},{' ',' ',' ',' ','+'},{'+',' ',' ',' ','+'},{' ','+','+','+','+',}}; 
char gosper_glider_gun[15][38] = { 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ' }, 
            { ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', ' ', '+', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', ' ', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '+', '+', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' }, 
            { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' } 
           }; 


//main function starts here 
int main(void) 
{int i = 0, j = 0;     //initializing some more variables 
    int a = 0, b = 0, seed_type = 0; 
    int choice_after_execution=0; 
    system("title CONWAY'S GAME OF LIFE");//to change the console title 
    _flushall();//to remove garbage values 
    printf("\t\t\t\t\tWelcome to Conway's Game of Life\n");//welcome note 
    Sleep(2500);//for dramatic purposes 
    system("cls"); 
    printf("Please make sure the console is maximized for optimal simulation.");//whole grid is not visible if console is not maximized 
    Sleep(2000);//to create a pause to maximize screen before proceeding 

    start:       //jump point in case user decides to restart the game 
    for (i = 0; i < 35; i++) {  //emptying the array to avoid double printing of patterns in the same grid 
     for (j = 0; j < 85; j++) { 
      array[i][j]=dead; 
     } 
    } 
    system("cls"); 

    printf("Select the seed type\nSTILL LIFE PATTERNS\nEnter 1 for Block \nEnter 2 for Loaf \nEnter 3 for Boat\nEnter 4 for Beehive\n\nOSCILLATORS\nEnter 5 for Blinker\nEnter 6 for Beacon\nEnter 7 for Toad\nEnter 8 for Pulsar\n\nGLIDERS AND SPACSHIPS\nEnter 9 for Glider\nEnter 10 for Spaceship\n\nGOSPER GLIDER GUN\nEnter 11 for Gosper Glider Gun\n\nRANDOM\nEnter 12 for Random\n\nYour choice: "); 
    retake_seed_type: //jump point for invalid choice 

      scanf("%d", &seed_type); 

    srand(time(NULL)); //random seed generator 
    a = 1 + rand() % 35; //randomizing the row for first generation 
    b = 1 + rand() % 85; //randomizing the column for first generation 


    switch (seed_type)//switch case for different seed types 
    { 
    case 1: //for block 
     for (i = a; i < a + 2; i++){ 
      for (j = b; j < b + 2; j++){ 

       array[i%35][j%85] = block[i - a][j - b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
    case 2://for loaf 
     for (i = a; i <a + 4; i++){ 
      for (j = b; j <b + 4; j++){ 
       array[i%35][j%85] = loaf[i - a][j - b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
    case 3://for boat 
     for (i = a; i <a + 3; i++){ 
      for (j = b; j <b + 3; j++){ 

       array[i%35][j%85] = boat[i - a][j - b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
    case 4://beehive 
     for(i = a; i <a + 3; i++){ 
      for(j = b; j <b + 4; j++){ 
      array[i%35][j%85] = beehive[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
    case 5://blinker 
     for(i=a;i<a+1;i++){ 
      for(j=b;j<b+3;j++){ 
      array[i%35][j%85] = blinker[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
    case 6://beacon 
     for(i=a;i<a+4;i++){ 
      for(j=b;j<b+4;j++){ 
      array[i%35][j%85] = beacon[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
    case 7://Toad 
     for(i=a;i<a+2;i++){ 
      for(j=b;j<b+4;j++){ 
      array[i%35][j%85] = toad[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
    case 8://Pulsar 
     for(i=a;i<a+15;i++){ 
      for(j=b;j<b+15;j++){ 
      array[i%35][j%85] = pulsar[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
     case 9://glider 
     for(i=a;i<a+3;i++){ 
      for(j=b;j<b+3;j++){ 
      array[i%35][j%85] = glider[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
     case 10://spaceship 
     for(i=a;i<a+4;i++){ 
      for(j=b;j<b+5;j++){ 
      array[i%35][j%85] = spaceship[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
     case 11://gosper glider gun 
     for(i=a;i<a+15;i++){ 
      for(j=b;j<b+38;j++){ 
      array[i%35][j%85] = gosper_glider_gun[i-a][j-b];//i%35 and j%85 to facilitate wrap around 
      } 
     } 
     break; 
     case 12://random 
      a=0; 
      b=0; 
      for(i=a;i<35;i++){ 
       for(j=b;j<85;j++){ 
       array[i][j] = random_seed[1+rand()%2]; 
      } 
     } 
     break; 

    default://default case asks for input again 
      printf("Enter a valid choice i.e. from 1 to 12: "); 
      goto retake_seed_type;//go-to statement to take seed_type input again 
    } 
    printf("\nEnter the number of generations(-1 for infinite): "); 
    scanf_s("%d", &generation); 
if(generation>0){//different cases for generation input 
    for (i = 1; i <= generation; i++){ 
     system("cls"); 
     neighbour_manager(); 
     generation_printer(); 
     printf("GENERATION NUMBER: %d\n", i);//to know how many generations have been printed 
     printf("Press any key to stop simulation.\n"); 
     if(_kbhit())//if user presses a key to stop simulation 
      { 
      printf("Generation Interrupted."); 
     break; 
     } 
     if(i==generation)//if user does not interrupt generations 
     { 
      Sleep(200);//dramatic purposes 
      printf("Generation completed successfully."); 
     } 

     Sleep(700);//according to the instructions 
    } 
} 
    if (generation <0) 
    {int z=0; 
     while (!_kbhit())//to make sure loop continues printing unless user press a key on keyboard 
      { 
      system("cls"); 
      neighbour_manager(); 
      generation_printer(); 
      z++;//generation counter 
      printf("GENERATION NUMBER: %d\n", z);//to know how many generations have been printed 
      printf("Press any key to stop simulation.\n"); 
      Sleep(700);//according to the instructions 
      if(_kbhit())//if user presses a key to stop simulation 
      { 
      printf("Generation Interrupted."); 
     break; 
     } 

      } 

    } 
    if(generation==0) 
     { system("cls"); 
      printf("No generations printed."); 
     } 

    printf("\nPress 1 to Restart.\nPress 2 to Exit.\nYour Choice: ");//exit message 
    after_generation_valid_choice://jump point in case of wrong input choice 
    scanf("%d",&choice_after_execution); 

    if(choice_after_execution==1) 
     goto start;//if user wants to start simulation again then go back to start 

    if(choice_after_execution==2)//if user wants to exit 
     { 
      printf("Thank you for using this program."); 
      Sleep(2000);//for dramatic purposes 
      goto exit;//if user decides to exit the program then skip system pause and just exit 
     } 
    else 
    { 
     printf("Enter a valid choice: ");//if invalid choice is entered ask again 
     goto after_generation_valid_choice; 
    } 

    exit://jump point in case user wants to exit 
    exit(0); 
}//main end 

void neighbour_manager(){      //custom function to decide whether cells should be alive or dead 
    int i, j;         //corresponding to the number of neighbours alive or dead 
    int neighbour; 
    for (i = 0; i < 35; i++){ 
     for (j = 0; j < 85; j++){ 

      neighbour = 0; 
      if (array[i - 1 < 0 ? 34 : i - 1][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1;//modifications in row and 
      if (array[i - 1 < 0 ? 34 : i - 1][j] == live) neighbour = neighbour + 1;     //column numbers to ensure 
      if (array[i - 1 < 0 ? 34 : i - 1][(j + 1) % 85] == live) neighbour = neighbour + 1;   //that the patterns wrap 
      if (array[i][j - 1 < 0 ? 84 : j - 1] == live)  neighbour = neighbour + 1;     //around 
      if (array[i][(j + 1) % 85] == live)  neighbour = neighbour + 1; 
      if (array[(i + 1) % 35][j - 1 < 0 ? 84 : j - 1] == live) neighbour = neighbour + 1; 
      if (array[(i + 1) % 35][j] == live) neighbour = neighbour + 1; 
      if (array[(i + 1) % 35][(j + 1) % 85] == live) neighbour = neighbour + 1; 


      if(neighbour == 3)      //game rules that decide whether a cell would be alive or 
      {           //not in the next generation 
       array1[i][j] = live; 
      } 
      else if (neighbour < 2 || neighbour > 3) 
      { 
       array1[i][j] = dead; 
      } 
      else 
      { 
       array1[i][j] = array[i][j]; 
      } 
     } 
    } 
    for(i=0; i<35; i++){       //replace array1 with array 
     for(j=0; j<85; j++){ 
      array[i][j] = array1[i][j]; 
      array1[i][j] = ' ';     // now empty array1 
     } 
    } 
    return; 
} 


int ran_out_of_variable_names1 = 35; 
int ran_out_of_variable_names2 = 85; 

void generation_printer() //custom function that prints both border and the array(with patterns) 
{ 
    int i,j; 
    // Top border 
    for (i = 0; i < ran_out_of_variable_names2 + 2; i++) { 
     printf("*"); 
    } 
    printf("\n"); 
    for (i = 0; i < ran_out_of_variable_names1; i++) { 
     // Star to the beginning of the line 
     printf("*"); 
     // Contents of the line 
     for (j = 0; j < ran_out_of_variable_names2; j++) { 
      printf("%c", array[i][j]); 
     } 
     // Star at the end of the line 
     printf("*\n"); 
    } 
    // Bottom border 
    for (i = 0; i < ran_out_of_variable_names2+ 2; i++) { 
     printf("*"); 
    } 
    printf("\n"); 
} 
//END OF CODE 
+0

'_kbhit'と' goto'が起こっていません問題になる。 – killerzula

+1

唯一の問題が文字を入力として入力している場合は、質問だけを制限し、コード全体を投稿しないようにすることができます。誰かがあなたの質問に答えるために最初にやるべきことは、そのコードのどこで入力が受け入れられるかを見つけることです。また、どの入力を受け入れるべきかを知ることもできます。 「キャラクター」でない場合、ユーザーは何を入力できますか?すべての入力は文字です。 – Clifford

+0

'scanf'は変換できないときに入力をクリアしません。入力はバッファに残ります。あなたはそれを自分でする必要があります。 'scanf'(変換された項目の数)からの戻り値を常にチェックしてください。 'fgets'を使い、' sscanf'を使うのが良いでしょう。それが失敗すると、その文字列をダンプして別の文字列を入力することができます。 –

答えて

1

入力バッファが非数字文字が含まれていて、あなたが入力を読み取るためにscanf() RITH %dを使用する場合は、入力が失敗し、数字以外の文字は何も持っていないので、失敗するだけで、その後のscanf()のために、バッファリングされたままになりますかわった。

ソリューションはlegionです。ここで一つだ:

while(scanf("%d",&choice_after_execution) != 1) 
{ 
    while(getchar() != '\n') ; // read buffer until end of line 
} 

代替はfgets()を使用して入力の行全体を読んで、sscanf()を使用してそれを解析することです。

私は強く(あなたが一度だけの問題を解決しなければならない)、あなたがそれを行うが、あなたは再利用のための機能で解決策をラップすることを示唆している:

int getDecimalInput() 
{ 
    int input = 0 ; 
    while(scanf("%d",&input) != 1) 
    { 
     while(getchar() != '\n') ; // read buffer until end of line 
    } 

    return input ; 
} 
関連する問題