0

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;
}
4

1 に答える 1

1

ユーザー入力はです。数字が必要な場合は、誰かが「A」と入力します。「y」または「n」が必要で、数十文字の入力が得られます。防御的なエラー処理を使用してコーディングを改善しようとしたことを称賛します。

sscanf()またはなどを使用する場合scanf()は、必ず結果を確認してください。

int result;  
result = sscanf(buffer, "%this %that ...", &var1);  
if (result != ExpectedResult) // handle error

と を混在fgets()させるgetchar()scanf()、問題が混乱する可能性があります。fgets()2. fgets()は行指向であり、改行scanf()を消費する前に停止することがよくあります。

「Y」または「y」を入力して続行するのは楽しいですが、「文字と enter_key」の組み合わせを使用することはそれほど悪くなく、最初は整理するのが簡単です。

ペアはしゃっくりを引き起こしたfgets() sscanf()かもしれませんが、最終的には整理しやすくなりました. そのスタイルに戻り、 の結果を確認することをお勧めしsscanf()ます。

scanf("%d", &slot);

ここでは、ユーザーが「Enter」を押す前に数字を入力したかどうかはわかりません。ユーザーが数字を入力した場合でも、scanf() は先頭のスペースと数字を消費しますが、次の入力関数のために「Enter」を残します。その代わり:

int ScanCount;
const char *prompt = "\nEnter Position 1-9(from left to right):";
do {
  fputs(prompt, stdout);
  prompt = "Incorrect data input! Try again. \n"; // For the maybe next time around
  if (fgets(line, sizeof(line), stdin) == NULL) {
    // Standard input is closed or some grievous I/O error, let's go home.
    return 0;
  }
  ScanCount = sscanf(line,"%d",&slot);
} while ((ScanCount != 1) || (slot < 1) || slot > 9));

ところで: 「9z」のような数字の後に余分なテキストが入力されたかどうかをテストするためのちょっとしたトリックがあります。ScanCount = ... slot > 9));と置き換えます

char c;
ScanCount = sscanf(line,"%d%[^\n]",&slot, &c);
} while ((ScanCount != 1) || (slot < 1) || slot > 9));  // still ScanCount != 1
于 2013-08-01T00:51:14.490 に答える