Home > Software engineering >  C Project Query
C Project Query

Time:07-26

I was trying to make a Rock, Paper, Scissors Game in C.

  1. Rock beats Scissors.
  2. Scissors beat Paper.
  3. Paper beats Rock.

My code is:

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

/**
 * @brief Checks whether choice is in arr or not
 * 
 * @param arr 
 * @param choice 
 * @return int 
 */
int In(char (*arr)[10], char *choice){
    int len = strlen(choice);
    int ctr = 0;
    while(*choice!='\0'){
        if(*choice = *(*arr)){
           ctr  ; 
        }
        choice  ;
        arr  ;
    }
    if(ctr==len){
        return 1;
    }
    return 0;
}
/**
 * @brief Ask for playing forward
 * 
 * @return int 
 */
int play_fwd(){
    int fwd;
    fflush(stdin);
    printf("Would You Like to play further?(0 for No/ 1 for Yes): ");
    scanf("%d",&fwd);
    return fwd;
}

int main(){
    char choice[10],choices[3][10],comp_choice[10];
    int cont_fwd = 1;
    strcpy(choices[0],"Rock");
    strcpy(choices[1],"Paper");
    strcpy(choices[2],"Scissor");
    
    printf("!!!Welcome!!!\n");

    srand(time(NULL));
    int index = rand()%3;
    strcpy(comp_choice,choices[index]);

    do{
        fflush(stdin);
        printf("Enter Your Choice: ");
        gets(choice);
        if(In(choices,choice)==0){
            printf("Wrong Input");
            continue;
        }
        
        if(strcmp(choice,"Rock")&&strcmp(comp_choice,"Paper")){
            printf("Lose\n");
            cont_fwd = play_fwd();
        }
        else if(strcmp(choice,"Rock")&&strcmp(comp_choice,"Scissor")){
            printf("Win\n");
            cont_fwd = play_fwd();
        }
        else if(strcmp(choice,"Scissor")&&strcmp(comp_choice,"Paper")){
            printf("Win\n");
            cont_fwd = play_fwd();
        }
        else if(strcmp(choice,"Scissor")&&strcmp(comp_choice,"Rock")){
            printf("Lose\n");
            cont_fwd = play_fwd();
        }
        else if(strcmp(choice,"Paper")&&strcmp(comp_choice,"Rock")){
            printf("Win\n");
            cont_fwd = play_fwd();
        }
        else if(strcmp(choice,"Paper")&&strcmp(comp_choice,"Scissor")){
            printf("Lose\n");
            cont_fwd = play_fwd();
        }
        else{
            printf("Draw\n");
            cont_fwd = play_fwd();
        }
    }while(cont_fwd==1);
    return 0;
}

I am not getting my desired outcome.

IN Function, I guess, isn't working. Since It doesn't print "Wrong Output" as output even if I deliberately put wrong input for choice.

My Way of Thinking for the IN Function:

  1. I will take input of array of string,choices and string array, choice.
  2. Then I will compare two string character by character.
  3. Count of variable, ctr will increase if character are same.
  4. Then I will check whether ctr is equal to length of choice.
  5. If Yes, Then It will return 1 or else,0.

My Way of Thinking for Game:

  1. Create 2 String Arrays,comp_choice,choice and array of string array,choices(which will contains the choices available to computer and users.)
  2. After that I will randomly generate an index value ranging from 0 to 2 which will help in randomly letting computer choose option.
  3. Then I will check whether User had chosen right option or not by checking whether, choice is in choices or not.
  4. If not, then it will ask again.
  5. If yes, then It will check for condition of game and print the status of game.
  6. It will also ask for whether user wants to play further or not.

I am not able to understand why my IN function isn't working? Any Idea??

Edit: Thanks to @Barmar. My Code had started working. I changed the definition of IN Function in my code.

int In(char (*arr)[10], char *choice,int len){
    for(int i=0;i<len;i  ){
        if(strcmp(*(arr i),choice)==0){
            return 1;
        }
    }
    return 0;
}

After this, It started working.

CodePudding user response:

  1. You have to strip the newline from choice. Easiest option is probably:
- gets(choice);
  scanf("%9s", choice);

As noted, never use gets() as it cannot be used safely.

  1. Your In() function uses = instead of == so it changes the value of choice. Here is a more straight forward implementation:
int In(int n, char (*arr)[10], char *choice){       
          for(int i = 0; i < n; i  ) {
                  if(!strcmp(arr[i], choice))         
                          return 1;
          }                 
          return 0;                                
}                                                     

Make sure you update caller to pass in number of options.

  1. strcmp() returns 0 when two strings are the same so you want to negate all those tests. Also did a minor refactoring by moving the common cont_fwd = play_fwd(); line to after the conditions:
        if(
            !strcmp(choice,"Rock") &&
            !strcmp(comp_choice,"Paper")
        ) {
            printf("Lose\n");
        } else if(
            !strcmp(choice,"Rock") &&
            !strcmp(comp_choice,"Scissor")
        ) {
            printf("Win\n");
        } else if(
            !strcmp(choice,"Scissor") &&
            !strcmp(comp_choice,"Paper")
        ) {
            printf("Win\n");
        } else if(
            !strcmp(choice,"Scissor") &&
            !strcmp(comp_choice,"Rock")
        ) {
            printf("Lose\n");
        } else if(
            !strcmp(choice,"Paper") &&
            !strcmp(comp_choice,"Rock")
        ) {
            printf("Win\n");
        } else if(
            !strcmp(choice,"Paper") &&
            !strcmp(comp_choice,"Scissor")
        ) {
            printf("Lose\n");
        } else {
            printf("Draw\n");
        }
        cont_fwd = play_fwd();
  1. I also removed all the fflush() calls as the behavior is undefined.

  2. The program now seems to work for me, however, you may want to update comp_choice within the loop so each play uses a new value.

The next step would be to encode the game logic in a table along these lines and write a function to lookup the the result. If you convert your choice to a symbol (say by converting the text to an enum symbol { ROCK, PAPER, SCISSOR }; then it would just an 2d array lookup instead of all those if statements.

choice vs comp_choice Rock Paper Scissor
Rock Draw Lose Win
Paper Win Draw Lose
Scissor Lose Win Draw

I made this change so you can see how compact it becomes:

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

enum symbol {
    INVALID = -1,
    ROCK,
    PAPER,
    SCISSOR,
    SYMBOLS // count of valid symbols
};

enum symbol str_to_sym(const char *s) {
    if(!strcmp(s, "Rock")) return ROCK;
    if(!strcmp(s, "Paper")) return PAPER;
    if(!strcmp(s, "Scissor")) return SCISSOR;
    return INVALID;
}

const char *rules[3][3] = {
    (const char *[]) { "Draw", "Lose", "Win" },
    (const char *[]) { "Win", "Draw", "Lose" },
    (const char *[]) { "Lose", "Win", "Draw" }
};

int play_fwd() {
    int fwd;
    printf("Would You Like to play further?(0 for No/ 1 for Yes): ");
    scanf("%d", &fwd);
    return fwd;
}

int main() {
    printf("!!!Welcome!!!\n");
    srand(time(NULL));
    for(;;) {
        enum symbol comp_choice = rand() % SYMBOLS;
        printf("Enter Your Choice (Rock, Paper or Scissor): ");
        char str[10];
        scanf("%9s", str);
        enum symbol choice = str_to_sym(str);
        if(choice == INVALID) {
            printf("Wrong Input");
            continue;
        }
        printf("%s\n", rules[choice][comp_choice]);
        if(!play_fwd())
            break;
    }
    return 0;
}
  •  Tags:  
  • c
  • Related