C 中的逻辑运算符导致我的循环出现问题?

Logical Operators in C causing issue with my loop?

我正在为一项任务制作游戏,其中有 2 名玩家,每回合玩家掷 2 个骰子。当我问玩家是否想再次滚动时,一切都从那里向南。我很困惑,因为即使我将我的 rollAgain 角色更改为 'n',它仍然会在我想要的地方播放我的循环 运行 只有当 rollAgain'y''Y'。这是我的第一个 C 程序,我以前只用 Java 编程过。我觉得我一定是在我的 while 循环中错误地检查了逻辑运算符,但我知道我做错了什么,我现在已经检查了所有代码好几次了。

这是我的代码:

#include <stdio.h>
#include <stdlib.h>     // NULL constant, srand() & rand() functions
#include <time.h>       // access your computer’s clock time

// function prototype statements
int rollDice();
int calcPoints(int die1, int die2);
char checkOne(int die1, int die2);

int main()
{
    int p1Score = 0;
    int p2Score = 0;
    int turnTotal = 0;
    char rollAgain = 'Y';
    char rolled1 = 'N';
    int die1;
    int die2;

    printf("Welcome to the Pig Game. Each turn the player rolls two dice repeatedly until a single 1 is rolled or the player holds.\n\n");
    printf("If a single 1 is rolled all points are lost. If the player holds, all earned points are kept.\n");
    printf("If double 1's are rolled 25 points are earned, if any other doubles are rolled the value is doubled.\n");
    printf("Player 1 has an advantage because they get to go first, the youngest player gets to be Player 1.\n\n");
    printf("First player to 100 points wins, let the games begin!!!\n\n");

    do
    {
        //----------------------P1's turn starts----------------------------------------
        while ((rollAgain == 'Y' || rollAgain == 'y') && rolled1 == 'N')
        {
            die1 = rollDice(); //roll die 1
            die2 = rollDice(); //roll die 2

            printf("Player 1 rolls %d, and %d\n", die1, die2);
            rolled1 = checkOne(die1, die2); //check if turn ending 1 is rolled if they did the below while loop will not run and the current while loop will end.

            if(rolled1 == 'N') //if a single 1 wasn't rolled calculate total for the turn
            {
                turnTotal += calcPoints(die1, die2);

                printf("Player 1 your turn total so far is %d. Would you like to roll again?\n", turnTotal);
                fflush(stdin);
                scanf_s("%c", &rollAgain);
            }

        }

        //-------------------------P1's turn is now over---------------------------------
        if (rolled1 == 'Y')   //turnTotal isn't added to p1Score
        {
            printf("Sorry Player 1 your turn is over because you rolled a 1 on a single die :(\n");
            printf("Your total score is now: %d.\n", p1Score);
        }
        else //player1 must have held
        {
            printf("Congratulations on scoring %d point this turn Player 1!\n", turnTotal);
            p1Score += turnTotal;
            printf("Your total score is now: %d.\n", p1Score);
        }

        //reset variables to start p2s turn
        turnTotal = 0;
        rolled1 = 'N';
        rollAgain = 'Y';

        //----------------------P2's turn starts----------------------------------------
        while ((rollAgain == 'Y' || rollAgain == 'y') && rolled1 == 'N' && p1Score < 100) //player2's turn should not start if player 1 has already won the game so we must check p1's score as well
        {
            int die1 = rollDice(); //roll die 1
            int die2 = rollDice(); //roll die 2

            printf("Player 2 rolls %d, and %d\n", die1, die2);
            rolled1 = checkOne(die1, die2); //check if turn ending 1 is rolled if it was the below while loop will not run and the current while loop will end.

            if(rolled1 == 'N') //if a single 1 wasn't rolled calculate total for the turn
            {
                turnTotal += calcPoints(die1, die2);

                printf("Player 2 your turn total so far is %d. Would you like to roll again?\n", turnTotal);
                fflush(stdin);
                scanf_s("%c", &rollAgain);
            }

        }

        //-------------------------P2's turn is now over---------------------------------
        if (rolled1 == 'Y' && p1Score < 100)   //turnTotal isn't added to p1Score
        {
            printf("Sorry Player 2 your turn is over because you rolled a 1 on a single die :(\n");
            printf("Your total score is now: %d.\n", p2Score);
        }
        if (rolled1 == 'N' && p1Score < 100) //player2 must have held, use an if statement rather than else because we don't want this code to play if p1 has already won
        {
            printf("Congratulations on scoring %d point this turn Player 2!\n", turnTotal);
            p2Score += turnTotal;
            printf("Your total score is now: %d.\n", p2Score);
        }

        //reset variables for p1's turn
        turnTotal = 0;
        rolled1 = 'N';
        rollAgain = 'Y';

        //if either player's score is > 100 the game is now over so the game ending code will now play

    } while (p1Score < 100 && p2Score < 100);

    if (p1Score >= 100) //player 1 has won, congratulate them
        printf("Congratulations Player 1, you have won the game! Pat yourself on the back!\n");

    else //player 1 didn't win so player 2 must have won since there are no draws
        printf("Congratulations Player 2, you have won the game! You are awesome!\n");

    return 0; //end main
}

