Ich schrieb diesen C-Code für Conways Game of Life Simulation. Es funktioniert perfekt, außer wenn der Benutzer ein Zeichen als Eingabe eingibt. Das habe ich bisher gemacht. Wenn ich irgendein Zeichen z. * oder/Wenn das Programm nach Eingabe fragt, bleibt das Programm stehen oder geht in eine Endlosschleife. Kann mir jemand dabei helfen? Ich habe den Code auf alle möglichen Arten optimiert, um den Fehler zu entfernen, aber alles umsonst.Warum friert meine Eingabe ein?
#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
'_kbhit' und' goto' nicht geht ein Problem sein. – killerzula
Wenn das einzige Problem darin besteht, ein Zeichen als Eingabe einzugeben, könnten Sie versuchen, Ihre Frage auf genau das zu beschränken und nicht Ihren gesamten Code zu veröffentlichen. Das erste, was jemand tun muss, um Ihre Frage zu beantworten, ist zu finden, wo unter all dem Code die Eingabe akzeptiert wird, und auch herauszufinden, welche Eingabe akzeptiert werden soll - Sie haben uns nicht mitgeteilt, wie eine gültige Eingabe aussieht. Was kann der Benutzer eingeben, wenn kein "Charakter"? Alle Eingaben sind Zeichen. – Clifford
'scanf' löscht die Eingabe nicht, wenn sie nicht konvertiert werden kann, der Eingang bleibt im Puffer. Das musst du selbst machen. Überprüfen Sie immer den Rückgabewert von 'scanf' (Anzahl der konvertierten Artikel). Es ist besser, 'fgets' und dann' sscanf' zu verwenden. Wenn es fehlschlägt, können Sie diese Zeichenfolge ausgeben und eine andere eingeben. –