Игра «Быки и коровы». Не могу до конца понять логику
Если например программа уже "нашла корову", то проверяет все остальные цифры и если находит "быка" засчитывает. Правильно ли это, или же если например я угадал все число и получил 4 "коровы" то "быков" уже не может быть? КОМЕНТАРИЕМ ОБОЗНАЧИЛ В КОДЕ ТУ ЧАСТЬ,КОТОРУЮ НАДО ПРОВЕРИТЬ(где происходит подсчет быков и коров).
Игра «Быки и коровы». Правила:
программа генерирует случайным образом 4-значное число;
пользователю предлагают угадать сгенерированное программой число;
за каждую угаданную пользователем цифру, стоящую на правильной позиции, он получает «корову»;
за каждую угаданную пользователем цифру, стоящую на неправильной позиции, он получает «быка»;
после каждого предположения пользователю должно выводиться количество «коров» и «быков», которые он заработал;
игра окончена тогда, когда пользователь угадал все цифры.
#include <iostream>
#include <ctime>
#include <Windows.h>
#include <conio.h>
using namespace std;
int main()
{
srand(time(NULL));
rand();
setlocale(LC_ALL, "Rus");
int rand_numb, num;
int arr_rand_system[4] = {}, arr_inputs_sign[4] = {};
int arr_count, count_cow, count_ox, count, attempt_num;
bool continue_ = true;
char n;
cout << "Это игра \"Быки и коровы\"\n";
cout << "программа генерирует случайное 4-значное число;\n"
"вам необходимо угадать это число;\n"
"за каждую угаданную вами цифру, стоящую на правильном месте, вы получите «корову»;\n"
"если же цифра стоит на неправильном месте, вы получает «быка»;\n"
"вы победите тогда когда угадаете все число.\n";
while (continue_ != false)
{
arr_count = 0, count_cow = 0, count_ox = 0, count = 0, attempt_num = 0;
srand(time(NULL));
rand();
rand_numb = (1000 + rand() % 9000);
for (int i = 1000; i >= 1; i /= 10)
{
arr_rand_system[arr_count] = (rand_numb / i) % 10;
arr_count++;
}
while (count != 4)
{
count_cow = 0, count_ox = 0, count = 0;
while (true)
{
cout << "\n\nВведите 4-значное число: ";
cin >> num;
if (cin.fail() || num < 1000 || num > 9999)
{
cin.clear();
cin.ignore(32767, '\n');
cout << "Вы ввели недопустимое число. Попробуйте еще раз\n";
}
else break;
}
arr_count = 0;
for (int i = 1000; i >= 1; i /= 10)
{
arr_inputs_sign[arr_count] = (num / i) % 10;
arr_count++;
}
for (int i = 0; i < 4; i++) // логика игры
{
for (int j = 0; j < 4; j++)
{
if (arr_rand_system[i] == arr_inputs_sign[j] && i == j) // подсчет коров
{
count_cow++;
count++;
continue;
}
else if (arr_rand_system[i] == arr_inputs_sign[j] && i != j) // подсчет быков
count_ox++;
}
}
cout << count_cow << (count_cow == 1 ? " корова, " : (count_cow == 0 ? " коров, " : " коровы, "));
cout << count_ox << (count_ox == 1 ? " бык\n" : (count_ox == 0 ? " быкoв\n" :" быка\n"));
attempt_num++;
}
auto name_attempt = (attempt_num == 1 ? " попытка." :
(attempt_num > 1 && attempt_num < 5 ? " попытки." : " попыток."));
cout << "\n\nПоздравляю, вы выиграли. На это у вас ушло " << attempt_num
<< name_attempt << "\nХотите продолжить ? Если да - нажмите Enter, нет - любую другую клавишу";
if (!_kbhit())
{
n = _getch();
if (n == 13)
continue_ = true;
else
continue_ = false;
}
}
return 0;
}
Ответы (2 шт):
как по мне код очень усложнён
как вижу его я:
можно работать не с числом, а со строкой, в которую переводится число
соответственно пользователь вводит цифру (переводится в букву) и позицию
таким образом общий код должен выглядеть так:
массив использованных цифр
int digits[10]
может содержать значения 0 (цифра не использована), 1 (цифра использована, не в неправильной позиции), 2 (цифра использована в правильной позиции)
кол-во коров = 0
кол-во быков = 0
цикл пока кол-во коров + кол-во быков меньше кол-ву цифр в числе:
запрашиваем у пользователя цифру и позицию
если цифра раньше уже выбиралась (т.е. 1 или 2 в массиве digits) - переходим на начало цикла
проверяем соответствует ли цифра цифре в числе в нужной позиции (одно сравнение буквы и буквы в строке)
если буквы совпадают:
кол-во коров ++
для цифры выставляем в массиве digits значение 2
если буквы не совпадают, то ищем букву в строке и если находим:
кол-во быков ++
для цифры выставляем в массиве digits значение 1
выводим информацию о коровах и быках
#include <iostream>
#include <vector>
#include <algorithm>
#include <random>
#include <string>
#include <ctime>
using namespace std;
string generateSecretNumber(int N) {
vector<char> digits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
shuffle(digits.begin(), digits.end(), mt19937(time(0)));
string secret;
for (int i = 0; i < N; ++i) {
secret += digits[i];
}
return secret;
}
pair<int, int> countBullsAndCows(const string& secret, const string& guess) {
int bulls = 0, cows = 0;
for (int i = 0; i < secret.size(); ++i) {
if (secret[i] == guess[i]) {
++bulls;
} else if (secret.find(guess[i]) != string::npos) {
++cows;
}
}
return {bulls, cows};
}
int main() {
int N;
cout << "Enter length (1-10): ";
cin >> N;
if (N < 1 || N > 10) {
cerr << "Incorrect length!\n";
return 1;
}
string secret = generateSecretNumber(N);
string guess;
int attempts = 0;
cout << "Загадано число из " << N << " уникальных цифр. Угадайте его!\n";
while (true) {
cout << "Ваша попытка: ";
cin >> guess;
if (guess.size() != N) {
cout << "Число должно быть длины " << N << "!\n";
continue;
}
bool hasDuplicate = false;
for (int i = 0; i < N; ++i) {
for (int j = i + 1; j < N; ++j) {
if (guess[i] == guess[j]) {
hasDuplicate = true;
break;
}
}
if (hasDuplicate) break;
}
if (hasDuplicate) {
cout << "Цифры не должны повторяться!\n";
continue;
}
attempts++;
auto [bulls, cows] = countBullsAndCows(secret, guess);
cout << "Быки: " << bulls << ", Коровы: " << cows << endl;
if (bulls == N) {
cout << "Поздравляем! Вы угадали число за " << attempts << " попыток.\n";
break;
}
}
return 0;
}