Сравнение числа по одной цифре c++

Делаю всем известную игрушку "Угадай число". Единственный момент, она должна после каждого предположения писать сколько чисел угадано и сколько на своих местах(число трехзначное, к примеру) Не получается правильно сделать функцию, которая сравнивает каждую введенную цифру в числе с сгенерированными. Проблема в функции ugadal(). Код целиком: (да, знаю, что переменные так лучше не называть, просто для понимания =) )

constexpr auto RANGE = 3;
int x;
int vveli[5];
int comp[5];
int computer();
int comp_num = computer();
int count(int x, int vveli[5], int RANGE);
int place(int vveli[5], int comp[5]);
int ugadal(int vveli[5], int comp[5]);

int computer()
{
    srand(time(NULL));
    int generation = 100 + rand() % ((999 + 1) - 100);
    return(generation);

}

int count(int x, int vveli[5], int RANGE)
{
    for (int i = 0; i < RANGE; i++)
    {
        int step = pow(10, (RANGE - i));
        vveli[i] = (x % step) / pow(10, (RANGE - 1 - i));
    }
    return(0);
}

int place(int vveli[5], int comp[5])
{
    int position = 0;
    for (int i = 0; i < RANGE; i++)
    {
        if (vveli[i] == comp[i])
            position++;
    }
    return(position);
}

int ugadal(int vveli[5], int comp[5])
{
    int total = 0;
  
    for (int i = 0; i < RANGE; i++)
    {
        for (int j = 0; j < RANGE; j++) // ближе всего - без этой строчки
        if (vveli[i] == comp[j])
            total++;

    }

    return(total);
}
int main()
{
    setlocale(LC_ALL, "Russian");
    printf("Загадано число с %d цифрами, поехали\n", RANGE);
    printf("Подсказка...: %d\n", comp_num);
    count(comp_num, comp, RANGE);

    do
    {
        puts("Ваш вариант:");
        scanf_s("%d", &x);
        int O = x / pow(10, RANGE - 1);
        if (O == 0 || O > 10)
            printf("Введите число с %d цифрами\n", RANGE);
        else {
            count(x, vveli, RANGE);
            printf("Угадано: %d., На своих местах: %d\n", ugadal(vveli, comp), place(vveli, comp));
        }
    } while (ugadal(vveli, comp) < RANGE || place(vveli, comp) < RANGE);
    puts("Верно! ");
    return 0;
}

Сначала кажется, что работает как нужно, но в ситуации, когда загадано, к примеру 761, вводим 777 - программа выдает 3 угаданных числа


Ответы (3 шт):

Автор решения: Mikhailo

Вот это вроде работает:

pair<int, int> check(int value, int guess) {
    pair<int, int> r{0, 0};
    int vd[10] = {0}, gd[10] = {0};

    while (value || guess) {
        int dv = value % 10, dg = guess % 10;

        if (dv == dg) {
            r.first++;
            r.second++;
            }
        else {
            vd[dv]++;
            gd[dg]++;
            }

        value /= 10;
        guess /= 10;
        }

    for (int i = 0; i < 10; ++i)
        if (vd[i]) {
            if (gd[i]) r.second += min(vd[i], gd[i]);
            }

    return r;
    }

Первый член пары - сколько на местах, второй - сколько угадано.

→ Ссылка
Автор решения: Dmitry Prokopenko

Как уже здесь писали, через строки пойти действительно во много раз проще:

#include <iostream>
#include <string>
#include <ctime>
#include <cstdlib>
#include <Windows.h>
#include <set>

using namespace std;

void init()
{
    srand(time(NULL));
    setlocale(LC_ALL, "Russian");
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
}

int chtoi(char ch)
{
    return ch - '0';
}

void guessCheck(int number, int guess)
{
    while (true)
    {
        if (to_string(guess).length() != to_string(number).length())
        {
            cout << endl << "Количество цифр в загаданном числе и предположении игрока не совпадают. Повторите ввод: ";
            cin >> guess;
        }
        else
            break;
    }
}

void guessComparePosition(int number, int guess)
{
    int cnt = 0;
    for (int i = 0; i < to_string(number).length(); i++)
    {
        if (to_string(number)[i] == to_string(guess)[i])
            cnt++;
    }
    cout << "Подсказка: " << cnt << " чисел находятся на своём месте." << endl;
}

void guessCompareNumber(int number, int guess)
{
    int cnt = 0;
    set<int> number_set;
    set<int> guess_set;
    for (int i = 0; i < to_string(number).length(); i++)
    {
        number_set.insert(chtoi(to_string(number)[i]));
        guess_set.insert(chtoi(to_string(guess)[i]));
    }
    set<int>::iterator it_number = number_set.begin();
    for (int i = 0; i < number_set.size(); i++)
    {
        set<int>::iterator it_guess = guess_set.begin();
        for (int j = 0; j < guess_set.size(); j++)
        {
            if (*it_number == *it_guess)
                cnt++;
            it_guess++;
        }
        it_number++;
    }
    cout << cnt << " уникальные цифры числа отгаданы верно." << endl;
}

void guessNumber(int number)
{
    cout << "Попробуйте угадать число. Введите предположение: ";
    int guess;
    cin >> guess;
    guessCheck(number, guess);
    while (true)
    {
        if (guess == number)
        {
            cout << endl << "Поздравляем, вы угадали! Загаданным числом было " << number << endl;
            break;
        }
        else
        {
            cout << endl << "Вы не угадали!" << endl;;
            guessComparePosition(number, guess);
            guessCompareNumber(number, guess);
            cout << "Попробуйте угадать ещё раз: ";
            cin >> guess;
            guessCheck(number, guess);
        }
    }
}

int main()
{
    int number = rand() % 1001;
    cout << "Игра начинается! Загадано число из " << to_string(number).length() << " цифр." << endl;
    guessNumber(number);
    return 0;
}

Открыт для вопросов и критики, если таковые возникнут.

→ Ссылка
Автор решения: someTimes new Roman

В общем, получился вот такой вот финальный вариант через строки. Все "баги" вроде исправил: числа генерируются каждый раз случайно, угаданные числа распознаются корректно, позиции также верно подсчитывает

#include <iostream>
#include <string>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std; 

int getRandom() {
    
    srand(time(NULL));
    int generation = 100 + rand() % ((999 + 1) - 100);
    return(generation);
}

int input() {
    int n{0};
    while (n < 100 || n > 999) {
        cout << "Введите число: ";
        cin >> n;
        if (n < 100 || n>999)
            cout << "Введите число из 3 цифр!"<< endl;
        
    }
    return n;
}
    
int main()
{
    setlocale(LC_ALL, "Russian");
    int test = getRandom();
    cout << "Компьютер загадал трехзначное число, поехали!\n";
    cout << "Подсказка..." << test << std::endl;
    int num{ 0 };
    while (true) {
        num = input();
        string s_test = to_string(test);
        string s_num = to_string(num);
        int guess{ 0 }; 
        int pos{ 0 };
        for (size_t i{ 0 }; i < s_test.length(); ++i) 
        {
            auto includes = find(s_num.begin(), s_num.end(), s_test[i]);
            includes != s_num.end() ? ++guess : guess += 0;

            for (size_t j{ 0 }; j < s_num.length(); ++j) 
            {
                if (s_test[i] == s_num[j] && i == j) ++pos;
            }
        }
        if (num == test) 
            break;
        
        cout << "Угадано: " << guess << ". На своем месте: " << pos << '\n';
    }
    cout << "\n *ВЫ УГАДАЛИ*: ";
    return 0;
}
→ Ссылка