//function rollDice rolles the dice for the player using a random number between 1-6.
int rollDice()
{
    // seed the random number generator using the computers clock
    srand(time(0));

    //generate a random number between 1-6
    int num = (rand() % 6) + 1;

    return num;
}

//function calcPoints that calculates how many points the player earned.
int calcPoints(int die1, int die2)
{
    int points;

    if (die1 == die2) //check if doubles were rolled
    {
        //snake eyes = 25 points
        if (die1 == 1)
            points = 25;
        //regular doubles = the value on the dice *2
        else
            points = (die1 + die2) * 2;
    }
    else //doubled weren't rolled
        points = die1 + die2;

    return points;
}

//function checkOne that checks if the player rolled a single 1 during their turn.
char checkOne(int die1, int die2)
{
    if (die1 == 1 && die2 != 1)
        return 'Y';
    else if (die1 != 1 && die2 == 1)
        return 'Y';
    else
        return 'N';
}

如果掷出单个 1,玩家回合应该结束。 我真的很感激任何帮助我不确定我哪里出错了。代码在询问我是否要再次滚动后有自己的想法。

Player 1 rolls 2, and 2
Player 1 your turn total so far is 8. Would you like to roll again?
y
Player 1 rolls 3, and 3
Player 1 your turn total so far is 20. Would you like to roll again?
Congratulations on scoring 20 point this turn Player 1!
Your total score is now: 20.
Player 2 rolls 3, and 3
Player 2 your turn total so far is 12. Would you like to roll again?

如果我同意再次滚动,这是我得到的输出。在此输出的末尾,它允许我输入是否要再次滚动。

    Player 1 rolls 3, and 3
Player 1 your turn total so far is 12. Would you like to roll again?
n
Congratulations on scoring 12 point this turn Player 1!
Your total score is now: 12.
Player 2 rolls 1, and 1
Player 2 your turn total so far is 25. Would you like to roll again?
Congratulations on scoring 25 point this turn Player 2!
Your total score is now: 25.
Player 1 rolls 1, and 1
Player 1 your turn total so far is 25. Would you like to roll again?

如果我拒绝再次滚动,这是我得到的输出。在此输出的末尾,它允许我输入是否要再次滚动。

您的代码中存在多个经典问题:

  • fflush(stdin); 有未定义的行为。只需删除此语句,它不会消耗 stdin.
  • 中的待处理输入
  • scanf_s("%c", &rollAgain); 将读取输入流中待处理的换行符。要跳过它,您只需在格式字符串中添加一个 space 并且您必须测试 scanf_s 是否成功以避免文件末尾的未定义行为:

    if (scanf_s(" %c", &rollAgain) != 1) {
        exit(1);   // unexpected end of file or some other error
    }
    
  • 您不应该在每次掷骰子时都重新初始化随机数生成器,只需在程序开始时重新初始化一次(将 srand() 函数调用移至 main 函数,并传递给它 clock() ,它的变化比 time(NULL) 快得多):

    //function rollDice rolls the die for the player using a random number between 1-6.
    int rollDice() {
        //generate a random number between 1-6
       return (rand() % 6) + 1;
    }