【问题标题】:While loop doesnt exit but condition are true虽然循环不退出但条件为真
【发布时间】:2019-03-08 12:48:44
【问题描述】:

我在这里是因为我有一个 C 项目,我需要在其中制作井字游戏。

我在这里做的是我问第一个玩家他想在哪里玩,我打印板然后我检查是否有同一玩家的对角线(仅实现 \ 对角线),如果有@ 987654321@ = 真。

问题出在 while 循环中,如果 compteur = 9 或 etat = true 它不会离开循环,我不明白为什么。我试过调试器,这些条件都是真的。

printTab() 是一个简单的 printf 函数 saisieInt() 是一个带有 scanf 和验证数字不是 9

的函数

我是猴子吗?

int main()  
{  
  int tab[COTE][COTE] = { 0 };  
  int compteur = 0, 
  joueur = 1,
  choix;  
  bool etat=false;
  printf("commande : ");
  choix = saisieInt();
  compteur++;

  while ( compteur < 9 || etat != true) {
///position where to place the piece///////////////////////////////
    int colonne = choix % 3;
    int ligne = choix / 3;
    tab[ligne][colonne - 1] = joueur;
///////////////////////////////////////////////

    printTab(tab);

///switch between the 2 players///////////////////////////////
    if (joueur == 1)
      joueur = 2;
    else
      joueur = 1;
///////////////////////////////////////////////

///check if one has a diagonal line //////////////////////////
    if (compteur >= 6) {
      int compteurdiag = 0;
      for (int i = 0; i < COTE; i++) {
        if (tab[i][i] == joueur) {
          compteurdiag++;
        }
        else {
          compteurdiag = 0;
        }
        if (compteurdiag == COTE)
          {
            etat = true;
          }
      }
    }
///////////////////////////////////////////////
//if (etat == false) {
    printf("compteur : %d commande : ", compteur);
    choix = saisieInt();
    compteur++;
//}
  }
  printf("compteur : %d termine\n", compteur);
}

void printTab(int t[COTE][COTE]) {
    int i, j;
    puts("\n|---|---|---|");
    for (i = 0; i < COTE; i++) {
        for (j = 0; j < COTE; j++) {
            printf("|%2d ", t[i][j]);
        }
        puts("|");
        for (j = 0; j < COTE; j++) {
            printf("|---");
        }
        puts("|");
    }
}


int saisieInt() {
    int valeur, n;
    n = scanf("%d", &valeur);
    while (n != 1  || valeur > 9) {
        printf("Attention, erreur de saisie\nRechoisissez : ");
        while (getchar() != '\n');
        n = scanf("%d", &valeur);
    }
    return(valeur);
}

【问题讨论】:

  • 这两个测试都必须为 false 才能结束循环。是这样的吗?
  • 只需将tab[ligne][colonne - 1] = joueur; 替换为tab[ligne][colonne] = joueur;,看我的回答

标签: c while-loop


【解决方案1】:

拥有

int colonne = choix % 3;

假设 choix 是一个从 0 到 2 的正数 colonne

 tab[ligne][colonne - 1] = joueur;

colonne 为 0 时,您修改 tab[ligne - 1][2] 或超出数组,这就是为什么您在理论上找不到 3 个对齐的情况

只是做

tab[ligne][colonne] = joueur;

这里有个建议:

#include <stdio.h>

#define COTE 3

void printTab(int (*tab)[COTE])
{
  for (int l = 0; l != COTE; ++l) {
    for (int c = 0; c != COTE; ++c) {
      printf("[%c]", *(" XO" + tab[l][c]));
    }
    putchar('\n');
  }
  putchar('\n');
}

