Сравнение числа по одной цифре 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 шт):
Вот это вроде работает:
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;
}
Первый член пары - сколько на местах, второй - сколько угадано.
Как уже здесь писали, через строки пойти действительно во много раз проще:
#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;
}
Открыт для вопросов и критики, если таковые возникнут.
В общем, получился вот такой вот финальный вариант через строки. Все "баги" вроде исправил: числа генерируются каждый раз случайно, угаданные числа распознаются корректно, позиции также верно подсчитывает
#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;
}