Semi-complejo adivina mi número -- ++ campo con number-guessing-game camp codereview Relacionados El problema

Semi-complex Guess My Number


5
vote

problema

Español

Por favor, comprenda mi solicitud antes de comentar, estoy buscando críticas positivas de mi trabajo. Cualquier cosa que haya hecho, que podría hacerse mejor al usar las mismas, o similares, las restricciones en los tipos de datos y los archivos que he usado. Para decirlo de otra manera, si ve todo lo que se podría hacer de manera más eficiente, utilizando las mismas restricciones, avise.

Sé que hay formas más elegantes de hacer esto. Solo estoy tratando de impulsar mi comprensión de las construcciones básicas de C ++, antes de ingresar a las implementaciones más avanzadas de C ++.

Código:

  //02_ex_03_guess_my_number_aplha #include <iostream> #include <ctime> #include <cstdlib>  using namespace std;  int main() {     bool exitGame = false;     bool playAgain = true;     bool roundOver = false;     char playAgainYes = 'y';     int playModeSelect = 0;     int computersNumber = 0;     int tooLow = 0;     int tooHigh = 101;     int playersNumber = 0;     int tries = 0;      enum playMode { playerVersusCpu = 1, cpuVersusPlayer, exitMenu};     srand(static_cast<unsigned int>(time(0)));      cout << " Guess My Number alpha   ";          do         {             cout << "1 - Player Versus Computer ";             cout << "2 - Computer Versus Player ";             cout << "3 - Exit ";             cout << "Select a game mode: ";              cin >> playModeSelect;              switch (playModeSelect)             {             case playerVersusCpu:                 cout << "You have selected Player VS Computer ";                 do                 {                     tries = 0;                     playAgainYes = 'n';                     cout << "Welcome. Try to guess my number: ";                     computersNumber = (rand()) % 100 + 1;                     do                     {                         cout << "DEBUG " << computersNumber;                          cin >> playersNumber;                         if (playersNumber > computersNumber)                         {                             cout << "Too bad. Your guess was too high. ";                             cout << "Try again: ";                             ++tries;                         }                         else if (playersNumber < computersNumber)                         {                             cout << "Too bad. Your guess was too low. ";                             cout << "Try again: ";                             ++tries;                         }                         else if (playersNumber = computersNumber)                         {                             cout << "You did it. You guessed my number. ";                             ++tries;                             cout << "It only took you " << tries << " tries. ";                             do                              {                                 cout << "Would you like to play again? ('y'/'n'): ";                                 cin >> playAgainYes;                                 if (playAgainYes == 'y')                                 {                                     playAgain = true;                                     cout << playAgainYes << "DEBUG ";                                 }                                 else if (playAgainYes == 'n')                                 {                                     playAgain = false;                                     cout << playAgainYes << "DEBUG ";                                 }                                 else                                 {                                     cout << "Inncorrect input ";                                     cout << "Select 'y' or 'n': ";                                 }                             } while ((playAgainYes != 'y') && (playAgainYes != 'n' ));                         }                     } while (playersNumber != computersNumber);                 } while (playAgainYes == 'y');//             break;              case cpuVersusPlayer:                 cout << "  You have selected Computer VS Player ";             do             {                 cout << "Pick a number: ";                 cin >> playersNumber;                 tries = 0;                 tooLow = 0;                 tooHigh = 101;                 do                 {                     computersNumber = rand() % 100 + 1;                     while ((computersNumber != playersNumber) && (computersNumber > tooLow) && (computersNumber < tooHigh))                     {                         ++tries;                         cout << "Is it, " << computersNumber << "? ";                         cout << "This was my " << tries << " try. ";                         if ((computersNumber > tooLow) && (computersNumber < playersNumber))                         {                             tooLow = computersNumber;                         }                          else if ((computersNumber < tooHigh) && (computersNumber > playersNumber))                         {                             tooHigh = computersNumber;                         }                     }                  } while (computersNumber != playersNumber);                 cout << "Well then it has to be " << computersNumber << " ";                 cout << "Only took me " << ++tries << " goes!  ";                 do                 {                     cout << "Would you like to play again? ('y'/'n'): ";                     cin >> playAgainYes;                     if (playAgainYes == 'y')                     {                         playAgain = true;                         cout << playAgainYes << "DEBUG ";                     }                     else if (playAgainYes == 'n')                     {                         playAgain = false;                         cout << playAgainYes << "DEBUG ";                     }                     else                     {                         cout << "Inncorrect input ";                         cout << "Select 'y' or 'n': ";                     }                 } while ((playAgainYes != 'y') && (playAgainYes != 'n'));             } while (playAgainYes == 'y');             break;              case exitMenu:                 exitGame = true;                 break;              default:                 cout << "Invalid selection. Please try again. ";                 cout << "1 - Player Versus Computer ";                 cout << "2 - Computer Versus Player ";                 cout << "3 - Exit ";                 cout << "Select a game mode: ";                 break;              }      } while (exitGame != true); //plan on implementing an escape feature to the program      system("pause");      return 0; }   