int main()
{
  int tab[COTE][COTE] = { 0 };
  int joueur = 1, compteur = 0;

  printTab(tab);

  do {
    int l, c;

    printf("player %d, enter line and column (1..%d) : ", joueur, COTE);
    if ((scanf("%d %d", &l, &c) != 2) ||
        (l < 1) || (c < 1) ||
        (l > COTE) || (c > COTE) ||
        (tab[l - 1][c - 1] != 0)) {
      while (getchar() != '\n')
        ;
      puts("illegal position or not free");
    else {
      tab[l - 1][c - 1] = joueur;

      printTab(tab);      

      /* done ? */
      for (l = 0; l != COTE; ++l) {
        int j = tab[l][0];

        if (j != 0) {
          for (c = 1; ; c += 1) {
            if (c == COTE) {
              printf("joueur %d gagne\n", j);
              return 0;
            }
            if (tab[l][c] != j)
              break;
          }
        }
      }
      for (c = 0; c != COTE; ++c) {
        int j = tab[0][c];

        if (j != 0) {
          for (l = 1; ; l += 1) {
            if (l == COTE) {
              printf("joueur %d gagne\n", j);
              return 0;
            }
            if (tab[l][c] != j)
              break;
          }
        }
      }

      int j;

      j = tab[0][0];
      if (j != 0) {
        for (l = 0; ; l += 1) {
          if (l == COTE) {
            printf("joueur %d gagne\n", j);
            return 0;
          }
          if (tab[l][l] != j)
            break;
        }
      }

      j = tab[0][COTE - 1];
      if (j != 0) {
        for (l = 0; ; l += 1) {
          if (l == COTE) {
            printf("joueur %d gagne\n", j);
            return 0;
          }
          if (tab[l][COTE - l - 1] != j)
            break;
        }
      }

      if (++joueur == 3)
        joueur = 1;

      compteur += 1;
    }
  } while (compteur != COTE*COTE-1);

  puts("partie nulle");
}

编译和执行:

/tmp % gcc -pedantic -Wextra ttt.c
/tmp % ./a.out
[ ][ ][ ]
[ ][ ][ ]
[ ][ ][ ]

player 1, enter line and column (1..3) : a 2
illegal position or not free
player 1, enter line and column (1..3) : 1 4
illegal position or not free
player 1, enter line and column (1..3) : 1 1
[X][ ][ ]
[ ][ ][ ]
[ ][ ][ ]

player 2, enter line and column (1..3) : 2 1
[X][ ][ ]
[O][ ][ ]
[ ][ ][ ]

player 1, enter line and column (1..3) : 1 1
illegal position or not free
player 1, enter line and column (1..3) : 1 3
[X][ ][X]
[O][ ][ ]
[ ][ ][ ]

player 2, enter line and column (1..3) : 3 2
[X][ ][X]
[O][ ][ ]
[ ][O][ ]

player 1, enter line and column (1..3) : 2 1
illegal position or not free
player 1, enter line and column (1..3) : 1 2
[X][X][X]
[O][ ][ ]
[ ][O][ ]

joueur 1 gagne

/tmp % ./a.out
[ ][ ][ ]
[ ][ ][ ]
[ ][ ][ ]

player 1, enter line and column (1..3) : 1 1
[X][ ][ ]
[ ][ ][ ]
[ ][ ][ ]

player 2, enter line and column (1..3) : 2 2
[X][ ][ ]
[ ][O][ ]
[ ][ ][ ]

player 1, enter line and column (1..3) : 3 3
[X][ ][ ]
[ ][O][ ]
[ ][ ][X]

player 2, enter line and column (1..3) : 1 2
[X][O][ ]
[ ][O][ ]
[ ][ ][X]

player 1, enter line and column (1..3) : 3 2
[X][O][ ]
[ ][O][ ]
[ ][X][X]

player 2, enter line and column (1..3) : 3 1
[X][O][ ]
[ ][O][ ]
[O][X][X]

player 1, enter line and column (1..3) : 2 3
[X][O][ ]
[ ][O][X]
[O][X][X]

player 2, enter line and column (1..3) : 1 3
[X][O][O]
[ ][O][X]
[O][X][X]

joueur 2 gagne

编辑:哎呀你已经把问题解决了,我浪费了我的时间来提出一个无用的建议:-(

【讨论】:

  • 不,如果我删除-1,唯一的变化是我需要把0放在棋盘的n°1盒子上
  • @FistiPaul 你错了,tab[0][-1] 不在 tab
  • @FistiPaul 幸运的是,当您检查时您执行的是 if (tab[i][i] == joueur) 而不是 if (tab[i][i-1] == joueur)
  • 好吧,我的错,但如果我进行更改,即使我是对角线,问题仍然存在
  • 很抱歉您没有看到布鲁诺,但非常感谢您抽出宝贵时间
【解决方案2】:

你的循环条件被破坏了:

while ( compteur < 9 || etat != true) {

这意味着:当你还没有完成第 9 步或没有匹配的对角线时,继续。

如果你有 9 步但没有赢家,它仍然会继续。 此外,如果您有一条对角线但少于 9 步,也请继续。

如果其中一个条件为真,则必须终止,而不是两者都为真。

while ( compteur < 9 && etat != true) {

注意: 这就是您在问题中陈述的问题的原因。 尽管如此,还必须修复 bruno 指出的错误,以避免未定义的行为和潜在的崩溃等。

【讨论】:

  • 是的,这就是问题所在,我绝对是一只猴子。谢谢
  • @FistiPaul 纠正:这是您遇到的 两个 问题中的 一个 ...
猜你喜欢
  • 1970-01-01
  • 2015-09-10
  • 2015-08-07
  • 2019-06-28
  • 2011-12-03
  • 2014-06-12
  • 1970-01-01
  • 2021-11-13
  • 2022-12-17
相关资源
最近更新 更多