C 策划双白色钉问题

C++ Mastermind Double White Peg Issue

本文关键字:问题 白色      更新时间:2023-10-16

我是C 的新手,并且在分配方面遇到麻烦。我无法弄清我对被计数的双白色钉子遇到的问题。有人可以帮忙吗?我可以理解我有双重计数问题,因为我只使用"或"陈述,但除此之外,我相信我需要从白色钉中减去黑钉,但我不知道该怎么做。

#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main() {
    char colors[4];
    srand(time(0));
    int randomint = (rand() % 5) + 1;
    for (int i = 0;i<4;i++) {
        randomint = (rand() % 5) + 1;
        switch (randomint) {
        case 1:
            colors[i] = 'R';
            break;
        case 2:
            colors[i] = 'B';
            break;
        case 3:
            colors[i] = 'Y';
            break;
        case 4:
            colors[i] = 'P';
            break;
        case 5:
            colors[i] = 'G';
            break;
        case 6:
            colors[i] = 'Bl';
            break;
        case 7:
            colors[i] = 'R';
            break;
        case 8:
            colors[i] = 'O';
            break;
        case 9:
            colors[i] = 'T';
            break;
        }
    }

    char usercolors[4];
    cout << "We have our colors!" << endl;
    cout << endl << endl;
    int turncounter = 0;
    while (turncounter != 12) {
        turncounter++;
        cout << "Current try: " << turncounter << endl;
        for (int i = 0;i<4;i++) {
            cout << "Color " << i << ": ";
            cin >> usercolors[i];
            cout << endl;
        }
        for (int i = 0;i<4;i++) {
            if (usercolors[i] == colors[i])
                cout << "Black Peg" << " ";
        }
        if (usercolors[0] == colors[1] ||
            usercolors[0] == colors[2] ||
            usercolors[0] == colors[3]) {
            cout << "White Peg" << " ";
        }
        if (usercolors[1] == colors[0] ||
            usercolors[1] == colors[2] ||
            usercolors[1] == colors[3]) {
            cout << "White Peg" << " ";
        }
        if (usercolors[2] == colors[0] ||
            usercolors[2] == colors[1] ||
            usercolors[2] == colors[3]) {
            cout << "White Peg" << " ";
        }
        if (usercolors[3] == colors[0] ||
            usercolors[3] == colors[1] ||
            usercolors[3] == colors[2])
        {
            cout << "White Peg" << " ";
        }
        cout << endl << endl;
        if (usercolors[0] == colors[0] &&
            usercolors[1] == colors[1] &&
            usercolors[2] == colors[2] &&
            usercolors[3] == colors[3])
        {
            cout << "You win! Number of tries: " << turncounter << endl;
            turncounter = 12;
        }
        else {
            cout << "Try Again!" << endl << endl;
        }
    }
    if (turncounter == 12) {
        cout << "Sorry, you are incorrect!" << endl;
        cout << "Answer: ";
        cout << "Color 1: " << colors[0] << "t" << "Color 2: " << colors[1] << "t" << "Color 3: " << colors[2] << "t" << "Color 4: " << colors[3] << "t" << endl;
    }
    cin.get();
    cin.get();
    return 0;
}

计算白色钉时,您必须忽略检测到黑色钉子的所有位置。因此,在检测到黑钉后,您正在尝试通过:

来检测白色钉。
if (usercolors[0] == colors[1] ||
    usercolors[0] == colors[2] ||
    usercolors[0] == colors[3]) {
    cout << "White Peg" << " ";
}

您已经注意到,这种方法将导致双重计数。一个示例:秘密图案在第一个位置包含绿色钉。现在,您输入猜测:第一个位置上的绿色和第四个位置绿色。您的代码将在第一个位置检测到一个黑色钉,并且(至少)另外两个白色钉,这不是应该工作的方式。在计算白色钉时,必须忽略黑色钉子的位置,并且都已经检测到白钉。

因此,您必须修改代码。可以通过将检测到的黑色钉位置写入地图(称为match_map),并在第一个白色钉匹配(也必须写入您的列表)后离开内部环,可以避免双白色钉数。请注意,您的颜色列表两次" R"。给出" bt"作为char无法正常工作,我用" b"代替了它。您可以通过使用一系列颜色来无需switch(),然后一个循环就足以处理秘密模式。

避免使用命名空间std; - 在这里查找解释 - 因为它被认为是不良的pratice并可能导致进一步的问题。

#include <iostream>
#include <cstdlib>
#include <ctime>
enum {
    PEG_NO_MATCH,
    PEG_BLACK,
    PEG_WHITE,
};
int main() {
    char colors[4], usercolors[4], match_map[4];
    const char rand_colors[8] = { 'R', 'B', 'Y', 'P', 'G', 'b', 'O', 'T' };    // B -> Black, b -> Blue
    int turncounter = 0, black_cnt, white_cnt;
    std::srand(time(0));
    for (int i = 0; i < 4; i++) colors[i] = rand_colors[std::rand() % 8];
    std::cout << "We have our colors!" << std::endl << std::endl << std::endl;
    while (turncounter != 12) {
        turncounter++;
        std::cout << "Current try: " << turncounter << std::endl;
        black_cnt = 0;
        white_cnt = 0;
        // Get input and count black pegs
        for (int i = 0; i < 4; i++) {
            std::cout << "Color " << i << ": ";
            std::cin >> usercolors[i];
            std::cout << std::endl;
            if (usercolors[i] == colors[i]){
                black_cnt++;
                match_map[i] = PEG_BLACK;
            }else{
                match_map[i] = PEG_NO_MATCH;
            }
        }
        // Count white pegs
        for (int i = 0; i < 4; i++) {
            if (match_map[i] != PEG_BLACK){
                for (int k = 0; k < 4; k++) {
                    if ((i != k) && (match_map[k] == PEG_NO_MATCH) && (usercolors[i] == colors[k])){
                        match_map[k] = PEG_WHITE;
                        white_cnt++;
                        break;
                    }
                }
            }
        }
        std::cout << std::endl << std::endl;
        // Display result
        std::cout << "Black Pegs : " << black_cnt << std::endl;
        std::cout << "White Pegs : " << white_cnt << std::endl;
        // Do all pegs match?
        if (black_cnt == 4)
        {
            std::cout << "You win! Number of tries: " << turncounter << std::endl;
            break;
        }
        else {
            std::cout << "Try Again!" << std::endl << std::endl;
        }
    }
    if (turncounter == 12) {
        std::cout << "Sorry, you are incorrect!" << std::endl;
        std::cout << "Answer: " << "Color 1: " << colors[0] << "t" << "Color 2: " << colors[1] << "t" << "Color 3: " << colors[2] << "t" << "Color 4: " << colors[3] << "t" << std::endl;
    }
    // Wait for input
    std::cin.get();
    std::cin.get();
    return 0;
}