Я программирую игру крестики-нолики на C.
Кажется, все идет хорошо, но мне нравится реализовывать методы обработки ошибок для таких программ, если пользователь вводит неверные данные.
Я прошу пользователя ввести число от 1 до 9, чтобы заполнить слот на графике крестики-нолики. Когда я использовал вместе fgets и sscanf, в первой игре все работало хорошо. Затем, когда пользователь выбирал «Y» или «y», чтобы продолжить играть в новую игру, казалось, что ни одно из значений переменных не обновлялось, и это в основном вызывало хаос в программе.
Какие-нибудь советы?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
int printmatch(int array[3][3]);
int check(int array[3][3]);
char y;
char Y;
int complacer = 0;
int complacer2 = 0;
int main()
{
do
{
int fill = 0;
int j = 0;
int slot = 0;
int array[3][3];
array[0][0] = 0;
array[0][1] = 0;
array[0][2] = 0;
array[1][0] = 0;
array[2][0] = 0;
array[1][1] = 0;
array[2][1] = 0;
array[1][2] = 0;
array[2][2] = 0;
srand(time(NULL ));
printmatch(array);
char line[20];
do
{
do
{
tryagain: printf("\nEnter Position 1-9(from left to right):");
//I was using fgets and sscanf as an error handling technique incase user inputs incompatible data type, but after the 1st game is over, it seems this code messes up the functionality of the program
//fgets(line,sizeof(line),stdin);
//sscanf(line,"%d",&slot);
//when I just use scanf for data input, all is fine, but limited error handling
scanf("%d", &slot);
if (slot > 9 || slot < 1)
{
printf("Incorrect data input! Try again. \n");
}
} while (!(slot > 0 && slot < 10));
switch (slot)
{
case 1:
if (array[0][0] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[0][0] = 1;
check(array);
break;
case 2:
if (array[1][0] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[1][0] = 1;
check(array);
break;
case 3:
if (array[2][0] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[2][0] = 1;
check(array);
break;
case 4:
if (array[0][1] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[0][1] = 1;
check(array);
break;
case 5:
if (array[1][1] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[1][1] = 1;
check(array);
break;
case 6:
if (array[2][1] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[2][1] = 1;
check(array);
break;
case 7:
if (array[0][2] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[0][2] = 1;
check(array);
break;
case 8:
if (array[1][2] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[1][2] = 1;
check(array);
break;
case 9:
if (array[2][2] == -1)
{
printf("\nWoops, try again!");
goto tryagain;
}
array[2][2] = 1;
check(array);
break;
}
if (array[0][0] != 0 && array[0][1] != 0 && array[0][2] != 0
&& array[1][0] != 0 && array[2][0] != 0 && array[1][1] != 0
&& array[2][1] != 0 && array[1][2] != 0 && array[2][2] != 0)
{
check(array);
if (check(array) == 1)
{
printf("The user wins!\n");
}
else if (check(array) == -1)
{
printf("The computer wins.\n");
}
else
{
printmatch(array);
printf("It's a draw!\n");
}
goto done;
}
++fill;
label:
complacer = rand() % 3;
complacer2 = rand() % 3;
if (array[complacer][complacer2] == 0)
{
array[complacer][complacer2] = -1;
check(array);
}
else
goto label;
++fill;
printmatch(array);
int fullcheck = check(array);
if (fullcheck == 1)
{
printf("The user wins!");
break;
}
if (fullcheck == -1)
{
printf("The computer wins.");
break;
}
if (fill > 9)
break;
} while (fill < 10);
done: printf("\nDo you want to continue? Y/N\n");
scanf("%c %c", &y, &Y);
} while ((Y == 'Y' || Y == 'y'));
getchar();
return 0;
}
int printmatch(int array[3][3])
{
int i;
int j;
for (i = 0; i < 3; i++)
{
for (j = 0; j < 3; j++)
{
printf("%d\t", array[j][i]);
}
printf("\n");
}
}
int check(int array[3][3])
{
int settle;
if (array[0][0] == 1 && array[1][1] == 1 && array[2][2] == 1)
{
settle = 1;
}
else if (array[0][0] == -1 && array[1][1] == -1 && array[2][2] == -1)
{
settle = -1;
}
if (array[0][0] == 1 && array[0][1] == 1 && array[0][2] == 1)
{
settle = 1;
}
else if (array[0][0] == -1 && array[0][1] == -1 && array[0][2] == -1)
{
settle = -1;
}
if (array[0][2] == 1 && array[1][2] == 1 && array[2][2] == 1)
{
settle = 1;
}
else if (array[0][2] == -1 && array[1][2] == -1 && array[2][2] == -1)
{
settle = -1;
}
if (array[0][1] == 1 && array[1][1] == 1 && array[2][1] == 1)
{
settle = 1;
}
else if (array[0][1] == -1 && array[1][1] == -1 && array[2][1] == -1)
{
settle = -1;
}
if (array[1][0] == 1 && array[1][1] == 1 && array[1][2] == 1)
{
settle = 1;
}
else if (array[1][0] == -1 && array[1][1] == -1 && array[1][2] == -1)
{
settle = -1;
}
if (array[0][0] == 1 && array[1][0] == 1 && array[2][0] == 1)
{
settle = 1;
}
else if (array[1][0] == -1 && array[1][1] == -1 && array[1][2] == -1)
{
settle = -1;
}
if (array[2][0] == 1 && array[1][1] == 1 && array[0][2] == 1)
{
settle = 1;
}
else if (array[1][0] == -1 && array[1][1] == -1 && array[1][2] == -1)
{
settle = -1;
}
if (array[2][0] == 1 && array[2][1] == 1 && array[2][2] == 1)
{
settle = 1;
}
else if (array[2][0] == -1 && array[2][1] == -1 && array[2][2] == 1)
{
settle = -1;
}
return settle;
}
goto
для обработки ошибок. Я настоятельно рекомендую против этого. Есть много причин, и на самом деле есть много колонок, статей, стяжек и разглагольствований против этого (и иногда статьи в пользу), но в основном все сводится к следующему: это добавляет уровень путаницы и сложности, и это разрушает обычные потоки управления, которые любой, кто смотрит на ваш код, ожидает найти. (Дляgoto
существуют допустимые варианты использования, и я работал с производственным кодом, в котором он используется, но пока вы не станете настоящим экспертом и не будете знать, что делаете, вам не следует даже считай.) - person This isn't my real name   schedule 02.08.2013