Я полагаю, что другие помогут вам с логикой вашей программы, поэтому я поможем вам с вашей структурой; то есть, как вы логически изложили программу и как я думаю, что вы могли бы сделать лучше. Обратите внимание: я на самом деле не запускаю какой-либо код здесь - у меня нет среды, чтобы сделать это в данный момент.
Я начал с автоматического форматирования вашего кода и переноса его из циклов do-while в простые while-loops. Кроме того, я переместил объявления переменных ближе к тому, где они используются. В реальном мире некоторые стандарты кодирования запрещают последний шаг, но я чувствую, что он улучшает читаемость вашей программы и помогает понять мою логику.
enum statuses { NEUTRAL, HIGH, LOW };
int status = NEUTRAL;
char input;
int cpuguess, high = 100, low = 1;
bool playing = true; // use booleans to represent true/false state, rather than characters
while (playing) { // "playing" closer to declaration = arguably easier to read & find purpose
cout << "Guess My Number" << endl << endl;
cout << "Press Enter to Play !" << endl;
cin.ignore();
cin.get();
bool gameWon = false;
while (!gameWon) {
cpuguess = getGuess(status, high, low);
cout << "Is your guess " << cpuguess << " ?" << endl;
cout << "(y/n)";
cin >> input;
gameWon = toupper(input) == 'Y';
if (!gameWon)
{
status = NEUTRAL;
while (status == NEUTRAL) {
cout << "Too HIGH or Too LOW ? O_O" << endl;
cout << "(h/l)";
cin >> input;
input = toupper(input);
if (input == 'H') {
status = HIGH;
high = cpuguess;
} else if (input == 'L') {
status = LOW;
low = cpuguess;
}
}
}
}
cout << "I won ! :D" << endl << endl;
cout << "Do you want to play again ?" << endl;
cout << "(y/n)" << endl;
cin >> input;
playing = toupper(input) == 'Y';
}
-
В вашей программе, вы часто хотите, чтобы пользователь, чтобы дать один из двух ответов. Фактически, мы видим код, аналогичный
cout << "Is your guess " << cpuguess << " ?" << endl;
cout << "(y/n)";
cin >> input;
gameWon = toupper(input) == 'Y';
Три раза! Возможно, мы могли бы ввести новую функцию, скажем, getAnswer, которая задает вопрос и два возможных ответа (например: «y» и «n») и возвращает ответ пользователя? Кроме того, я решил быть последовательным при печати верхних регистров параметров Y/N и считал «\ 0» значением, которое пользователь никогда не будет вводить. В результате программа больше не будет корректно работать, если опция 1 или вариант 2 имеют строчные значения. Есть много способов справиться с этим, например, проверить, что option1 и option2 isupper (c) в начале вашей функции getAnswer, хотя я этого не делал.
char getAnswer(const char * question, const char option1, const char option2);
void main() { // or whatever entry-point signature you've used
enum statuses { NEUTRAL, HIGH, LOW };
int status = NEUTRAL;
char input;
int cpuguess, high = 100, low = 1;
bool playing = true; // use booleans to represent true/false state, rather than characters
while (playing) { // "playing" closer to declaration = arguably easier to read & find purpose
cout << "Guess My Number" << endl << endl;
cout << "Press Enter to Play !" << endl;
cin.ignore();
cin.get();
bool gameWon = false;
while (!gameWon) {
cpuguess = getGuess(status, high, low);
stringstream ss;
ss << "Is your guess " << cpuguess << " ?";
gameWon = getAnswer(ss.c_str(), 'Y', 'N') == 'Y';
if (!gameWon) {
status = getAnswer("Too HIGH or Too LOW ? O_O", 'H', 'L') == 'H' ? HIGH : LOW;
if (status == HIGH)
high = cpuguess;
else
low = cpuguess;
}
}
cout << "I won ! :D" << endl << endl;
playing = getAnswer("Do you want to play again?", 'Y', 'N') == 'Y';
}
}
char getAnswer(const char * question, const char option1, const char option2) {
char response = '\0';
while (response != option1 && response != option2) {
cout << question << endl;
cout << "(" << option1 << "/" << option2 << ")" << endl;
cin >> response;
response = toupper(response);
}
return response;
}
Awesome, наш код выглядит намного ровнее от только что, но мы до сих пор не нарушили наш код на логические части, так что давайте попробуем сделать это. Обратите внимание, что я переместил часть вашего вывода на консоль вне внешнего цикла while и изменил «ваша догадка» на «ваш номер». Раньше, если бы пользователь заявлял, что хочет играть снова, им придется нажать enter после того, что было досадно!
enum class GuessStatus { NEUTRAL, HIGH, LOW }; // I elected to use c++11's 'enum class'
// these are called forward declarations
void runIntroduction();
void playGame();
// I elected to use const char * and const char here. They weren't necessary, though.
char getAnswer(const char * question, const char option1, const char option2);
void main() { // or whatever entry-point signature you've used
runIntroduction();
bool playing = true; // use booleans to represent true/false state, rather than characters
while (playing) { // "playing" closer to declaration = arguably easier to read & find purpose
playGame();
playing = getAnswer("Do you want to play again?", 'Y', 'N') == 'Y';
}
}
void runIntroduction() {
cout << "Guess My Number" << endl << endl;
cout << "Press Enter to Play !" << endl;
cin.ignore();
cin.get();
}
void playGame() {
int guessHigh = 100, guessLow = 1;
GuessStatus status = GuessStatus::NEUTRAL; // I'd suggest having GuessState::INITIAL = NEUTRAL to improve readability. Either that, or throwing in a comment to describe why you use NEUTRAL.
bool gameWon = false;
while (!gameWon) {
int cpuguess = getGuess(status, high, low);
stringstream ss;
ss << "Is your number " << cpuguess << " ?";
gameWon = getAnswer(ss.c_str(), 'Y', 'N') == 'Y';
if (!gameWon) {
status = getAnswer("Too HIGH or Too LOW ? O_O", 'H', 'L') == 'H' ? GameStatus::HIGH : GameStatus::LOW;
if (status == GameStatus::HIGH)
high = cpuguess;
else // status == GameStatus::LOW
low = cpuguess;
}
}
cout << "I won ! :D" << endl << endl;
}
char getAnswer(const char * question, const char option1, const char option2) {
char response = '\0';
while (response != option1 && response != option2) {
cout << question << endl;
cout << "(" << option1 << "/" << option2 << ")" << endl;
cin >> response;
response = toupper(response);
}
return response;
}
Это все, не стесняйтесь задавать вопросы, если что-то вводит в заблуждение.
Вам нужно включить функцию 'getGuess', чтобы нам не было догадываться. – Matt
Re 'Любые другие советы в целях улучшения, приветствуются слишком lol.': Я бы посоветовал вам отклониться от использования goto, пока вы не приобретете больше опыта (они, как правило, недовольны, и многие утверждают, что вы должны никогда не используйте их вообще) - они часто (хотя и не всегда, имо) являются индикатором того, что вы неправильно структурировали свою программу и что ваша логика может быть изложена лучше и понятнее. – Warty
omg gotos .... записать его –