简体   繁体   中英

Issue with Mastermind Game in C language

I've been trying for a while to make this work but I'm still stuck with some issue...I would love some help.

The thing is the code works almost the way I want, the only issue I have is when the program is telling you how many colours you guessed right, if the first colour matches it works good but if the others positions are right the program give a wrong answer (or at least not what I would like).

I'm just starting to code I know my code is really far from being perfect.

Here is my code :

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

#define SIZE_STRING 4
#define SIZE_STRING_BIG 15

void randomSeed(){
srand( (unsigned)time( NULL ) ); 
}

int randomM(int nMin, int nMax){
return nMin + rand()%(nMax-nMin+1);
}


int main(){

randomSeed();

char szUser[SIZE_STRING_BIG];
char szP[6]={'Y','B','W','P','R','G'}, szComputer[SIZE_STRING_BIG] = {szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], '\0'};
int counter=0;
int colour=0;
int position=0; 

printf("\n\n MASTERMIND ");
printf("\n\n We'll play with this colours:");
printf("\n\n Y - Yellow    B - Blue     W - White");
printf("\n P - Purple    R - Red      G - Green");
printf("\n\n You have 8 changes to get t right. \n");   

printf(" Machine choose %s", szComputer); // this line just to check everything works allright

do{
    counter++;
    position=0;
    colour=0;
    printf("\n ===================================================\n");
    printf("\n Chance %d", counter);
    printf("\n\n Please add your 4 colours ");
    printf("\n (Please write the four capital letters without space)  ");       
    scanf("%s",szUser);     

    if(strlen(szUser) != SIZE_STRING)
    {
        printf("\n\n Sorry you choose a wrong option.");
        counter--;
    } else {

            if(strcmp(szUser,szComputer))
            {
                printf("\n Wrong choice. Try again...");                    

                if (szUser[0] == szComputer[0])
                {
                    position++;
                }
                if (szUser[1] == szComputer[1])
                {
                    position++;
                }
                if (szUser[2] == szComputer[2])
                {
                    position++;
                }
                if (szUser[3] == szComputer[3])
                {
                    position++;
                }   

                printf("\n\n You have %d in the right position", position);

                if ( szUser[0] == szComputer[0] || szUser[0] == szComputer[1] || szUser[0] == szComputer[2] || szUser[0] == szComputer[3] )
                {
                    colour++;
                }                   
                if ( szUser[1] == szComputer[1] || szUser[1] == szComputer[2] || szUser[1] == szComputer[3] )
                {
                    colour++;
                }                   
                if ( szUser[2] == szComputer[2] || szUser[2] == szComputer[3] )
                {
                    colour++;
                }                   
                if ( szUser[3] == szComputer[3] )
                {
                    colour++;
                }

                printf("\n You have %d colours right\n", colour);
            }
        }

}while(strcmp(szUser,szComputer) && counter <=7);

if (strcmp(szUser,szComputer))
{
    printf("\n\n Sorry, you run out of chances...");
}   

if(!strcmp(szUser,szComputer))
    printf("\n\n Right choice !\n");

return 0;
}

I suggest using another array to keep track of which of the computer's pegs you've already seen for the current turn of the game:

char seen[SIZE_STRING];

For each turn, reset the "seen" flags and the count of correct colour and position pegs, and the count of correct colour and wrong position pegs:

memset(seen, 0, sizeof(seen));
position = 0;
colour = 0;

Then count user pegs with the correct colour and position, marking them as seen:

for (int i = 0; i < SIZE_STRING; i++)
{
    if (szUser[i] == szComputer[i])
    {
        seen[i] = 1;
        position++;
    }
}

Then count user pegs with the same colour as computer pegs that haven't been seen yet, marking the matching computer pegs as seen. These user pegs will all be at the wrong position because pegs of the correct colour at the correct position have already been accounted for above:

EDIT 1: My original version of the inner loop could count a user peg more than once if several computer pegs had the same colour as the user peg. I have added a break; statement to the inner loop to fix this so that each user peg can match at most one computer peg.

EDIT 2: The outer loop also needs to skip over any user pegs that matched in the position matching loop to avoid counting them twice.

