Answer the question
In order to leave comments, you need to log in
Rate C++ code please?
//Напишите программу реализующую игру «Угадай число».Компьютер загадывает число от 0 до 999 (используйте генерацию случайных чисел),
//а пользователь угадывает его.На каждом шаге угадывающий делает предположение, а задумавший число — сообщает, сколько цифр из числа угаданы
//и сколько из угаданных цифр занимают правильные позиции в числе.Например, если задумано число 725 и выдвинуто предположение,
//что задумано число 523, то угаданы две цифры(5 и 2) и одна из них занимает верную позицию.
#include <iostream>
#include <ctime>
#include <string>
#include <random>
#include <algorithm>
#include <iomanip> // для ограничения количества вводимых симолов для std::cin
void startTheGame();
int getUsersGuess();
int getRandomNumber(int min, int max);
void compUsrWthCmptr(std::string userInput, std::string computerInput);
int main()
{
setlocale(LC_ALL, "Russian");
srand(static_cast<unsigned int>(time(0)));
startTheGame();
return 0;
}
void compUsrWthCmptr(std::string userInput, std::string computerInput)
{
// Считаем правильно угаданные позиции
std::reverse(userInput.begin(), userInput.end());
std::reverse(computerInput.begin(), computerInput.end());
int guessedPositions{ 0 };
for (int i = 0; (i < userInput.length()) && (i < computerInput.length()); ++i)
{
if (userInput[i] == computerInput[i])
{
guessedPositions++;
}
}
std::string::iterator it_userInput;
std::string::iterator it_computerInput;
// Удаляем повторяющиеся цифры
it_userInput = std::unique(userInput.begin(), userInput.end());
userInput.resize(std::distance(userInput.begin(), it_userInput));
it_computerInput = std::unique(computerInput.begin(), computerInput.end());
computerInput.resize(std::distance(computerInput.begin(), it_computerInput));
// Считаем количество правильно угаданных цифр без учета повторяющихся
int guessedDigits{ 0 };
for (int i = 0; i < userInput.length(); ++i)
{
for (int x = 0; x < computerInput.length(); ++x)
{
if (userInput[i] == computerInput[x])
{
guessedDigits++;
}
}
}
std::cout << " Угадано: " << guessedDigits << ". Соответствует своим разрядам: " << guessedPositions << std::endl << std::endl;
};
void startTheGame()
{
int pcsRandomNumber = getRandomNumber(0, 999); //Загаданое число.
std::cout << " Компьютер загадал трехзначное число от 0 до 999!\n" << " Это: " << pcsRandomNumber << std::endl << std::endl;
std::string pcNumber{ std::to_string(pcsRandomNumber) };
bool win = false;
do
{
int usersGuess = getUsersGuess();
std::string guess{ std::to_string(usersGuess) };
std::cout << " Ваш вариант : " << guess << std::endl;
compUsrWthCmptr(guess, pcNumber);
if (usersGuess == pcsRandomNumber)
{
win = true;
std::cout << " *** Вы угадали число " << pcsRandomNumber << "!***\n";
}
} while (!win);
};
int getUsersGuess()
{
while (true) // цикл продолжается до тех пор, пока пользователь не введет корректное значение
{
std::cout << " Введите коректное значение: ";
int a;
std::cin >> std::setw(3) >> a;
// Проверка на предыдущее извлечение
if (std::cin.fail()) // если предыдущее извлечение оказалось неудачным,
{
std::cin.clear(); // то возвращаем cin в 'обычный' режим работы
std::cin.ignore(32767, '\n'); // и удаляем значения предыдущего ввода из входного буфера
std::cout << " Предыдущее извлечение оказалось неудачным. Попытайтесь еще раз.\n\n";
}
else
{
if (a >= 1000 || a < 0)
{
std::cin.ignore(32767, '\n'); // удаляем лишние значения
std::cout << " Введенное число вне требуемого диапазонате. Попытайтесь еще раз.\n\n";
}
else
{
std::cin.ignore(32767, '\n'); // удаляем лишние значения
return a;
}
}
}
}
int getRandomNumber(int min, int max)
{
return static_cast<int>(rand() % (max - min + 1) + min);
}
Answer the question
In order to leave comments, you need to log in
If you're going to take Crosses more seriously than this C-style lab, pay attention to the following. Your functions perform all sorts of rather banal operations, but at the same time they are called compUsrWthCmptr and assume the execution of precisely these actions that are needed now. Or rather, understanding what this function does and why, when working with it.
For the future, try abstracting away from the task and writing functions that do exactly what they do, without any knowledge of what's going on outside of them. Your function compares two strings - so let it compare. She only needs to know the comparison algorithm, and not that this input is user-defined. Two lines come into it, the result comes out - and that's it.
But in the function that calls it, you will write higher-level code for preparing input for processing by this function and acting on its result. And this function, unlike yours, will be read easily and naturally.
This will keep low-level byte digging isolated from the more human logic of the program, and dividing the code into similar levels makes it much easier to work with. Especially when you move from procedural to class.
Why expand the lines if you can run the comparison cycle in the opposite direction.
As said, it's strange to see output in cout in "utility" functions. It would be logical to return this data by a function (in a tuple / pair or in its own structure).
Most likely an algorithmic error: if 1223 is guessed, and the user entered 92227, then he guessed one or two digits? Probably two.
If the function only looked at the lines, then they had to be passed by const. link or string_view. Because changes, then yes, done correctly - by value. Here the objects are short strings, no effect; and in the general case, then when calling, you can transfer the data that is no longer needed:
Or, it’s easier to remove the guess declaration, and write
compUsrWthCmptr(std::move(guess), pcNumber);
compUsrWthCmptr(std::to_string(usersGuess), pcNumber);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question