Original en ingles

Please understand my request before commenting, I'm looking for positive critiques of my work. Anything I've done which could be done better while using the same, or similar, restrictions on data types and #include files that I've used. To put it another way, if you see anything that could be done more efficiently, using the same restrictions, please advise.

I know there's more elegant ways to do this. I'm just trying to push my understanding of the basic C++ constructs, before getting into more advanced C++ implementations.

code:

//02_ex_03_guess_my_number_aplha #include <iostream> #include <ctime> #include <cstdlib>  using namespace std;  int main() {     bool exitGame = false;     bool playAgain = true;     bool roundOver = false;     char playAgainYes = 'y';     int playModeSelect = 0;     int computersNumber = 0;     int tooLow = 0;     int tooHigh = 101;     int playersNumber = 0;     int tries = 0;      enum playMode { playerVersusCpu = 1, cpuVersusPlayer, exitMenu};     srand(static_cast<unsigned int>(time(0)));      cout << "\tGuess My Number alpha\n\n\n";          do         {             cout << "1 - Player Versus Computer\n";             cout << "2 - Computer Versus Player\n";             cout << "3 - Exit\n";             cout << "Select a game mode: ";              cin >> playModeSelect;              switch (playModeSelect)             {             case playerVersusCpu:                 cout << "You have selected Player VS Computer\n";                 do                 {                     tries = 0;                     playAgainYes = 'n';                     cout << "Welcome. Try to guess my number: ";                     computersNumber = (rand()) % 100 + 1;                     do                     {                         cout << "DEBUG " << computersNumber;                          cin >> playersNumber;                         if (playersNumber > computersNumber)                         {                             cout << "Too bad. Your guess was too high.\n";                             cout << "Try again: ";                             ++tries;                         }                         else if (playersNumber < computersNumber)                         {                             cout << "Too bad. Your guess was too low.\n";                             cout << "Try again: ";                             ++tries;                         }                         else if (playersNumber = computersNumber)                         {                             cout << "You did it. You guessed my number.\n";                             ++tries;                             cout << "It only took you " << tries << " tries.\n";                             do                              {                                 cout << "Would you like to play again? ('y'/'n'): ";                                 cin >> playAgainYes;                                 if (playAgainYes == 'y')                                 {                                     playAgain = true;                                     cout << playAgainYes << "DEBUG\n";                                 }                                 else if (playAgainYes == 'n')                                 {                                     playAgain = false;                                     cout << playAgainYes << "DEBUG\n";                                 }                                 else                                 {                                     cout << "Inncorrect input\n";                                     cout << "Select 'y' or 'n': ";                                 }                             } while ((playAgainYes != 'y') && (playAgainYes != 'n' ));                         }                     } while (playersNumber != computersNumber);                 } while (playAgainYes == 'y');//             break;              case cpuVersusPlayer:                 cout << "\n\nYou have selected Computer VS Player\n";             do             {                 cout << "Pick a number: ";                 cin >> playersNumber;                 tries = 0;                 tooLow = 0;                 tooHigh = 101;                 do                 {                     computersNumber = rand() % 100 + 1;                     while ((computersNumber != playersNumber) && (computersNumber > tooLow) && (computersNumber < tooHigh))                     {                         ++tries;                         cout << "Is it, " << computersNumber << "?\n";                         cout << "This was my " << tries << " try.\n";                         if ((computersNumber > tooLow) && (computersNumber < playersNumber))                         {                             tooLow = computersNumber;                         }                          else if ((computersNumber < tooHigh) && (computersNumber > playersNumber))                         {                             tooHigh = computersNumber;                         }                     }                  } while (computersNumber != playersNumber);                 cout << "Well then it has to be " << computersNumber << "\n";                 cout << "Only took me " << ++tries << " goes!\n\n";                 do                 {                     cout << "Would you like to play again? ('y'/'n'): ";                     cin >> playAgainYes;                     if (playAgainYes == 'y')                     {                         playAgain = true;                         cout << playAgainYes << "DEBUG\n";                     }                     else if (playAgainYes == 'n')                     {                         playAgain = false;                         cout << playAgainYes << "DEBUG\n";                     }                     else                     {                         cout << "Inncorrect input\n";                         cout << "Select 'y' or 'n': ";                     }                 } while ((playAgainYes != 'y') && (playAgainYes != 'n'));             } while (playAgainYes == 'y');             break;              case exitMenu:                 exitGame = true;                 break;              default:                 cout << "Invalid selection. Please try again.\n";                 cout << "1 - Player Versus Computer\n";                 cout << "2 - Computer Versus Player\n";                 cout << "3 - Exit\n";                 cout << "Select a game mode: ";                 break;              }      } while (exitGame != true); //plan on implementing an escape feature to the program      system("pause");      return 0; } 
     

