Home > Mobile >  Cannot get my menu code to work with my rock paper scissors code
Cannot get my menu code to work with my rock paper scissors code

Time:12-31

I have two separate sets of code. One of a menu and the other of a rock paper scissors game. Im not sure how to link the two. Im pretty new to C and have been scrawling the internet looking for answers but I keep coming up with nothing. Im not sure what to look for either.

#define _CRT_SECURE_NO_WARNINGS
// C program for the above approach
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <windows.h>
#include <conio.h>




//UDF declaration
int inapp(); //UDF inapp
int exitapp(); //UDF exit app
int exitapp(); //UDF mainmenu

int menu = 0;


int mainmenu(int x) {



    system("cls");
    printf("Welcome to Rock Paper Scissors! \n---------------------\n\nc To continue \nb To exit\n");
    int menumain = _getch();

    while (1) {
        if (menumain == 'c') { //checks if the user is in the app, then makes it so they go to the inapp
            inapp();

        }
        else if (menumain == 'b') { // checks
            exitapp();
        }
        else {
            printf("\nNah. I don't get it.");
            Sleep(1000);
            mainmenu(1);
        }
    }
}

//In app function
int inapp() {



    system("cls");
    printf("Welcome to the menu.\n\n0 to exit \n1 to continue\n2 to return\n");
    //scanf_s("%d", &menuin);
    printf("\nPlease enter your choice\n");
    char menuin = _getch();

    if (menuin == '0') {
        exitapp();
    }
    else if (menuin == '1') {
        ;
    }
    else if (menuin == '2') {
        mainmenu(1);
    }
    else {
        printf("\nNah. I don't get it.");
        Sleep(1000);
        inapp();
    }

}

//Exit app function
int exitapp() {

    system("cls");

    printf("Goodbye, and thank you for your time.\n\n");
    exit(0);
}

// Function to implement the game
int game(char you, char computer)
{
    // If both the user and computer
    // has chose the same thing
    if (you == computer)
        return -1;

    // If user's choice is stone and
    // computer's choice is paper
    if (you == 's' && computer == 'p')
        return 0;

    // If user's choice is paper and
    // computer's choice is stone
    else if (you == 'p' && computer == 's') return 1;

    // If user's choice is stone and
    // computer's choice is scissor
    if (you == 's' && computer == 'z')
        return 1;

    // If user's choice is scissor and
    // computer's choice is stone
    else if (you == 'z' && computer == 's')
        return 0;

    // If user's choice is paper and
    // computer's choice is scissor
    if (you == 'p' && computer == 'z')
        return 0;

    // If user's choice is scissor and
    // computer's choice is paper
    else if (you == 'z' && computer == 'p')
        return 1;
}

// Driver Code
int main()
{

    // Stores the random number
    int n;

    char you, computer, result;

    // Chooses the random number
    // every time
    srand((unsigned int)time(NULL));

    // Make the random number less
    // than 100, divided it by 100
    n = rand() % 100;

    // Using simple probability 100 is
    // roughly divided among stone,
    // paper, and scissor
    if (n < 33)

        // s is notating Stone
        computer = 's';

    else if (n > 33 && n < 66)

        // p is notating Paper
        computer = 'p';

    // z is notating Scissors
    else
        computer = 'z';

    printf("\n\n\n\n\t\t\t\tEnter s for STONE, p for PAPER and z for SCISSOR\n\t\t\t\t\t\t\t");

    // this is the input from the user
    scanf("%c", &you);

    // Function Call to play the game
    result = game(you, computer);

    if (result == -1) {
        printf("\n\n\t\t\t\tGame Draw!\n");
    }
    else if (result == 1) {
        printf("\n\n\t\t\t\tWow! You have won the game!\n");
    }
    else {
        printf("\n\n\t\t\t\tOh! You have lost the game!\n");
    }
    printf("\t\t\t\tYOu choose : %c and Computer choose : %c\n", you, computer);
    
    return 0;
}

I have all the errors gone and the rock paper scissors game works but the menu isnt showing up. I don't know what else to search for or what the issue is.

CodePudding user response:

The entry for your program is main() and it doesn't call either mainmenu() or inapp(). mainmenu() and inapp() seems to be doing the same thing so let's eliminate inapp().

