使用C语言的Mastermind Game问题

时间:2018-01-09 16:59:47

标签: c

我已经尝试了一段时间才能完成这项工作,但我仍然遇到了一些问题...我会很乐意帮忙。

问题就是代码几乎按照我想要的方式工作,我唯一的问题就是当程序告诉你你猜对了多少颜色,如果第一种颜色匹配它的效果很好但是如果其他的位置是正确的程序给出错误的答案(或者至少不是我想要的)。

我刚刚开始编码我知道我的代码远非完美。

这是我的代码:

#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;
}

2 个答案:

答案 0 :(得分:1)

我建议使用另一个阵列来跟踪你在当前游戏中已经看过的计算机钉子:

char seen[SIZE_STRING];

对于每个回合,重置“看到”标志和正确颜色和位置钉的计数,以及正确颜色和错误位置钉的计数:

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

然后用正确的颜色和位置计算用户钉,将它们标记为:

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

然后计算与尚未看到的计算机挂钩颜色相同的用户挂钩,标记匹配的计算机挂钩。这些用户钉都将处于错误的位置,因为正确位置的正确颜色的钉子已经在上面说明:

编辑1:如果多个计算机挂钩与用户挂钩颜色相同,我内部循环的原始版本可以多次计算用户挂钩。我在内部循环中添加了一个break;语句来修复此问题,以便每个用户peg最多可以匹配一个计算机挂钩。

编辑2:外部循环还需要跳过位置匹配循环中匹配的任何用户挂钩,以避免对它们进行两次计数。

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.
        }
    }
}

答案 1 :(得分:0)

我一直在尝试使用您发布的代码,但仍然无法100%正常工作。几乎所有情况下代码都可以正常工作,但有些情况下也会出错。我遇到了白钉的问题,我在一个案例中仍然有一些额外的白钉,例如,如果猜测的代码是RYPG并且我引入RRRR它应该回答1个红旗和1个白旗当它应该只说1红色标志。如果代码是RYPG并且我引入了RRPP,它应该回复2个红旗和2个白旗,它应该只有2个红旗。这是我的代码:

#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;
}