0

I am working on an assignment in C, trying to create a program that simulates a "Rock, Paper, Scissors" match between the user and the computer. Everything is working fine except the for loop I have created is skipping the first iteration of the loop and going straight to my second match. Is there any way to fix this? Code and compilation below

main.c

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

int main(void) {
    srand(time(0)); // This gives the random function a new seedallows me to use time in order to create "random" numbers. //
    time_t t; // Allows the program to store system time values. //

    int R; // This statement declares the variable for the move "Rock". //
    int P; // This statement declares the variable for the move "Paper". //
    int S; // This statement declares the variable for the move "Scissors". //

    int numMatches; // This statement declares the variable for the number of matches that are to be played. //
    int roundNumber; // This statement declares the variable for the current round of the match that is being played. //
    int compMove; // This statement declares the variable that represents the move (rock, paper, or scissors) that the computer makes. //
    char userMove; // This statement declares the variable that represents the move (rock, paper, or scissors) that the user of the program chooses. //
    int randNumber; // This statement declares the variable for the random number that will be generated. //

    printf("Starting the Rock, Paper, Scissors Game!\n");

    printf("Enter the number of matches to play: ");
    scanf(" %d", &numMatches); // This statement allows the user to input the number of matches he/she wishes to play. //

    for (roundNumber = 1; roundNumber <= numMatches; roundNumber++) { // This for statement first initializes the number of rounds to 1. Then, the statement sets a parameter that the for loop will only continue as long as the number of matches completed is less that than the total matches that are to played. The last statement increments

        printf("\nMatch %d: Enter R for rock, P for paper, or S for scissors: ", roundNumber);
        fflush(stdin);
        userMove = getchar();

        randNumber = (rand() % 3) + 1; //1 to 3//
        compMove = randNumber == 0 ? 'R' : randNumber == 1 ? 'P' : 'S';

        if ((userMove == 'R') && (compMove == 'S')) { // These statements state the result of the game depending on the user's move and the computer's move. //
            printf("The computer chose scissors. You won \n");
        } else
        if ((userMove == 'P') && (compMove == 'R')) {
            printf("The computer chose rock. You won \n");
        } else
        if ((userMove == 'S') && (compMove == 'P')) {
            printf("The computer chose paper. You won \n");
        } else
        if ((userMove == 'R') && (compMove == 'R')) {
            printf("The computer chose rock. You tied \n");
        } else
        if ((userMove == 'P') && (compMove == 'P')) {
            printf("The computer chose paper. You tied \n");
        } else
        if ((userMove == 'S') && (compMove == 'S')) {
            printf("The computer chose scissors. You tied \n");
        } else
        if ((userMove == 'R') && (compMove == 'P')) {
            printf("The computer chose paper. You lose \n");
        } else
        if ((userMove == 'P') && (compMove == 'S')) {
            printf("The computer chose scissors. You lose \n");
        } else
        if ((userMove == 'S') && (compMove == 'R')) {
            printf("The computer chose rock. You lose \n");
        }
    }
    return 0;
}

compile

chqrlie
  • 131,814
  • 10
  • 121
  • 189
  • Im not sure but test it:remove predefine roundNumber and define it in for arguement.like this i mean:for(int roundNumber =1;roundNuber<=numMatches;roundNuber++) – akbar Feb 15 '20 at 00:38
  • The `scanf` does not consume the newline character. So the first`getchar` call and every second one after that will read a newline instead of the intended character. – kaylum Feb 15 '20 at 00:42
  • One could use an `enum { ROCK, PAPER, SCISSORS, MAX_CHOICE } Choice;` then the logic is very much simplified; _eg_ `randNumber =...; compMove =...` would be a simple `compMove = rand() % MAX_CHOICE` and one could use a `switch` statement. – Neil Feb 15 '20 at 19:27

1 Answers1

3

The line:

userMove = getchar();

Catches the char but lets a newline character \n in the buffer caused by pressing Enter, you need to discard it.

You can do, for instance, this:

userMove = getchar();
getchar(); // <-- catches and discards '\n'

I would also get rid of fflush(stdin), it causes undefined behaviour, reasons in Why should I use fflush(stdin) in this program?.

Replace it also with getchar(). Or use type specifier with discard in your scanf function like scanf(" %d%*c", &numMatches); Here is a working sample

Another thing that is not very good is the fact that none these variables is being used:

time_t t; // Allows the program to store system time values. //
int R; // This statement declares the variable for the move "Rock". //
int P; // This statement declares the variable for the move "Paper". //
int S; // This statement declares the variable for the move "Scissors". //
anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • Probably need to swap the order of those two lines of code. Because `scanf` also leaves in a newline. – kaylum Feb 15 '20 at 00:46
  • @kaylum Yes, but then there is a `fflush(stdin);` – anastaciu Feb 15 '20 at 00:47
  • Ah, I missed that. You might be right. But it doesn't correlate with the OP's output where the first `getchar` seems to be reading a newline. `fflush(stdin)` is not defined in the C standard and its behaviour is platform specific. So personally I would not use it. But your answer is pretty much correct anyway. – kaylum Feb 15 '20 at 00:51
  • Yeah, not really a good thing, I should probably mention that too. – anastaciu Feb 15 '20 at 00:52
  • 2
    @kaylum `fflush(stdin)` is not platform-specific, it's explicitly [undefined behavior](https://port70.net/~nsz/c/c11/n1570.html#7.21.5.2p2): "If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; **otherwise, the behavior is undefined.**" Some platforms offer `fflush(stdin)` as a non-portable extension. – Andrew Henle Feb 15 '20 at 00:56
  • @AndrewHenle Yeah what you said is more accurate – kaylum Feb 15 '20 at 00:56
  • Yes, it's undefined behaviour. – anastaciu Feb 15 '20 at 00:57