A continuación, te presentamos un divertido juego matemático escrito en C++. En él, desafiamos al usuario a resolver 6 sumas de dos cantidades aleatorias seleccionadas entre cero y 1 millón, con un tiempo límite de respuesta de 5 segundos (+ 2 segundos por cada nivel superado) y con una dificultad que aumentará gradualmente entre niveles. Cada respuesta correcta aumentará el contador un punto, mientras que cada error le quitará uno. La victoria se obtendrá al acumular 3 puntos o más al final de la partida. 

Ejecución en consola de un código escrito en C++ de un juego matemático de suma.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
#include <unistd.h> // Biblioteca para sleep (pausa)
#include <conio.h>

using namespace std;

int main() {
    // Semilla aleatoria para generar números aleatorios
    srand(time(0));

    int score = 0;
    int numQuestions = 6;
    int difficulty = 0; // Nivel de dificultad
    int tiempoLimite = 5; // Tiempo inicial de 5 segundos

    cout << "¡Prepárate para un emocionante desafío matemático! En este divertido juego de suma tendrás 6 oportunidades para demostrar tus habilidades aritméticas. En cada nivel, tendrás " << tiempoLimite << " segundos para sumar dos cantidades aleatorias de acuerdo al nivel de dificultad (+2 segundos adicionales por cada nivel superado). Para ganar el juego tienes que acumular al menos 3 puntos ¡Buena suerte!" << endl;

    // Esperar a que el usuario presione Enter para comenzar
    cout << "¿Estás preparado? Presiona Enter para comenzar...";
    cin.ignore(); // Esperar a que se presione Enter

    for (int i = 0; i < numQuestions; ++i) {
        int minRange, maxRange;

        // Determina los rangos de números aleatorios según la dificultad
        switch (difficulty) {
            case 0:
                minRange = 0;
                maxRange = 100;
                break;
            case 1:
                minRange = 100;
                maxRange = 1000;
                break;
            case 2:
                minRange = 1000;
                maxRange = 10000;
                break;
            case 3:
                minRange = 10000;
                maxRange = 100000;
                break;
            case 4:
                minRange = 100000;
                maxRange = 1000000;
                break;
            case 5:
                minRange = 100000;
                maxRange = 1000000;
                break;
            default:
                minRange = 0;
                maxRange = 100;
                break;
        }

        double num1, num2;

        // Para la sexta pregunta, generamos números decimales hasta centésimas dentro del rango
        if (difficulty == 5) {
            num1 = (rand() % (maxRange - minRange + 1) + minRange) + (rand() % 10000) / 100.0;
            num2 = (rand() % (maxRange - minRange + 1) + minRange) + (rand() % 10000) / 100.0;
        } else {
            num1 = rand() % (maxRange - minRange + 1) + minRange;
            num2 = rand() % (maxRange - minRange + 1) + minRange;
        }

        double correctAnswer = num1 + num2;
        double userAnswer;
        double startTime = time(0);
        double endTime = startTime + tiempoLimite; // Definir endTime al inicio
        double remainingTime = tiempoLimite;
        bool answered = false;

        // Almacena la pregunta en una cadena antes de mostrar el contador
        string pregunta;
        if (difficulty < 5) {
            pregunta = "Nivel " + to_string(difficulty + 1) + " - ¿Cuánto es " + to_string(static_cast<int>(num1)) + " + " + to_string(static_cast<int>(num2)) + "? ";
        } else {
            pregunta = "Nivel " + to_string(difficulty + 1) + " - ¿Cuánto es " + to_string(num1) + " + " + to_string(num2) + "? ";
        }

        // Agregar un espacio antes de los niveles
        cout << endl;

        // Muestra el tiempo inicial restante junto con la pregunta
        cout << pregunta << "Tienes " << static_cast<int>(remainingTime) << " segundos para responder:" << flush;

        while (endTime > time(0)) {
            if (_kbhit()) { // Verifica si se ha presionado una tecla
                cin >> userAnswer;
                answered = true;
                break; // Sale del bucle si el usuario responde
            }

            sleep(1); // Pausa de 1 segundo
            remainingTime = endTime - time(0); // Actualiza el tiempo restante

            // Actualiza el tiempo restante y muestra en la misma línea
            cout << "\r" << pregunta << "Tienes " << static_cast<int>(remainingTime) << " segundos para responder" << flush;

            if (remainingTime <= 0) {
                cout << "\nTiempo agotado. La respuesta correcta es " << fixed << setprecision(2) << correctAnswer << ". -1 punto." << endl;
                if (score > 0) {
                    score--;
                }
                break; // Sale del bucle si el tiempo se agota
            }
        }

        if (answered && userAnswer == correctAnswer) {
            cout << "\r¡Correcto! +1 punto." << endl;
            score++;
        } else if (!answered) {
            // No mostrar nada aquí, ya que ya se mostró "Tiempo agotado" en el bucle anterior
            if (score > 0) {
                score--;
            }
        } else {
            cout << "\rRespuesta incorrecta. La respuesta correcta es " << fixed << setprecision(2) << correctAnswer << ". -1 punto." << endl;
            if (score > 0) {
                score--;
            }
        }

        // Aumenta la dificultad después de cada pregunta
        if (difficulty < 5) {
            difficulty++;
        }

        // Aumenta el tiempo límite después de cada nivel
        tiempoLimite += 2;
    }

    cout << endl << "Juego terminado. Tu puntaje final es " << score << " de " << numQuestions << "." << endl;

    if (score >= 3) {
        cout << "¡Felicidades, has acumulado al menos 3 puntos y has ganado el juego!" << endl;
    } else {
        cout << "¡Sigue practicando! Puedes hacerlo mejor la próxima vez." << endl;
    }

    return 0;
}

