【问题标题】:rock paper scissors game in c. Can someone tell where my fault is?c中的石头剪刀布游戏。谁能告诉我错在哪里?
【发布时间】:2021-03-30 02:35:52
【问题描述】:

计算机总是给出相同的输入。

例如:exampleexample2

就像在示例中一样,我总是选择岩石,而计算机总是选择纸张。我应该怎么做才能让电脑给出不同的结果?

可能最后一个函数有问题,但我找不到。有人可以帮帮我吗?

enum Move {ROCK = 1, PAPER, SCISSORS}input;

int input, computerInput = 0;
int rock = 1;
int paper = 2;
int scissors = 3;
int computerPoint = 0, userPoint = 0;

printf(" ###### Welcome to Rock-Paper-Scissors Game ###### \n");
printf(" ### Rules: \n ### Press 1 for Rock \n ### Press 2 for Paper \n ### Press 3 for Scissors \n ### First one to reach 3 points will win. \n");

printf("Input your move : ");
scanf("%d", &input);


while(input < 1 || input > 3)
{
printf("Your input must be 1, 2 or 3 \n");
printf("Input your move : ");
scanf("%d",&input);
}
    
while(input == computerInput)
{
        printf("It's draw. \n");
        printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
        printf("Input your move : ");
        scanf("%d",&input);
            
}


while(input != computerInput && userPoint < 3 && computerPoint < 3){
    
    switch (input)
    {
        
        case ROCK:
        if(computerInput == 2){
            printf("You picked Rock. Computer picked Paper. Computer got 1 point(s). \n");
            computerPoint++;            
        }
        else if(computerInput == 3){
            printf("You picked Rock. Computer picked Scissors. You got 1 point(s). \n");
            userPoint++;
        }
        break;
        case PAPER:
        if(computerInput == 1){
            printf("You picked Paper. Computer picked Rock. You got 1 point(s). \n");
            userPoint++;
        }else if(computerInput == 3){
            printf("You picked Paper. Computer picked Scissors. Computer got 1 point(s). \n");
            computerPoint++;
        }    
        break;
        case SCISSORS:
        if(computerInput == 1){
            printf("You picked Scissors. Computer picked Rock. Computer got 1 point(s). \n");
            computerPoint++;
        }else if(computerInput == 2){
            printf("You picked Scissors. Computer picked Paper. You got 1 point(s). \n");
            userPoint++;                
        }   
        break;
        return 0;
    }
   
   
   if(computerPoint == 3){
    printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
    printf("\n!!Computer won the game!!");
    return 0;
    }

    if(userPoint == 3){
    printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
    printf("\n!!You won the game!!");
    return 0;
    }
   
    printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
    printf("Input your move : ");
    scanf("%d",&input);
}
return 0;

enum Move getRandomMove(){
    int computerInput;
    srand(time(NULL));
    computerInput  = 1 + rand() %3;
    return computerInput;
}
  

【问题讨论】:

  • 阅读 Modern Cthis C reference 以及您的 C 编译器 GCC 和调试器 GDB 的文档
  • 您能否将显示的代码简化为您用作示例的一种情况并制作一个minimal reproducible example?给出您输入的确切输入、您期望的输出、解释原因以及您得到的输出将有很大帮助。见How to Ask
  • 关于switch部分的两个问题,但是如果其他部分有问题,我都发了,也许有人可以警告他们。如果你仍然说删除那些部分,我会删除它们。
  • if(input = computerInput) 是错字吗?顺便说一句:由于重复三行说明位置、询问和下一步行动,代码不必要地臃肿。它们都可以(6 * 3 = 18 行)被放在switch 代码块之外的那三行替换
  • 您修改后的代码仍在使用if(computerPoint = 3) 之类的比较。你的意思是==

标签: c function time enums srand


【解决方案1】:

TL;DR 的答案是这样的:

  • 您将inputcomputerInput= 进行比较,而您应该使用==
  • 您创建了一个名为getRandomMove() 的函数,我怀疑您的意思是用来设置computerInput,但实际上您并没有在任何地方调用它,所以computerInput 开始时未初始化,然后被意外分配给上面的错误。

但既然我很无聊,让我们来看看它为什么会这样:

printf("Input your move : ");
scanf("%d", &input);

while (input < 1 || input > 3)
{
    printf("Your input must be 1, 2 or 3 \n");
    printf("Input your move : ");
    scanf("%d", &input);
}

到目前为止还不错。您要求用户输入一个从 1 到 3 的数字,如果他们不这样做,则重复输入请求。

