-2

The computer always gives the same input.

For example :example or example2

As in the example, I always choose the rock and the computer always chooses the paper. What should I do to make the computer give a different result?

Probably there is something wrong with the last function but I couldn't find it. Can someone help me please?

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;
}
  
  • Read [*Modern C*](https://modernc.gforge.inria.fr/), [this C reference](https://en.cppreference.com/w/c) and the documentation of your C compiler [GCC](http://gcc.gnu.org/) and debugger [GDB](https://www.gnu.org/software/gdb/) – Basile Starynkevitch Dec 19 '20 at 20:13
  • Could you please reduce the shown code to the one case you use as example and make a [mre] of that? Giving the exact input you enter, the output you expect, an explanation why and the output you do get would help a lot. See [ask]. – Yunnosch Dec 19 '20 at 20:16
  • In two questions about the switch part, but if there is something wrong with the other parts, I sent all of them, maybe someone could warn them. If you still say remove those parts, I'll remove them. – Abuzer Kadayıf Dec 19 '20 at 20:24
  • Is `if(input = computerInput)` a typo? Aside: the code is needlessly bloated by repetition of three lines stating the position, asking, and getting the next move. They could all (6 * 3 = 18 lines) be replaced by those three lines placed outside the `switch` code block – Weather Vane Dec 19 '20 at 20:44
  • Thank You Weather Vane. I got the answer to what I want to ask in the second question, I'm correcting the code. – Abuzer Kadayıf Dec 19 '20 at 20:47
  • 2
    Your revised code is still using comparisons like `if(computerPoint = 3)`. Did you mean `==`? – Weather Vane Dec 19 '20 at 20:58
  • Can I send you a direct message Weather Vane. By the way, thank you very much for taking care of the question. – Abuzer Kadayıf Dec 19 '20 at 21:12

3 Answers3

1

The TL;DR answer is this:

  • You are comparing input and computerInput with =, when you should be using ==
  • You made a function called getRandomMove(), which I suspect you mean to use to set computerInput, but you haven't actually called it anywhere, so computerInput starts off uninitialised and is then assigned to accidentally because of the mistake above.

But since I'm bored, lets walk through why it behaves like it does:

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

Good so far. You are asking the user to input a number from 1 to 3, and repeating the input request if they don't do that.

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

Uh oh. This is your first mistake: you are comparing input with computerInput without first initialising it.

You declared computerInput at the start of your program with the line

int input, computerInput;

But since you haven't given it a value, computerInput is going to contain arbitrary memory data. Since the chances of this ever being 1, 2 or 3 are incredibly slim, chances are that input != computerInput will not be true the first time.

case ROCK:
   if (computerInput = 2)

Here you are using the assignment operator (=), instead of the equality operator (==). Instead of comparing computerInput to 2, you are giving it the value of 2. It just so happens that in C, an assignment statement will evaluate to the value you are assigning.

So this boils down to if(2), which is always going to be true, because it isn't zero. At this point, you then add one to the computerpoint, break out of the switch statement.

For your first example, you entered '1' each time. So "1" was not equal to "2" (which is what you set computerInput to above), so the loop started again. You entered ROCK again, so the exact same thing happened above, resulting in another score for the computer.

This keeps happening each time until the score reaches three and the computer wins.

Ben Wainwright
  • 4,224
  • 1
  • 18
  • 36
  • I can't thank you enough, sir. you are king But I guess it's because I've been struggling with this since the morning, how can I define this computerInput. I mean, how can I fix that first error you said. – Abuzer Kadayıf Dec 19 '20 at 22:01
1

I "fixed" you issues with your own code:

#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");
}

First of all you had pretty messy code, i restructured it a little bit to make it easier to read and understand. I added comments to most of the statements to explain what the following code does.

Let's walk though this

Since your code is so small you could copy the includes aswell as the main function.

First of all i set the getRandomMove() function at the beginning, so we don't have to declare it seperatly (again, messy code etc.).

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

I get rid of some code because

int a = 0;
return a;

is the same as return 0;.

Next i reduced the count of while loops down to two.

The first repeats itself until a player has reached 3 points.

I added a line where the computer gets a random number, you missed that so the computer never played fair: computerInput = getRandomMove();

Next we check if they draw, when true we reset the players Moves. At the end of the loop i added two lines

userInput = 0;
computerInput = 0;

to reset the players Moves, same procedure as with a draw.

Zacki
  • 177
  • 11
  • In your user input loop you use the value of `userInput` without initializing it. Maybe you wanted to do a `do {} while` loop rather than `while` loop. And while you are at it, move the declaration of your variables to the innermost block where they are needed. – HAL9000 Dec 20 '20 at 04:20
  • It is also possible to determine the winner without `switch`/`if` but with arithmetic. Hint: calculate `(3 + userInput - computerInput)%3)` for different inputs. – HAL9000 Dec 20 '20 at 04:28
  • I did no want to change up his game logic itself, and i was too lazy to write a new switch block with calculation :/. The hint with moving the variables is recognised. – Zacki Dec 20 '20 at 10:10
  • I have no Vars to move anywhere else – Zacki Dec 20 '20 at 10:18
  • I was asleep so I just saw the answer, I'm sorry. I cannot thank you enough, you corrected all the mistakes. but I'm going to ask something, actually it's the thing that confuses me the most. int getRandomMove () { return 1 + rand ()% 3; } Can I write this function as an enum function. If you ask why you want something like that, this is my homework and the teacher wanted it that way. I checked all the notes, but I have not encountered such an example. Do you know how I can do it? By the way, thank you very much again <3 – Abuzer Kadayıf Dec 20 '20 at 13:28
  • Ok i did. enum Move getRandomMove() { return (enum Move)(1 + rand() % SCISSORS); } – Abuzer Kadayıf Dec 20 '20 at 14:29
  • Thank you again Zacki You are my Hero. :D – Abuzer Kadayıf Dec 20 '20 at 14:29
  • Yeah, you should type cast it, and it will work fine. The "MOVE" enom is just an int between 1 - 3. You should also consider to mark one answer as solution to close the topic – Zacki Dec 20 '20 at 15:09
0

After all the changes, this is the correct working and cleared version. Thank you very much to everyone who helped.

#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;   
}
  • Minor nitpick: Move the declaration (and initialization) of `input` and `computerInput` inside the body the `while (computerPoint < 3 && userPoint < 3)`-loop. The way the program is written now, it has to remember the value of those variables from one iteration of the loop to the next. This is only a minor ugliness in a simple program as this . But in a more complex program it may have a tiny effect on efficiency and, more important, a HUGE effect on readability. – HAL9000 Dec 20 '20 at 16:00