Looking at mainmenu() it seems c is what should invoke our game. To do that we rename main() to rock_paper_scissors() and rename mainmenu(int x) to int main(). We can use a switch instead of the if-else if-else to make it a little cleaner. Also, you don't want to call mainmenu() recursively as stack space is finite. Just loop around instead. In terms of user experience, it's better to just start the game and then ask if user wants to continue.

I don't use windows but getchar() gets a byte from the stdin, but it's line buffered so we have to ignore everything that comes after till we read a newline. I will call that function getchar_and_flush(). You wan to use this instead of scanf() to read the choice from user.

There are other issues with your program. For instance, if n == 33 the computer will elect z which is surprising. Those single letter symbols makes your code hard to read. I suggest you introduce enum symbol { ROCK, PAPER, SCISSORS } and use that instead of s, p, and z. You sometimes call it rock, other times stone (internally inconsistent). The game() function looks weird to me as you sometimes you if and sometimes else if. There a much better trick, namely, a table. Let's first rename the result, using an enum:

enum result {
    LOSS = -1,
    TIE,
    WIN
};
you \ computer rock paper scissors
rock TIE LOSS WIN
paper WIN TIE LOSS
scissor LOSS WIN TIE

which can directly expressed as a 2d array (see game()).

After cleaning up the prompts, and removing windows specific features the code now looks like this:

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

enum result {
    LOSS = -1,
    TIE,
    WIN
};

enum symbol {
    ROCK,
    PAPER,
    SCISSORS,
    INVALID
};

struct {
    enum symbol s;
    char c;
    const char *name;
} map[] = {
    { ROCK, 'r', "rock" },
    { PAPER, 'p', "paper" },
    { SCISSORS, 's', "scissors" },
    { INVALID, '?' }
};

int getchar_and_flush() {
    int c = getchar();
    while(getchar() != '\n');
    return c;
}

const char *name_from_symbol(enum symbol s) {
    for(size_t i = 0; i < sizeof map / sizeof *map; i  )
        if(s == map[i].s)
            return map[i].name;
    return map[INVALID].name;
}

enum symbol symbol_from_char(char c) {
    for(size_t i = 0; i < sizeof map / sizeof *map; i  )
        if(c == map[i].c)
            return map[i].s;
    return INVALID;
}

int game(enum symbol you, enum symbol computer) {
    return (enum result [3][3]) {
        { TIE,  LOSS, WIN },
        { WIN,  TIE,  LOSS },
        { LOSS, WIN,  TIE }
    }[you][computer];
}

void rock_paper_scissor() {
    enum symbol computer;
    srand((unsigned int)time(NULL));
    int n = rand() % 100;
    if (n < 33)
        computer = ROCK;
    else if (n < 66)
        computer = PAPER;
    else
        computer = SCISSORS;
    enum symbol you;
    do {
        printf("Enter r for ROCK, p for PAPER and s for SCISSORS: ");
        you = symbol_from_char(getchar_and_flush());
        if(you == INVALID)
           printf("Invalid input\n");
    } while(you == INVALID);
    switch(game(you, computer)) {
        case LOSS:
            printf("Oh! You have lost the game!\n");
            break;
        case TIE:
            printf("Game Draw!\n");
            break;
        case WIN:
            printf("Wow! You have won the game!\n");
            break;
    }
    printf(
        "You choose : %s and Computer choose : %s\n"
        "\n",
        name_from_symbol(you), name_from_symbol(computer)
    );
}

int main() {
    printf(
        "Welcome to Rock Paper Scissors!\n"
        "-------------------------------\n"
        "\n"
    );
    for(;;) {
        rock_paper_scissor();
        printf("Again (y/n)? ");
        switch(getchar_and_flush()) {
            case 'y':
                printf("\n");
                continue;
                break;
            case 'n':
                printf("Goodbye, and thank you for your time.\n");
                return 0;
            default:
                printf("Nah. I don't get it.\n");
                break;
        }
    }
}

and example session:

Welcome to Rock Paper Scissors!
-------------------------------

Enter r for ROCK, p for PAPER and s for SCISSORS: r
Oh! You have lost the game!
You choose : rock and Computer choose : paper

Again (y/n)? y