Lista de respuestas

5
 
vote
vote
La mejor respuesta
 

Comenzando con algunas cosas simples:

  using namespace std;   

Es una mala idea importar todo el espacio de nombres de std en su programa. En su lugar, le sugiero que tome selectivamente los nombres que pretende usar.

  system("pause");   

Cuando se usa system() , siempre debe verificar su valor de devolución; En este caso en particular, siempre fallará a menos que haya un programa 99887766555544334 en la ruta del usuario. No tengo tal cosa, y no parece estar en ninguna distribución de Linux común que he visto, parece ser este patrón anti-patrón < / a>.

Dos variables se declaran pero nunca se usan: playAgain y roundOver .


en la estructura. El código se parece a un gran principal (). Realmente ayuda a identificar los trozos de funcionalidad autocontenidos y, especialmente, cualquier parte reutilizable del programa. Así que escribiría algo más como:

  int main() {     playMode playModeSelect;     do {         playModeSelect = selectPlayMode();         switch (playModeSelect) {         case playerVersusCpu:             playComputersChoice();             break;         case cpuVersusPlayer:             playPlayersChoice();             break;         case exitMenu:             // do nothing here             break;         }     } while (playModeSelect != exitMenu); }   

Habiendo hecho eso, podemos implementar las funciones selectPlayMode() , playComputersChoice()9 y std0 . Vamos a empezar con std1 . Se ve una versión de función de su código:

  std2  

Podemos ser más rigurosos para garantizar que los números mostrados coincidan con la forma en que los interpretamos:

  std3  

Tenga en cuenta que he eliminado explícitamente el flujo de salida antes de leer cualquier entrada. Este debería suceder cuando cambia entre std4 std5 , pero es bueno quedar claro que esto es lo que queremos.


Ahora vamos a seguir adelante a std6 . Si extraemos esto en una función, tenemos:

  std7  

Algunas cosas que veo aquí: en la cascada IF / ONDE-IF, la última condición siempre será cierta si los dos primeros fueron falsos, por lo que podemos escribir un simple 99887766555443318 allí. Tenga en cuenta también que incrementamos std9 en cada sucursal del IF, para que podamos alquilar esa declaración para que siempre se ejecute. Finalmente, el DO / mientras repite la prueba de system("pause"); 0 Contra system("pause"); 1 ; En lugar de eso, podríamos escribir un bucle infinito, y romperlo cuando el jugador gana:

  system("pause"); 2  

Verá que hice system("pause"); 3 constante, para mostrar que durante este juego, la computadora no puede cambiar su número secreto, ¡eso sería trampa! Más seriamente, el uso juicioso de system("pause"); 4 puede ayudar a evitar malentendidos y errores.


Finalmente, hagamos que la computadora haga la adivinación:

  system("pause"); 5  

Hay algunos cambios que podemos hacer aquí. Primero, deberíamos asegurarnos de que el número del jugador esté dentro del rango 1-100, de lo contrario, la computadora nunca puede adivinarla:

  system("pause"); 6  

Además, la computadora debe poder usar sus valores altos y bajos determinados previamente al adivinar:

  system("pause"); 7  

y podemos usar un bucle similar al juego del jugador:

  system("pause"); 8  

ahora, algo que se aplica a lo largo. ¿Qué pasa si no ingresas un número cuando se le pregunta? El operador system("pause"); 9 devolverá falso, pero nunca lo veremos, y nunca lo arreglamos. Definitivamente necesitamos un manejo de errores, y para evitar escribir el mismo código muchas veces, lo querremos como una función:

  system()0  

No te creo la pregunta "Juega de nuevo (y / n)". Dado que la opción 3 del menú es "Salir", luego preguntar si volver a jugar es redundante. Podría ir al otro lado, y eliminar la opción de salida en su lugar.


Mi versión

  system()1  
 

Starting with a few simple things:

using namespace std; 

It's a poor idea to import the whole of std namespace into your program. Instead, I suggest you selectively take just those names you intend to use.

system("pause"); 

When using system(), you should always check its return value; in this particular case, it will always fail unless there's a pause program on the user's PATH. I have no such thing, and it doesn't seem to be in any common Linux distribution I've ever seen - it appears to be this anti-pattern.

Two variables are declared but never used: playAgain and roundOver.


On to the structure. The code looks like One Big Main(). It really helps to identify self-contained chunks of functionality and, especially, any re-usable parts of the program. So I'd write something more like:

int main() {     playMode playModeSelect;     do {         playModeSelect = selectPlayMode();         switch (playModeSelect) {         case playerVersusCpu:             playComputersChoice();             break;         case cpuVersusPlayer:             playPlayersChoice();             break;         case exitMenu:             // do nothing here             break;         }     } while (playModeSelect != exitMenu); } 

Having done that, we can implement the functions selectPlayMode(), playComputersChoice() and playPlayersChoice(). Let's start with selectPlayMode(). A function version of your code looks like:

playMode selectPlayMode() {     using std::cout;     using std::cin;      cout << "1 - Player Versus Computer\n";     cout << "2 - Computer Versus Player\n";     cout << "3 - Exit\n";     cout << "Select a game mode: ";      int playModeSelect;     cin >> playModeSelect;     return playMode(playModeSelect); } 

We can be more rigorous about ensuring that the displayed numbers match how we interpret them:

cout << playerVersusCpu << " - Player Versus Computer\n"; cout << cpuVersusPlayer << " - Computer Versus Player\n"; cout << exitMenu << " - Exit\n"; cout << "Select a game mode: " << std::flush; 

Note that I've explicitly flushed the output stream before reading any input. This should happen anyway when switching between cout and cin, but it's good to be clear that this is what we want.


Now let's move on to playComputersChoice(). If we extract this into a function, we have:

void playComputersChoice() {     int computersNumber = (rand()) % 100 + 1;     int tries = 0;     std::cout << "Welcome. Try to guess my number: " << std::flush;     int playersNumber;     do {         std::cin >> playersNumber;         if (playersNumber > computersNumber)             {                 std::cout << "Too bad. Your guess was too high.\n";                 std::cout << "Try again: " << std::flush;                 ++tries;             }         else if (playersNumber < computersNumber)             {                 std::cout << "Too bad. Your guess was too low.\n";                 std::cout << "Try again: " << std::flush;                 ++tries;             }         else if (playersNumber = computersNumber)             {                 std::cout << "You did it. You guessed my number.\n";                 ++tries;                 std::cout << "It only took you " << tries << " tries.\n";             }     } while (playersNumber != computersNumber); } 

Some things that I see here: in the if/else-if cascade, the last condition will always be true if the first two were false, so we can write a simple else there. Note also that we increment tries in each branch of the if, so we can hoist that statement so it's always executed. Finally, the do/while repeats the test of playersNumber against computersNumber; instead of that, we could write an infinite loop, and break out of it when the player wins:

void playComputersChoice() {     const int computersNumber = (rand()) % 100 + 1;     std::cout << "Welcome. Try to guess my number: " << std::flush;     for (int tries = 0;  ;  ++tries) {         int playersNumber;         std::cin >> playersNumber;         if (playersNumber > computersNumber) {             std::cout << "Too bad. Your guess was too high.\n"                       << "Try again: " << std::flush;         } else if (playersNumber < computersNumber) {             std::cout << "Too bad. Your guess was too low.\n"                       << "Try again: " << std::flush;         } else {             std::cout << "You did it. You guessed my number.\n"                       << "It only took you " << tries << " tries.\n";             return;         }     } } 

You'll see that I made computersNumber constant, to show that during this game, the computer can't change its secret number - that would be cheating! More seriously, the judicious use of const can help to avoid misunderstandings and mistakes.


Finally, let's have the computer do the guessing:

void playPlayersChoice() {     int playersNumber;     std::cout << "Pick a number: " << std::flush;     std::cin >> playersNumber;     int tries = 0;     int tooLow = 0;     int tooHigh = 101;     int computersNumber;     do {         computersNumber = rand() % 100 + 1;         while ((computersNumber != playersNumber) && (computersNumber > tooLow) && (computersNumber < tooHigh)) {             ++tries;             std::cout << "Is it " << computersNumber << "?\n";             std::cout << "This was my " << tries << " try.\n";             if ((computersNumber > tooLow) && (computersNumber < playersNumber)) {                 tooLow = computersNumber;             } else if ((computersNumber < tooHigh) && (computersNumber > playersNumber)) {                 tooHigh = computersNumber;             }         }      } while (computersNumber != playersNumber);     std::cout << "Well then it has to be " << computersNumber << "\n";     std::cout << "Only took me " << ++tries << " goes!\n\n"; } 

There's a few changes we can make here. First, we should ensure that the player's number is within the range 1-100, otherwise the computer can never guess it:

int playersNumber; do {     std::cout << "Pick a number: " << std::flush;     std::cin >> playersNumber; } while (playersNumber < 1 || playersNumber > 100); 

Also, the computer should be able to use its previously determined high and low values when guessing:

    computersNumber = tooLow + 1 + rand() % (tooHigh-tooLow-1); 

And we can use a similar loop to the player's game:

for (int tries = 0;  ;  ++tries) { 

Now, something that applies throughout. What happens if you don't enter a number when asked? The >> operator will return false, but we never check it, and never fix up the stream. We definitely need some error handling, and to avoid writing the same code many times, we'll want it as a function:

int readInteger(const char *prompt) {     std::cout << prompt << std::flush;     int n;     if (std::cin >> n)         return n;     // else, clean up and ask again     std::cin.clear();     return readInteger(prompt); } 

I don't think you the "Play again (y/n)" question. Given that choice 3 from the menu is "exit", then asking whether to play again is redundant. You could go the other way, and remove the exit option instead.


My version

#include <iostream> #include <ctime> #include <cstdlib> #include <string>  int readInteger(const char *prompt) {     std::cout << prompt << std::flush;     int n;     if (std::cin >> n)         return n;     // else, clean up and ask again     std::cin.clear();     std::string line;     std::getline(std::cin, line);     return readInteger(prompt); }  void playComputersChoice() {     const int computersNumber = (rand()) % 100 + 1;     std::cout << "Welcome. Try to guess my number.\n";     for (int tries = 0;  ;  ++tries) {         int playersNumber = readInteger("Your guess: ");         if (playersNumber > computersNumber) {             std::cout << "Too bad. Your guess was too high.\n";         } else if (playersNumber < computersNumber) {             std::cout << "Too bad. Your guess was too low.\n";         } else {             std::cout << "You did it. You guessed my number.\n"                       << "It only took you " << tries << " tries.\n";             return;         }     } }  void playPlayersChoice() {     int playersNumber;     do {         playersNumber = readInteger("Pick a number: ");     } while (playersNumber < 1 || playersNumber > 100);      int tooLow = 0;     int tooHigh = 101;     for (int tries = 0;  ;  ++tries) {         int computersNumber = tooLow + 1 + rand() % (tooHigh-tooLow-1);         std::cout << "Is it " << computersNumber << "?\n";         std::cout << "This was my " << tries << " try.\n";         if (computersNumber < playersNumber) {             tooLow = computersNumber;         } else if (computersNumber > playersNumber) {             tooHigh = computersNumber;         } else {             // found it             std::cout << "Well then it has to be " << computersNumber << "\n";             std::cout << "Only took me " << ++tries << " goes!\n\n";             return;         }     } }  enum playMode { playerVersusCpu = 1, cpuVersusPlayer, exitMenu};  playMode selectPlayMode() {     std::cout << playerVersusCpu << " - Player Versus Computer\n";     std::cout << cpuVersusPlayer << " - Computer Versus Player\n";     std::cout << exitMenu << " - Exit\n";      return playMode(readInteger("Select a game mode: ")); }  int main() {     std::srand(static_cast<unsigned int>(std::time(nullptr)));      playMode playModeSelect;     do {         playModeSelect = selectPlayMode();         switch (playModeSelect) {         case playerVersusCpu:             playComputersChoice();             break;         case cpuVersusPlayer:             playPlayersChoice();             break;         case exitMenu:             // do nothing here             break;         }     } while (playModeSelect != exitMenu); } 
 
 
     
     

Relacionados problema

24  Juego de adivinación del número principiante en Java  ( Beginner number guessing game in java ) 
Soy un estudiante de CS primer año. Actualmente estamos aprendiendo a Java y mi última asignación fue crear este juego de números aleatorios. Espero obtener a...

5  Juego de adivinanzas de números en Kotlin  ( Number guessing game in kotlin ) 
¿Está faltando este código? "Kotlinismos"? Acabo de empezar a aprender a Kotlin, así que todavía no estoy familiarizado con la forma de hacer las cosas. E...

10  Juego de adivinanzas de números en Racket  ( Number guessing game in racket ) 
Decidí aprender un idioma Lisp-Ish y estoy descubriendo una sintaxis muy rara y nueva. El primer programa obligatorio, que también usa todos los fundamentos, ...

7  Juego de adivinanzas de números para principiantes  ( Number guessing game for beginners ) 
Estoy enseñando una clase de Python a algunos estudiantes de secundaria. Estaba pensando en hacer un juego de "Oracle" donde la computadora surgiría con un nú...

7  Número aleatorio adivinando  ( Random number guessing ) 
¿Hay algo específicamente malo aquí, o cualquier cosa que pueda mejorar? Líneas de código desperdiciadas, las cosas hechas en una forma más intensiva de memor...

3  Juego de adivinanzas del número de tres jugadores  ( Three player number guessing game ) 
Este es un tutorial de ejercicios de muestra que se utilizaría para probar la comprensión de la sencilla las clases que se comunican / mensaje y están diseñad...

2  Adivinando un número aleatorio entre un rango de números  ( Guessing a random number between a range of numbers ) 
¿Cuál es el patrón de diseño general para declarar variables en una clase? Tengo una tarea para crear un programa de Java simple que le pide al usuario un r...

1  Juego de adivinación de números aleatorios 456  ( Random number guessing game 456 ) 
Este código está funcionando bien, soy bastante nuevo para programar y espero que alguien más experimentado pueda buscarlo y darme algunos punteros. * Aut...

3  "Adivina mi número" en Java  ( Guess my number in java ) 
Acabo de empezar a aprender a Java, y no quiero iniciar ningún mal hábito, así que por favor revise mi último código de juego: namespace TVDBSharp.Models.D...

11  Juego de adivinación de alto bajo  ( High low guessing game ) 
El programa le está pidiendo que adivine un número entre 1-100 y si adivinó demasiado bajo, dice que en sueco y lo mismo ocurre si es demasiado alto y si es l...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos