I was trying to make a Rock, Paper, Scissors Game in C.
- Rock beats Scissors.
- Scissors beat Paper.
- 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:
- I will take input of array of string,choices and string array, choice.
- Then I will compare two string character by character.
- Count of variable, ctr will increase if character are same.
- Then I will check whether ctr is equal to length of choice.
- If Yes, Then It will return 1 or else,0.
My Way of Thinking for Game:
- Create 2 String Arrays,comp_choice,choice and array of string array,choices(which will contains the choices available to computer and users.)
- After that I will randomly generate an index value ranging from 0 to 2 which will help in randomly letting computer choose option.
- Then I will check whether User had chosen right option or not by checking whether, choice is in choices or not.
- If not, then it will ask again.
- If yes, then It will check for condition of game and print the status of game.
- 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:
- 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.
- Your
In()
function uses=
instead of==
so it changes the value ofchoice
. 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.
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 commoncont_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();
I also removed all the
fflush()
calls as the behavior is undefined.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;
}