Enter r for ROCK, p for PAPER and s for SCISSORS: r
Game Draw!
You choose : rock and Computer choose : rock

Again (y/n)? y

Enter r for ROCK, p for PAPER and s for SCISSORS: s
Wow! You have won the game!
You choose : scissors and Computer choose : paper

Again (y/n)? n
Goodbye, and thank you for your time.

CodePudding user response:

NOT INTENDED AS AN ANSWER (please do not DV)

If your ambition is to become a coder, you have to learn to break apart a problem and produce a good solution. Your version of game() is long and convoluted.

Study the following and see how it serves to compare the two players' selections with only a few lines of code. (This could be further reduced when you learn about modulo arithmetic.)

int game( char you, char computer ) {
    if( you == computer ) return -1;
    if( you == 's' )    return computer == 'z'; // stone/scissors wins
    if( you == 'p' )    return computer == 's'; // paper/stone wins
/*  if( you == 'z' ) */ return computer == 'p'; // scissors/paper wins
}

Notice that else is not necessary. When the if() evaluates true, the execution is already diverted by return;

With less code to read, the answer to your question will not be hidden in too many lines of code and you may be able to solve it for yourself.

EDIT
Following the (customary) excellent answer from @AllanWind and in support of his demonstration of using a look up table to determine the results of a combination, the following shows how one might implement the slightly more complicated decisions of Sheldon Cooper's Variation: "Rock/Paper/Scissors/Lizard/Spock".

In brief, the user makes a selection from the terse menu and a similar random(!) selection is made for the PC. Then evaluate performs a table lookup to determine the winner and the appropriate string to explain the basis of the winning relationship.

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

char *dr = "DRAW\n\n";

char *sp = "scissors cuts paper";
char *pr = "paper covers rock";
char *rl = "rock crushes lizard";
char *ln = "lizard poisons Spock";
char *ns = "Spock smashes scissors";
char *sl = "scissors decapitates lizard";
char *lp = "lizard eats paper";
char *pn = "paper disproves Spock";
char *nr = "Spock vaporizes rock";
char *rs = "rock crushes scissors";

char *tbl[][6] = {
    { dr, pr, rs, rl, nr, " lwwl", },
    { pr, dr, sp, lp, pn, "w llw", },
    { rs, sp, dr, sl, ns, "lw wl", },
    { rl, lp, sl, dr, ln, "lwl w", },
    { nr, pn, ns, ln, dr, "wlwl ", },
};

void evaluate( int usr, int cpu ) {
    char *elems[] = { "rock", "paper", "scissors", "lizard", "nimoy(spock)" };
    printf ( "\nYou: %-14s - PC: %-14s - %s", elems[ usr ], elems[ cpu ], tbl[usr][cpu] );
    if( usr != cpu )
        printf( " - %s\n\n", tbl[usr][5][cpu] == 'w' ? "WIN!!" : "lose..." );
}

void oneRound() {
    char *choices = "rpslnRPSLN";
    char buf[32];

    printf( "choose [r]ock [p]aper [s]cissors [l]izard [n]imoy(Spock): " );
    fgets( buf, sizeof buf, stdin );
    char *cp = strchr( choices, buf[0] );
    if( cp == NULL )
        puts( "bad entry" );
    else
        evaluate( ( cp - choices ) % 5, rand() % 5 );
}

int main() {
    srand( time(NULL) );
    for( ;; )
        oneRound();

    return 0;
}
choose [r]ock [p]aper [s]cissors [l]izard [n]imoy(Spock): n

You: nimoy(spock)   - PC: paper          - paper disproves Spock - lose...

choose [r]ock [p]aper [s]cissors [l]izard [n]imoy(Spock): r

You: rock           - PC: paper          - paper covers rock - lose...

choose [r]ock [p]aper [s]cissors [l]izard [n]imoy(Spock): r

You: rock           - PC: nimoy(spock)   - Spock vaporizes rock - lose...

choose [r]ock [p]aper [s]cissors [l]izard [n]imoy(Spock): l

You: lizard         - PC: rock           - rock crushes lizard - lose...

choose [r]ock [p]aper [s]cissors [l]izard [n]imoy(Spock):

Of note may be the very few lines of code at the heart of this program. "Window dressing" of user interaction can be added to taste.

  • Related