while (input != computerInput && userPoint < 3 && computerPoint < 3)
{

哦哦。这是您的第一个错误:您将 inputcomputerInput 进行比较而没有先初始化它。

您在程序的开头声明了computerInput

int input, computerInput;

但由于您没有给它一个值,computerInput 将包含任意内存数据。由于这个曾经为 1、2 或 3 的可能性非常小,input != computerInput 第一次可能不会是真的。

case ROCK:
   if (computerInput = 2)

这里您使用的是 assignment 运算符 (=),而不是 equality 运算符 (==)。您不是将computerInput2 进行比较,而是将其值设为2。碰巧在 C 中,赋值语句将计算出您正在分配的值。

所以这归结为if(2),这总是正确的,因为它不是零。此时,你再给计算机点加一,跳出 switch 语句。

对于您的第一个示例,您每次都输入“1”。所以“1”不等于“2”(这是你在上面设置的computerInput),所以循环又开始了。你又输入了 ROCK,所以上面发生了完全相同的事情,导致计算机的另一个分数。

每次都这样,直到分数达到 3 并且计算机获胜。

【讨论】:

  • 我非常感谢您,先生。你是王者但我想这是因为我从早上开始就一直在努力解决这个问题,我该如何定义这个计算机输入。我的意思是,我该如何解决你所说的第一个错误。
【解决方案2】:

我用自己的代码“修复”了你的问题:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/**
 * ROCK = 1 
 * PAPER = 2
 * SCISSORS = 3
 */

// random move returns a random int from 1 - 3.
// I removed the local variable
int getRandomMove()
{
    return 1 + rand() %3;
}

// main logic of the game
int main()
{
    //Your enum with rock, paper, scissors defind as 1, 2, 3
    enum Move {ROCK = 1, PAPER = 2, SCISSORS = 3} userInput = 0;

    // sets a random seed for the rand()-function
    srand(time(NULL));

    // here you declared userInput another time
    // int userInput is not needed, you already got it up here 
    int computerInput = 0, computerPoint = 0, userPoint = 0;

    printf(" ###### Welcome to Rock-Paper-Scissors Game ###### \n");
    printf(" ### Rules: \n ### Press 1 for Rock \n ### Press 2 for Paper \n ### Press 3 for Scissors \n ### First one to reach 3 points will win. \n");

    // add big while loop to avoid multiple loops:
    // runs as long as no one reached the goal of 3 points
    while (computerPoint < 3 && userPoint < 3)
    {

        // Test for valid input
        // when user input is unvalid (not from 1 - 3), we ask to enter a number again
        while (userInput < 1 || userInput > 3)
        {
            printf("\n");
            printf("Your input must be 1, 2 or 3 \n");
            printf("Input your move : ");
            scanf("%d",&userInput);
            printf("\n");
        }
        
        // You missed this in your initial program:
        // The computer gets a random value (ROCK/PAPER/SCISSOR)
        computerInput = getRandomMove();

        // what if it's a draw...?
        if (userInput == computerInput)
        {
            printf("It's draw. \n");
            printf("You got %d point(s) and the computer has %d point(s)\n",userPoint, computerPoint);
            userInput = 0;
            computerInput = 0;
            continue;
        }
        
        // I changed little besides comparing the computer input with the the different "Move" types
        switch (userInput)
        {
            case ROCK:
                if(computerInput == PAPER)
                {
                printf("You picked Rock. Computer picked paper. Computer got 1 point(s). \n");
                computerPoint++;          
                }
                else if(computerInput == SCISSORS)
                {
                printf("You picked rock. Computer picked scissors. You got 1 point(s). \n");
                userPoint++;
                }
                break;
            case PAPER:
                if(computerInput == ROCK)
                {
                    printf("You picked paper. Computer picked Rock. You got 1 point(s). \n");
                    userPoint++;
                }
                else if(computerInput == SCISSORS)
                {
                    printf("You picked paper. Computer picked scissors. Computer got 1 point(s). \n");
                    computerPoint++;
                }    
                break;
            case SCISSORS:
                if(computerInput == ROCK)
                {
                    printf("You picked Scissors. Computer picked Rock. Computer got 1 point(s). \n");
                    computerPoint++;
                }else if(computerInput == PAPER)
                {
                    printf("You picked Scissors. Computer picked Paper. You got 1 point(s). \n");
                    userPoint++;                
                }
                break;
            default:
                break; 
        }

        // game ending condition (one player reached 3 points)
        if (computerPoint == 3 || userPoint == 3)
        {
            // print out each players points
            printf("You got %d points and the Computer got %d points\n", userPoint, computerPoint);
            
            // computer won
            if (computerPoint == 3)
            {
                printf("You lost :/\n");
            }
            // player won
            else 
            {
                printf("You WON!!!\n");
            }
            // if this is reached the next time we enter the loop while(computerPoint < 3 && userPoint < 3) 
            // isn't true anymore so we skip to the end of program (no break, continue whatever needed)
        }

        // set the values 0 for the next loop
        userInput = 0;
        computerInput = 0;

    }

    // waits for the user to enter "enter"
    // else the console would close before you see the result!
    system("pause");
}

首先,您的代码非常混乱,我对其进行了一些重组,使其更易于阅读和理解。我在大部分语句中添加了 cmets 来解释以下代码的作用。

让我们来看看这个

由于您的代码太小,您可以复制 includes 以及 main 函数。

首先,我在开头设置了getRandomMove() 函数,所以我们不必单独声明它(再次,混乱的代码等)。

enum Move getRandomMove() { // we don't want to return an enum but an Integer
  
    int computerInput; // here you define a variable to return it's value a few lines further, i deleted it
  
    srand(time(NULL)); // this function should be called once, i put it in the main function

    computerInput  = 1 + rand() %3; // you store a random number in a variable to return it on line later hence we put the function call in the return
  
    return computerInput;
}   

我去掉了一些代码,因为

int a = 0;
return a;

return 0;相同。

接下来我将while 循环的数量减少到两个。

第一次重复,直到玩家达到 3 分。

我在计算机获取随机数的地方添加了一行,你错过了,所以计算机永远不会公平: computerInput = getRandomMove();

接下来我们检查他们是否平局,如果是,我们重置玩家Moves。 在循环结束时我添加了两行

userInput = 0;
computerInput = 0;

重置玩家Moves,过程与平局相同。

【讨论】:

  • 在您的用户输入循环中,您使用 userInput 的值而不对其进行初始化。也许你想做一个do {} while 循环而不是while 循环。当你在它的时候,把你的变量声明移到需要它们的最里面的块中。
  • 也可以不用switch/if而用算术来确定获胜者。提示:针对不同的输入计算(3 + userInput - computerInput)%3)
  • 我不想改变他的游戏逻辑本身,我懒得写一个新的带有计算的开关块:/。识别移动变量的提示。
  • 我没有 Vars 可以移动到其他任何地方
  • 我睡着了,所以我才看到答案,对不起。我不能感谢你,你纠正了所有的错误。但我要问一些事情,实际上这是最让我困惑的事情。 int getRandomMove () { return 1 + rand ()% 3;我可以把这个函数写成枚举函数​​吗?如果你问为什么你想要这样的东西,这是我的作业,老师就是这样想要的。我检查了所有的笔记,但我没有遇到过这样的例子。你知道我该怎么做吗?顺便说一句,再次非常感谢你
【解决方案3】:

在所有更改之后,这是正确的工作和清除版本。非常感谢所有提供帮助的人。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void){

enum Move {ROCK = 1, PAPER, SCISSORS}input;
srand(time(NULL));
int computerInput;
int computerPoint = 0, userPoint = 0;

enum Move getRandomMove()
{
return (enum Move)(1 + rand() % SCISSORS);
}


printf(" ###### Welcome to Rock-Paper-Scissors Game ###### \n");
printf(" ### Rules: \n ### Press 1 for Rock \n ### Press 2 for Paper \n ### Press 3 for Scissors \n ### First one to reach 3 points will win. \n");

printf("Input your move : ");
scanf("%d", &input);

while (computerPoint < 3 && userPoint < 3)
{
    while(input < 1 || input > 3)       
    {
        printf("Your input must be 1, 2 or 3 \n");
        printf("Input your move : \n\n");
        scanf("%d",&input);
    }
    
    
    computerInput = getRandomMove();
    
    if(input == computerInput)
    {  
        printf("\nIt's draw. \n");
        printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
        printf("Input your move : ");
        scanf("%d",&input);
        continue;
    }
    
    
    switch (input)
    {
        
        case ROCK:
        if(computerInput == PAPER){
            printf("\nYou picked Rock. Computer picked Paper. Computer got 1 point(s). \n");
            computerPoint++;            
        }
        else if(computerInput == SCISSORS){
            printf("\nYou picked Rock. Computer picked Scissors. You got 1 point(s). \n");
            userPoint++;
        }
        break;
        case PAPER:
        if(computerInput == ROCK){
            printf("\nYou picked Paper. Computer picked Rock. You got 1 point(s). \n");
            userPoint++;
        }else if(computerInput == SCISSORS){
            printf("\nYou picked Paper. Computer picked Scissors. Computer got 1 point(s). \n");
            computerPoint++;
        }    
        break;
        case SCISSORS:
        if(computerInput == ROCK){
            printf("\nYou picked Scissors. Computer picked Rock. Computer got 1 point(s). \n");
            computerPoint++;
        }else if(computerInput == PAPER){
            printf("\nYou picked Scissors. Computer picked Paper. You got 1 point(s). \n");
            userPoint++;                
        }   
        break;
    }
    
    
    if(computerPoint == 3){
    printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
    printf("\n!!Computer won the game!!");
    return 0;
    }

    if(userPoint == 3){
    printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
    printf("\n!!You won the game!!");
    return 0;
    }
   
    printf("Your Point is %d and Computer's point is %d \n",userPoint, computerPoint);
    printf("Input your move : ");
    scanf("%d",&input);
}
return 0;   
}

【讨论】:

  • 次要挑剔:将inputcomputerInput 的声明(和初始化)移动到while (computerPoint &lt; 3 &amp;&amp; userPoint &lt; 3)-loop 的主体内。现在编写程序的方式,它必须记住从循环的一次迭代到下一次迭代的那些变量的值。这只是像这样的简单程序中的一个小丑。但在更复杂的程序中,它可能对效率的影响很小,更重要的是,对可读性的影响很大。
猜你喜欢
  • 1970-01-01
  • 2016-01-16
  • 2022-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多