Il gioco è molto semplice e si basa sul confronto, premetto che non essendo su ambienti di sviluppo senza compilatori il programma darà sbagliato se la struttura non è esattamente uguale a quella delle soluzioni.
A livello pratico questo è il gioco:

  • L'utente seleziona una difficoltà dall'apposito menu.
  • Viene visualizzata la consegna del problema selezionato.
  • L'utente inserisce il codice C++ nella textarea e fa clic su "Verifica".
  • Il codice viene confrontato con la soluzione corrispondente.
  • Se il codice è corretto si riceverà un messaggio di successo.
  • L'utente può anche selezionare una difficoltà dal menu delle soluzioni per visualizzare la soluzione corrispondente se necessario.

Nel codice HTML si definisce la struttura del gioco in particolare titolo, livelli, textarea, pulsanti e l'area del risultato.
Alla fine della pagina abbiamo un menu delle soluzioni a discesa <select> e l'apposita are <pre> e collegamento con i file CSS e Javascript.

Nel codice Javascript all'inizio vengono subito definiti due oggetti: problems e solutions che contengono le consegne dei problemi e le soluzioni.
Vengono anche richiamati vari elementi HTML come document.getElementById e document.querySelector.
La funzione currentDifficulty serve per dare una variabile iniziale per la difficoltà del gioco, updateProblem viene richiamata per aggiornare il testo in base all'area di input che abbiamo cliccato.
Gli eventi sono gestiti tramite event listeners come change > difficultySelect.
"Click" viene richiamato nel pulsante "Verifica" che innesca il confronto fra codice inserito dall'utente e la soluzione corrispondente.
Sempre l'evento change viene richiamato alla fine della pagina per visualizzare le soluzioni.

HTML:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cbomba</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div class="container">
        <h1>Cbomba</h1>
        <div class="difficulty">
            <label for="difficulty">Livello:</label>
            <select id="difficulty">
                <option value="easy">1</option>
                <option value="medium">2</option>
                <option value="hard">3</option>
            </select>
        </div>
        <div class="game-container">
            <p id="problem"></p>
            <textarea id="user-input" rows="4" cols="30" placeholder="Inserisci qui il tuo codice C++"></textarea>
            <button id="check-button">Verifica</button>
            <p id="result"></p>
        </div>
        <div class="bomb-container">
            <img id="bomb" src="bomb.webp" alt="Bomba">
            <img id="defused-bomb" src="defused.png" alt="Bomba Disinnescata" style="display: none;">
        </div>
        <div id="console-output" class="console"></div>

        <div class="solution-menu">
            <label for="solution">Soluzioni:</label>
            <select id="solution">
                <option value="none">Nessuna</option>
                <option value="easy">1</option>
                <option value="medium">2</option>
                <option value="hard">3</option>
            </select>
        </div>

        <div class="solution-container">
            <h2>Soluzione:</h2>
            <pre id="solution-text"></pre>
        </div>
    </div>
    <script src="script.js"></script>
</body>
</html>

CSS:

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f0f0f0;
}

.container {
    max-width: 800px;
    margin: 0 auto;
    padding: 20px;
    background-color: #fff;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}

h1 {
    text-align: center;
    color: #333;
}

.difficulty {
    text-align: center;
    margin-bottom: 20px;
}

.game-container {
    padding: 20px;
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    border-radius: 5px;
}

#problem {
    font-family: monospace;
}

textarea {
    width: 100%;
    padding: 10px;
    margin: 10px 0;
}

button {
    padding: 10px 20px;
    background-color: #007bff;
    color: #fff;
    border: none;
    cursor: pointer;
}

button:hover {
    background-color: #0056b3;
}

.result {
    text-align: center;
    font-weight: bold;
    margin-top: 20px;
}

.bomb-container {
    text-align: center;
    margin-top: 20px;
}

.console {
    margin-top: 20px;
    padding: 10px;
    background-color: #333;
    color: #fff;
    border-radius: 5px;
    font-family: monospace;
    white-space: pre-wrap;
}

img {
    max-width: 100%;
    height: auto;
}


.solution-menu {
    text-align: center;
    margin-bottom: 20px;
}


.solution-container {
    display: none;
}

.solution-container h2 {
    text-align: center;
}

.solution-container pre {
    background-color: #f9f9f9;
    border: 1px solid #ddd;
    padding: 10px;
    border-radius: 5px;
    white-space: pre-wrap;
}

Javascript:

const problems = {
    easy: `// Consegna:
// Programma in C++ che calcoli la somma dei primi 100 numeri interi positivi.`,
    medium: `// Consegna:
// Programma in C++ che calcoli il fattoriale di un numero inserito dall'utente.
// Il programma deve chiedere all'utente di inserire il numero e restituire il risultato.`,
    hard: `// Consegna:
// Scrivi un programma C++ che trovi tutti i numeri primi nell'intervallo da 1 a 100.`
};

