Click here to Skip to main content
15,889,482 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more:
Hello everyone! I have a small problem in C.
My whole code is below: (It is the game known as rock-scissor-pencil-paper)
Code:

What I have tried:

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

char* CPU_random_choice(char **cpu_array);
int player_input();
int check_hand_in_array(char **array , char *input);
int increase_score(int *score);
void result(int *for_CPU , int *for_player);
void win(char **array , char *player_hand , char *cpu_hand , int *CPU_score , int *player_score);

int main(void)
{
    int CPU_score = 0;
    int player_score = 0;
    char *Hands[4] = {"Rock" , "Scissor" , "Pencil" , "Paper"};
    result(&CPU_score , &player_score);

    char *cpu_choice = CPU_random_choice(Hands);
    printf("\nCPU hand: %s\n\n" , cpu_choice);
    int player_hand = player_input();
    printf("\nPlayer hand: %s\n" , Hands[player_hand - 1]);
    win(Hands , Hands[player_hand - 1] , cpu_choice , &CPU_score , &player_score);
    printf("\n\n");
    result(&CPU_score , &player_score);
}

char* CPU_random_choice(char **cpu_array)
{
    srand(time(NULL));
    int i = rand() % 4;
    return cpu_array[i];
}

int player_input()
{
    printf("1:  Rock\n2:  Scissor\n3:  Pencil\n4:  Paper\n");
    printf("Player give a hand: ");
    int player_hand;
    scanf("%d" , &player_hand);

    do
    {
        if(player_hand < 0 && player_hand > 4)
        {
            printf("Invalid hand...\nTry again: ");
            scanf("%d" , &player_hand);
        }
    }

    while(player_hand < 0 && player_hand > 4);

    return player_hand;
}

void result(int *for_CPU , int *for_player)
{
    printf("PLAYER  -  CPU\n==============\n");
    printf("   %d\t    %d\n" , *for_CPU , *for_player);
}

int increase_score(int *score)
{
    return (*score)++;
}

void win(char **array , char *player_hand , char *cpu_hand , int *CPU_score , int *player_score)
{
    if((strcmp(player_hand , CPU_random_choice(array))) == 0)
    {
        printf("Draw!");
    }
    else if(strcmp(player_hand , "Rock") == 0 && (strcmp(CPU_random_choice(array) , "Scissor") || strcmp(CPU_random_choice(array) , "Pencil")) == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Rock") == 0 && (strcmp(player_hand , "Scissor") || strcmp(player_hand , "Pencil")) == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
    else if(strcmp(player_hand , "Rock") == 0 && strcmp(CPU_random_choice(array) , "Paper") == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Rock") == 0 && strcmp(player_hand , "Paper") == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(player_hand , "Scissor") == 0 && strcmp(CPU_random_choice(array) , "Rock") == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Scissor") == 0 && strcmp(player_hand , "Rock") == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(player_hand , "Scissor") == 0 && (strcmp(CPU_random_choice(array) , "Pencil") || strcmp(CPU_random_choice(array) , "Paper")) == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Scissor") == 0 && (strcmp(player_hand , "Pencil") || strcmp(player_hand , "Paper")) == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
    else if(strcmp(player_hand , "Pencil") == 0 && (strcmp(CPU_random_choice(array) , "Rock") || strcmp(CPU_random_choice(array) , "Scissor")) == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Pencil") == 0 && (strcmp(player_hand , "Rock") || strcmp(player_hand , "Scissor")) == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(player_hand , "Paper") == 0 && (strcmp(CPU_random_choice(array) , "Pencil") || strcmp(CPU_random_choice(array) , "Scissor")) == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Paper") == 0 && (strcmp(player_hand , "Pencil") || strcmp(player_hand , "Scissor")) == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(player_hand , "Paper") == 0 && strcmp(CPU_random_choice(array) , "Rock") == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Paper") == 0 && strcmp(player_hand , "Rock") == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
    else if(strcmp(player_hand , "Pencil") == 0 && strcmp(CPU_random_choice(array) , "Paper") == 0)
    {
        printf("Player wins!");
        increase_score(player_score);
    }
    else if(strcmp(CPU_random_choice(array) , "Pencil") == 0 && strcmp(player_hand , "Paper") == 0)
    {
        printf("CPU wins!");
        increase_score(CPU_score);
    }
}

I fixed a previous problem I had with another way,but now my problem is that program doesn't return the correct solution(winner) and doesn't increase the the score of the winner(sometimes it does ,sometimes increase the score of loser,sometimes does nothing).I do not know what is going on...
I need your help...
Thanks!!!
Posted
Updated 3-Aug-20 6:53am
v6
Comments
KarstenK 3-Aug-20 2:19am    
OriginalGriff is right. Always remember: the compiler is the only friend in coding which tells you: "dont do that because you'll get trouble" ;-)
Richard MacCutchan 3-Aug-20 3:52am    
The code you have posted does not match the error message you have shown.
Nick_is_asking 3-Aug-20 5:08am    
I just uploaded the whole code.Take a look. Thanks!!
Richard MacCutchan 3-Aug-20 11:02am    
It is time for you to do some debugging and learn how to solve problems for yourself. Set a breakpoint in your code, start the debugger and step through it, inspecting the different variables at each statement. You will learn far more this way then just taking our solutions.
Richard MacCutchan 3-Aug-20 11:04am    
if(player_hand < 0 && player_hand > 4)