¿Cómo funciona el programa? Se comienza utilizando la función 'srand(time(0));' para inicializar la semilla del generador de números aleatorios. Como la semilla se basa en la hora actual, los números generados (sumandos) serán diferentes cada vez que se ejecute el programa. De este modo, evitaremos que los resultados sean predecibles o repetitivos. Después se declaran las variables de tipo entero ('int'): 'score' (puntaje del jugador), 'numQuestions' para el número de preguntas que se deben responder, 'difficulty' para el nivel de dificultad actual y 'tiempoLimite' para el tiempo límite de respuesta.

Luego se muestra una breve presentación del juego, y el programa espera a que el usuario presione la tecla "Enter" para continuar, utilizando para este fin la función "cin.ignore();". Esta función descarta o ignora los caracteres restantes en el buffer de entrada. En nuestro caso, al no tener argumentos, espera que se presione la tecla Enter para continuar con la ejecución normal del programa. Esto le da el tiempo al usuario para que lea las instrucciones del juego.

Luego comienza un bucle for que se ejecuta para cada una de las preguntas (numQuestions) del juego. Dentro de este bucle, se establecen los rangos de números aleatorios (minRange y maxRange) según el nivel de dificultad actual, es decir los números entre 0 y 1 millón mediante la estructura de control Switch. Esta estructura evalúa la expresion 'difficulty' (nivel de dificultad), que inicialmente tiene un valor de 0. Y busca el 'case' correspondiente al nivel actual. Recuerda que en cada bucle la variable 'difficulty' aumentará 1 unidad, por lo que el rango de números aumentará.

Posteriormente se generan los números aleatorios (num1 y num2) dentro de los rangos determinados y se calcula la respuesta correcta (correctAnswer) para la pregunta actual. Se muestra la pregunta al usuario en consola, junto con el tiempo restante para responder, utilizando un temporizador que se actualiza cada segundo.

El usuario introduce la cantidad calculada mediante kbhit(). Esta función se utiliza para verificar si se ha presionado una tecla sin bloquear la ejecución del programa. El programa verifica si el usuario ha presionado una tecla. Si es así, lee la respuesta del usuario y se establece la bandera answered en true, saliendo del bucle de temporización.

Si el usuario no ha presionado una tecla antes de que se agote el tiempo, se muestra un mensaje de "Tiempo agotado" y se resta un punto a la puntuación total. Si el usuario ha respondido en el tiempo correspondiente, se compara su respuesta con la respuesta correcta y se ajusta la puntuación en consecuencia.

La dificultad aumenta después de cada pregunta y el tiempo límite también aumenta 2 segundos adicionales por cada nivel superior. El bucle continúa hasta que se hayan realizado todas las preguntas. Finalmente, después de salir del bucle, se muestra el puntaje final y un mensaje de juego ganado o perdido según la puntuación obtenida.

Este programa presenta una serie de errores que debes tomar en cuenta, y corregirlos si lo crees pertinente. Sinceramente yo no encontré la solución, aunque pienso que no afecta la dinámica del juego en demasía. 

- En primer lugar, si introduces un número antes de que el contador termine su conteo, el temporizador se detendrá, por lo que tendrás tiempo ilimitado para escribir la respuesta hasta que presiones la tecla Enter. Así que la persona debe escribir el número cuando este completamente seguro de la respuesta, no antes, sino el juego pierde su dinamismo.

- En segundo lugar, el temporizador hace que el comportamiento de ciertos signos se muestren o desaparezcan de forma anormal, pero en sí no afecta el flujo del programa.

El código ha sido probado en Code::Blocks en Windows, por lo que es completamente funcional.

Puedes descargar el código .CPP aquí.

NOTA: Si los acentos o caracteres especiales no se muestran correctamente, puedes checar esta solución: ¿Cómo mostrar acentos y caracteres especiales en programas escritos en C++?