const solutions = {
    easy: `#include <iostream>
using namespace std;

int main() {
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
        sum += i;
    }
    cout << "La somma è: " << sum << endl;
    return 0;
}`,
    medium: `#include <iostream>
using namespace std;

int factorial(int n) {
    if (n == 0) {
        return 1;
    }
    return n * factorial(n - 1);
}

int main() {
    int num;
    cout << "Inserisci un numero intero positivo: ";
    cin >> num;
    int result = factorial(num);
    cout << "Il fattoriale di " << num << " è: " << result << endl;
    return 0;
}`,
    hard: `#include <iostream>
using namespace std;

int main() {
    cout << "Numeri primi nell'intervallo da 1 a 100: ";
    for (int i = 2; i <= 100; i++) {
        bool isPrime = true;
        for (int j = 2; j <= i / 2; j++) {
            if (i % j == 0) {
                isPrime = false;
                break;
            }
        }
        if (isPrime) {
            cout << i << " ";
        }
    }
    cout << endl;
    return 0;
}`,
};

const difficultySelect = document.getElementById("difficulty");
const problemText = document.getElementById("problem");
const userInput = document.getElementById("user-input");
const checkButton = document.getElementById("check-button");
const resultText = document.getElementById("result");
const bombImage = document.getElementById("bomb");
const defusedBombImage = document.getElementById("defused-bomb");
const consoleOutput = document.getElementById("console-output");

const solutionSelect = document.getElementById("solution");
const solutionText = document.getElementById("solution-text");
const solutionContainer = document.querySelector(".solution-container");

let currentDifficulty = "easy";

function updateProblem() {
    problemText.textContent = problems[currentDifficulty];
    userInput.value = '';
    resultText.textContent = '';
    consoleOutput.textContent = '';
    bombImage.style.display = 'block';
    defusedBombImage.style.display = 'none';
}

difficultySelect.addEventListener("change", () => {
    currentDifficulty = difficultySelect.value;
    updateProblem();
});

checkButton.addEventListener("click", () => {
    const userCode = userInput.value.trim();
    const solutionCode = solutions[currentDifficulty].trim();

    if (userCode === solutionCode) {
        resultText.textContent = "Hai disinnescato la bomba! La città è al sicuro!";
        bombImage.style.display = 'none';
        defusedBombImage.style.display = 'block';
    } else {
        resultText.textContent = "La bomba è esplosa! Riprova.";
        bombImage.style.display = 'block';
        defusedBombImage.style.display = 'none';
        consoleOutput.textContent = "Errore: Il tuo codice C++ non è corretto.";
    }
});

// Aggiornamento
solutionSelect.addEventListener("change", () => {
    const selectedSolution = solutionSelect.value;
    if (selectedSolution === "none") {
        solutionContainer.style.display = "none";
        solutionText.textContent = "";
    } else {
        solutionContainer.style.display = "block";
        solutionText.textContent = solutions[selectedSolution];
    }
});

updateProblem();

    Samueleex idea molto interessante, che mi ricorda un fatto curioso: esame opzionale, programmazione Ruby 😅 a vederlo è un linguaggio multipurpose interpretato orientato agli oggetti, misto fra Python e MATLAB (insomma, ne farei anche a meno di questo "ibrido"). Ebbene, l'esame funzionava proprio così: scrivevi il sorgente e se coincideva con un "checker" creato dal docente (di fatto quindi analogo a questo esercizio) l'esame era superato (la parte pratica al computer, appunto) altrimenti no. Valutazione quindi estremamente rigida e automatizzata, diciamo che per un esame universitario lo sconsiglio, non è l'ideale! 🤣

    Giusto un consiglio aggiuntivo: dato che sarebbe improponibile pensare ad un tool, checker più complesso che riesca ad analizzare e quindi riconoscere l'output, lavoriamo sempre sul codice sorgente, si possono inserire una serie di varianti accettate, in pseudocodice significa: if(nome1 OR nome2 OR nome3...), quindi tramite operatore OR prevedere qualche possibile variante e verificare possibilmente il "core" (anche es. come sottostringa necessaria del totale ovvero "se questa parte oppure quest'altra è contenuta, allora OK"), significa che non occorre testare quello che scrivi nella prinft per esempio, mentre testiamo il ciclo se è corretto: qui si cerca anche di mantenere un certo standard, "best practices" di programmazione (ovvero eviterei cose assurde del tipo i-=-1 che di fatto è pur sempre coincidente ad i++). Un'alternativa per avere maggiore versatilità nell'input (es. il contatore che lo chiami "i" oppure "j" concettualmente non cambia) si potrebbe fare uso di espressioni regolari, il tutto diventa appunto più versatile, un bel po' più complesso sia da scrivere che da leggere, sappiamo che le Regex non piacciono a nessuno ahah!
    Idea comunque molto interessante! 🙂

    Powered by: FreeFlarum.
    (remove this footer)