An integer value cannot be less than zero and greater than 4 at the same time.

No, no - bad idea!
Whey you declare an array (or any other variable) inside a function, it is created on the stack (a form of memory that holds local variables and function return addresses) and that memory is released and recycled when you exit the function. So trying to pass that memory to the world outside the function has a special name: hanging reference. And it's a very bad idea, because the next function you call will use exactly the same memory for very different purposes and will corrupt the array - or you will change the array and corrupt memory being used for other things. And then all bets are off: your code develops strange bugs, or crashes for "no reason".
And it is really, really difficult to spot those problems when they occur, because it's usually a long time after you wrote - and tested - the code that caused it!

So don't do it. Ever.

If you need to return new memory from a function, then you need to use malloc[^] to allocate it on the heap (a different form of memory in your program) - and remember to use free[^] to release the memory when you are finished with it, or your app will start to "leak" memory, and that's bad too!

As to the problem you have spotted - no idea. We don't have access to the code your function is calling, so we have no idea what the parameters should be.
 
Share this answer
 
Comments
Nick_is_asking 3-Aug-20 5:51am    
I just uploaded the whole code.Take a look. Thanks!!
OriginalGriff 3-Aug-20 6:01am    
And now it's even worse: it will crash a whole lot sooner *because you don't allocate any memory to player_hand*

char *player_hand;
do
{
scanf("%s" , player_hand);

Where is it supposed to put the user input? Read what I said, especially the bits about malloc and free ...
Nick_is_asking 3-Aug-20 6:21am    
I understand that when I build a function ,its variables are saved to a special part of memory (such as main or another function),but I don't understand how to fix this problem now...
I followed your link (malloc/free) ,but it doesn't work(I'm definitely doing something wrong,I know...).
What should I do?
Can you help me?
Thanks again!!!
OriginalGriff 3-Aug-20 6:59am    
How would I know what is wrong with code I can't see? :laugh:

And "It doesn't work" is probably the most useless problem report we get - and we get it a lot. It tells us nothing about what is happening, or when it happens.
So tell us what it is doing that you didn't expect, or not doing that you did.
Tell us what you did to get it to happen.
Tell us any error messages.
Nick_is_asking 3-Aug-20 7:14am    
Well,I want to return a string character from player_input() function.
What should I fix?
Quote:
I want an explanation of my fault...

Never do this !
Never return a local variable or pointer, because the return itself kills all local variables.
A function can return the value of a local variable, but not an array or a pointer to local variable, because the return kills all local variables.
 
Share this answer
 
C++
char* player_input(char **array)
{
    //printf("\n");
    printf("Player give a hand: ");
    char *player_hand; 
    do
    {
        scanf("%s" , player_hand);

        if(check_hand_in_array(array , player_hand) == 0)
        {
            printf("Invalid hand...\nTry again: ");
        }
    }

    while(check_hand_in_array(array , player_hand) == 0);

    return *player_hand;
}

Your function is declared to return a char* but your return statement tries to return a single character. You declare the pointer player_hand but it does not point to anything so the scanf will crash. You are also calling check_hand_in_array twice when you only need it once.

You need something like:
C++
char* player_input(char **array)
{
    //printf("\n");
    printf("Player give a hand: ");
    char *player_hand = (char*)malloc(256); // get some space
    int handOK = 0;
    do
    {
        scanf("%s", player_hand);
        handOK = check_hand_in_array(array , player_hand);
        if (handOK == 0)
        {
            printf("Invalid hand...\nTry again: ");
        }
    }
    while(handOK == 0);

    return player_hand; // return the allocated hand buffer
}
 
Share this answer
 
Comments
Member 12556999 3-Aug-20 13:47pm    
make sure you free the malloc data or you will have a memory leak
Richard MacCutchan 3-Aug-20 15:24pm    
You cannot free it in this function as it is being passed back to the caller.
Your
C++
CPU_random_choice()
function everytime creates a new random value, so you havent a clear code flow.

I would create for all these values some global constant sstring.
C++
 char *Hands[4] = {"Rock" , "Scissor" , "Pencil" , "Paper"};
// to
const char *HAD_ROCK = "Rock"; // and so on
So you are out of the problem of local values.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900