【问题标题】:How to count the "white" correctly in mastermind guessing game in c?如何在c中的策划者猜谜游戏中正确计算“白色”?
【发布时间】:2010-01-05 11:34:52
【问题描述】:

“白”是在错误的位置检查正确的数字。 但我不知道如何正确计算。

#include "stdafx.h"
#include "stdlib.h" 
#include "time.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int answer[4];
    int guess[4];
    int count = 0;

    srand(time(NULL)); 
    /*answer[0] = (rand() % 6)+1;
    answer[1] = (rand() % 6)+1;
    answer[2] = (rand() % 6)+1;
    answer[3] = (rand() % 6)+1;*/

    answer[0] = 3;
    answer[1] = 3;
    answer[2] = 5;
    answer[3] = 2;

    printf("%d %d %d %d\n", answer[0],  answer[1],  answer[2],  answer[3]);
    printf("          B W\n"); 

    do
    {
        int black = 0;
        int white = 0;
        count++;
        printf("Enter 4 numbers, this is your %d guess: ", count);
        scanf("%d %d %d %d", &guess[0], &guess[1], &guess[2], &guess[3]);
        printf("\n%d %d %d %d\n", guess[0], guess[1], guess[2], guess[3]);

        int g2[2][6];

        for (int a = 0;a < 4;a++)
            g2[0][a]=answer[a];

        for (int i = 0;i < 4;i++)
            g2[1][i]=guess[i];

        if (answer[0]==guess[0])
            black++;
        if (answer[1]==guess[1])
            black++;
        if (answer[2]==guess[2])
            black++;
        if (answer[3]==guess[3])
            black++;

        if (answer[1]==guess[0] || answer[2]==guess[0] || answer[3]==guess[0])
            white++;
        if (answer[0]==guess[1] || answer[2]==guess[1] || answer[3]==guess[1])
            white++;
        if (answer[0]==guess[2] || answer[1]==guess[2] || answer[3]==guess[2])
            white++;
        if (answer[0]==guess[3] || answer[1]==guess[3] || answer[2]==guess[3])
            white++;

        if (black==4)
            white=0;

        g2[1][4]=black;
        g2[1][5]=white;

        for (int n = 0;n < 6;n++)
            printf(" %d",g2[1][n]); 

        printf("\n");
    }
    while (answer[0]!=guess[0] || answer[1]!=guess[1] ||
           answer[2]!=guess[2] || answer[3]!=guess[3]);

    printf("BINGO!!!\n");

    return 0;
}

更新 2:

for (int slot=0;slot<4;slot++)
{
    if (guess[slot] == answer[slot]) 
        black++;
    else 
        for (int s=0;s<4;s++)
            if (s != slot) 
            {
                if (guess[slot] == answer[s]) 
                    white++;
                break;
            }
}

更新 3:

for (int x=0;x<4;x++)
flag[x]=0;

for (int slot = 0;slot < 4;slot++) 
{ 
    if (guess[slot] == answer[slot])  
        if (flag[slot]==1)
            black++; 
    else  
        for (int s=0;s < 4;s++) 
            if (s != slot)  
            { 
                if (guess[slot] == answer[s])
                    if (flag[s]==1)
                    {
                        white++; 
                        break; 
                    }
            } 
} 

更新 4

for (int x=0;x<4;x++)
flag[x]=0;

for (int slot = 0;slot < 4;slot++) 
{ 
    if (guess[slot] == answer[slot])  {
        black++; 
        flag[slot]=1;
    }
else  
    for (int s=0;s < 4;s++)
        if (s != slot)
        { 
            if (guess[slot] == answer[s])  
            {
                white++; 
                flag[s]=1;
                break; 
            }
        } 
} 

更新 5:

#include "stdafx.h"
#include "stdlib.h" 
#include "time.h"

int _tmain(int argc, _TCHAR* argv[])
{
    int answer[4];
    int guess[4];
    int flag[4];
    int count = 0;

    srand(time(NULL)); 
    /*answer[0] = (rand() % 6)+1;
    answer[1] = (rand() % 6)+1;
    answer[2] = (rand() % 6)+1;
    answer[3] = (rand() % 6)+1;*/

    answer[0] = 1;
    answer[1] = 2;
    answer[2] = 3;
    answer[3] = 4;

    printf("%d %d %d %d\n", answer[0],  answer[1],  answer[2],  answer[3]); 

    do
    {
        int black = 0;
        int white = 0;
        count++;
        printf("Enter 4 numbers, this is your %d guess: ", count);
        scanf("%d %d %d %d", &guess[0], &guess[1], &guess[2], &guess[3]);

        int g2[2][6];

        for (int a = 0;a < 4;a++)
            g2[0][a]=answer[a];

        for (int i = 0;i < 4;i++)
            g2[1][i]=guess[i];

        for (int x=0;x<4;x++)
            flag[x]=0;

        for (int slot = 0;slot < 4;slot++) 
        { 
            if (guess[slot] == answer[slot])  
                black++; 
            else   
                for (int s=0;s < 4;s++)  
                    if (s != slot && guess[slot] == answer[s] && !flag[s]) 
                    {  
                        white++;  
                        flag[s]=1; 
                        break;  
                    }
        } 

        g2[1][4]=black;
        g2[1][5]=white;

        printf("Guess %d: ", count);

        for (int n = 0;n < 4;n++){
            printf(" %d",g2[1][n]);
        }

        printf(" Black: %d White: %d\n", g2[1][4], g2[1][5]);
        printf("\n");
    }
    while (answer[0]!=guess[0] || answer[1]!=guess[1] ||
           answer[2]!=guess[2] || answer[3]!=guess[3]);

    printf("BINGO!!!\n");

    return 0;
}

【问题讨论】:

    标签: c arrays


    【解决方案1】:

    Knuth 在The Computer as Master Mind 中回答了这个问题,并承认很难准确定义它。他建议这样做:

    1. 通过将答案中的每个位置与当前猜测中的相同位置进行比较来计算黑色的数量。
    2. 如下计算白人加黑人的数量。
    3. 从 (2) 中减去 (1) 得到白人的数量。

    计算白人加黑人:

    1. 制作两个数组,ansguess,每个颜色对应一个槽。
    2. 对于每种颜色,在ans 中填入答案中该颜色的钉数。同样,在guess 中填充当前猜测中该颜色的钉子数。
    3. 为每个i 加起来min(ans[i], guess[i])。这是白人加黑人。

    【讨论】:

    • #4 是未命中数,而不是白人数。
    • @Spookbuster - 谢谢,已修复。
    • 我无法描述这个答案的想法/书面和帮助程度。帮了我很多
    【解决方案2】:

    建议的替代方案(伪代码):

    white = 0;
    black = 0;
    for slot=0 to 3
      if guess[slot] == answer[slot]
        black++
      else
        for s=0 to 3
          if s != slot
            if guess[slot] == answer[s]
              white++
              break
    

    更新(详细)

     else  
        for (int s=0;s < 4;s++) 
          if (s != slot && guess[slot] == answer[s] && !flag[s])
          { 
              white++; 
              flag[s]=1;
               break; 
          }
    

    我认为应该这样做:我们正在检查另一个不是当前位置的位置,一个不是完美(黑色)匹配的位置,并且以前没有用于标记黑色或白色。

    【讨论】:

    • 已在上面更新,但在某些情况下仍然是错误的,例如“3115”。 :(
    • 请说得更具体一点:请问答案、猜测和结果是什么?
    • 答案是“3352”。如果我猜“3115”,结果应该是 1 Black 和 1 White。如果我猜“0033”,结果应该是 0 Black 和 2 White。
    • 您的更新 2 缺少用于最内层 if 的花括号,因此它只会检查每个挂钩的一个插槽。
    • 喜欢这个?还是不行:( if (guess[slot] == answer[s]) white++; { break; }
    【解决方案3】:

    试试这个:

        for (int x=0;x<4;x++)
            flag[x]=guess[x]==answer[x]?1:0;
    
        for (int slot = 0;slot < 4;slot++) 
        { 
            if (guess[slot] == answer[slot])  
                black++; 
            else   
                for (int s=0;s < 4;s++)  
                    if (!flag[s] && guess[slot] == answer[s]) 
                    {  
                        white++;  
                        flag[s]=1; 
                        break;  
                    }
        } 
    

    【讨论】:

      【解决方案4】:

      评论指出 Knuth 提供了一个 4 步算法来确定 步骤 4 中白色和黑色钉子的数量不正确。

      第 4 步只返回 4 - 第 3 步中返回的数字。第 4 步返回“未命中”的数量,即不是黑色或白色钉子。

      只需使用步骤 3 即可计算出白人和背面的总数;使用简单的方法计算黑色钉子的数量

      for i = 0 to 3:
         if(a[i] == g[i]) b = b + 1 
      

      那么当然是白人 = 第 3 步 - 黑色钉子的数量 (b)。

      【讨论】:

      • 提示:在用于构建第 3 步频率表的同一循环中计算黑人。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多