for (int u = 0; u < SIZE_STRING; u++)
{
    // Bug fix (EDIT 2).  Skip user pegs already accounted for by position matching loop ...
    if (szUser[u] == szComputer[u])
    {
        // Already accounted for this user peg.
        continue;
    }
    for (int c = 0; c < SIZE_STRING; c++)
    {
        if (!seen[c] && szUser[u] == szComputer[c])
        {
            colour++;
            seen[c] = 1;
            // Bug fix (EDIT 1) due to comment by @Rup ...
            break; // Skip to next user peg.
        }
    }
}

I've been trying with the code you posted but still doesnt work 100% properly. The code works allright almost all cases but still some cases get it wrong. I'm having trouble with the white pegs, im still having some extra white pegs in one case, for example if the code to guess is RYPG and i introduce RRRR it answer back 1 red flag and 1 white flag when it should say just 1 red flag. and if the code is RYPG and i introduce RRPP it answer back 2 red flags and 2 white flags when it should be just 2 red flags. Here is my code:

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

#define SIZE_STRING 4
#define SIZE_STRING_LONG 15

void randomSeed(){
    srand( (unsigned)time( NULL ) ); 
}

int randomM(int nMin, int nMax){
    return nMin + rand()%(nMax-nMin+1);
}


int main(){

randomSeed();

char szUser[SIZE_STRING_LONG];
char szP[6]={'Y','B','W','P','R','G'}, szComputer[SIZE_STRING_LONG] = {szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], szP[randomM(0,5)], '\0'};
int counter=0;
int colour=0;
int position=0; 
char alreadyChecked[SIZE_STRING];


printf("\n\n MASTERMIND ");
printf("\n\n We'll play with this colours:");
printf("\n\n Y - Yellow    B - Blue     W - White");
printf("\n P - Purple    R - Red      G - Green");
printf("\n\n You have 8 changes to get t right. \n");           
printf("\n\n White flags indicate right colour in right position");
printf("\n\n Red flags indicate right colour in wrong position");

printf("\n\n Computer choses %s", szComputer); //check if the program works allright

do{
    counter++;
    position=0;
    colour=0;
    memset(alreadyChecked, 0, sizeof(alreadyChecked));
    printf("\n ===================================================\n");
    printf("\n Chance %d", counter);
    printf("\n\n Please enter your 4 colours choice");
    printf("\n (Please write capital letters without space  ");         
    scanf("%s",szUser);     

    if(strlen(szUser) != SIZE_STRING)
    {
        printf("\n\n Sorry you choose a wrong option.");
        counter--;
    } else {

            if(strcmp(szUser,szComputer))
            {
                printf("\n Wrong choice. Try again...");                    

                for (int u = 0; u < SIZE_STRING; u++)
                {
                    if (szUser[u] == szComputer[u])
                    {
                        position++;                             
                    }
                }

                if (position > 0 && position < 2)
                {
                    printf("\n\n You have %d red flag", position);
                }

                if (position > 1 )
                {
                    printf("\n\n You have %d red flags", position);
                }

                for (int u = 0; u < SIZE_STRING; u++)
                {

                    if (szUser[u] == szComputer[u])
                    {        
                        continue;
                    }

                        for (int c = 0; c < SIZE_STRING; c++)
                        {
                            if (!alreadyChecked[c] && szUser[u] == szComputer[c])
                            {
                                colour++;
                                alreadyChecked[c] = 1;

                                break; 
                            }
                        }
                }       



                if (colour > 0 && colour < 2)
                {
                    printf("\n\n You have %d white flag", colour);
                }

                if (colour > 1 )
                {
                    printf("\n\n You have %d white flags", colour);
                }

                if (colour == 0 && position == 0)
                {
                    printf("\n\n 0 white flags and 0 red flags");
                }
            }
        }

}while(strcmp(szUser,szComputer) && counter <=7);

if (strcmp(szUser,szComputer))
{
    printf("\n\n Sorry, you run out of chances...");
}   

if(!strcmp(szUser,szComputer))
    printf("\n\n Right combination !\n");

return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM