In questo tutorial impareremo a creare il gioco del 15 online con JavaScript.

Cliccate sui tasselli se adiacenti al tassello vuoto così da spostare i numeri. Quando avrete finito, se tutti i tasselli sono al loro posto, vi comparirà il messaggio di vittoria.

Gioca online al gioco del 15

Gioco del 15


Implementazione del gioco del 15 online con JavaScript

Realizzeremo questo gioco in maniera molto semplice utilizzando i fogli di stile e i metodi di JavaScript per gestire gli eventi. Naturalmente, esistono molte altre modalità di implementazione di questo gioco online con JavaScript, io vi presenterò una delle possibili soluzioni.

Codice HTML

Innanzitutto realizziamo il codice HTM che per lo sviluppo del gioco sarà semplicemente costitutito da un container che conterrà tutti i tasselli a cui assegneremo la classe classe tassello e da un button che serve a mescolare i tasselli.

Ecco dunque l'html di esempio:

<div id="game-container"></div>
<div id="mescola-container">
    <button id="mescola" onclick="mescola()">Mescola</button>
</div>

Foglio di stile per il gioco del 15

Stabiliamo le regole per il nostro foglio di stile. Il gioco è rappresentato da una griglia di 4x4 tasselli, gestita da un div con l'ID game-container. Utilizzando la griglia (grid-template-columns: repeat(4, 1fr);), in questo caso, ciascuna colonna occupa un quarto dello spazio disponibile, e i tasselli, all'interno di queste colonne, si espandono orizzontalmente per coprire la larghezza della colonna.

Banner Pubblicitario

La classe .tassello definisce lo stile visivo di ogni singolo tassello nel gioco del 15. Questo stile include l'aspetto, le dimensioni, i colori e altre proprietà che contribuiscono all'aspetto complessivo dei tasselli nella griglia di gioco. Diamo ad ogni tassello un'altezza fissa di 75px ed una larghezza del 100%. Il fatto che essi si estendano per l'intera larghezza della colonna li rende quadrati. Infatti la proprietà width: 100%; è implicitamente ereditata dal layout grid che occupa l'intera larghezza della cella della griglia.

Ecco di seguito una possibile implementazione:

#game-container {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 5px;
      width: 300px;
      margin: 20px auto;
}

.tassello {
      width: 100%;
      height: 75px;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 24px;
      background-color: #5cb1d6;
      color: white;
      border: 2px solid #3889c4;
      border-radius: 5px;
      cursor: pointer;
}

.empty {
     background-color: #ffffff;
     color: #cccccc;
}

/* Stile del pulsante Mescola */
#mescola-container {
     text-align: center;
}
#mescola {
    display: inline-block;
    padding: 10px 20px;

    font-size: 16px;
    background-color: #4caf50;
    color: white;
    border: none;
    border-radius: 5px;
    cursor: pointer;
}

#mescola:hover {
      background-color: #45a049;
}

Codice JavaScript

Continuiamo l'impementazione del gioco del 15 online utilizzando JavaScript. Innanzitutto selezioniamo i due elementi HTML. Il primo è il pulsante con l'ID 'mescola', al quale viene aggiunto un listener per l'evento 'click' che eseguirà la funzione mescola quando il pulsante viene premuto. Il secondo elemento è un contenitore con l'ID 'game-container' che rappresenta la griglia di gioco.

Poi dichiariamo un array vuoto tasselli. La funzione creaTassello prende un numero come argomento, crea un elemento div, gli assegna la classe 'tassello', imposta il contenuto testuale e aggiunge un listener per il clic. Questo listener chiama la funzione muoviTassello con il numero del tassello come argomento quando il tassello viene cliccato.

Innanzitutto invochiamo la funzione startGame per far iniziare il gioco. La funzione si occupa di cancellare il contenuto del contenitore della griglia utilizzando la seguente riga di codice: (gameContainer.innerHTML = '') e crea tasselli numerati da 1 a 15, oltre ad un tassello vuoto. Questi taselli vengono poi aggiunti al contenitore della griglia utilizzando il metodo appendChild. Successivamente, viene chiamata la funzione mescola per mescolare i tasselli.

La funzione mescola utilizza l'algoritmo di mescolamento Fisher-Yates per scambiare casualmente la posizione dei tasselli nell'array tasselli. La variabile vittoria viene resettata a false, e viene chiamata la funzione modifica per aggiornare l'aspetto della griglia. Difatti la funzione modifica cancella il contenuto del contenitore della griglia e aggiunge nuovamente tutti i tasselli, aggiornando così l'aspetto della griglia.

Banner pubblicitario

La funzione muoviTassello è fondamentale in quanto gestisce il movimento dei tasselli. Inizialmente determina se si è raggiunto il caso di vittoria ed in tal caso, esce dalla funzione. Se non è così cerca l'indice del tassello cliccato e l'indice della casella vuota. Se il tassello cliccato è adiacente alla casella vuota, scambia le loro posizioni, aggiorna l'aspetto della griglia richiamando la funzione modifica e controlla se è stata raggiunta la vittoria richiamando la funzione controllaVittoria. La funzione controllaVittoria verifica se i tasselli sono nell'ordine corretto (da 1 a 15) e, in caso affermativo, imposta la variabile vittoria a true e mostra un messaggio di vittoria attraverso alert.

Per verificare se due tasselli sono adiacenti utilizziamo la funzione adiacente la quale esegue questi controlli

  • const diff = Math.abs(index1 - index2);: Calcola la differenza assoluta tra gli indici index1 e index2. Questo fornisce la distanza tra gli indici sulla griglia.
  • return (diff === 1 && Math.floor(index1 / 4) === Math.floor(index2 / 4)) || (diff === 4);: Restituisce true se la differenza è 1 e gli indici sono sulla stessa riga (lo stesso quoziente quando diviso per 4), o se la differenza è 4 (indicando che gli indici sono sulla stessa colonna). Altrimenti, restituisce false.

Ecco una possibile implementazione del codice JavaScript per il gioco del 15 online:

const buttonMescola = document.getElementById('mescola');
buttonMescola.addEventListener('click', mescola);

const gameContainer = document.getElementById('game-container');
const shuffleButton = document.querySelector('button');

const tasselli = [];
let vittoria = false; 

startGame();

function creaTassello(number) {
    const tassello = document.createElement('div');
    tassello.classList.add('tassello');
    tassello.textContent = number;
    tassello.addEventListener('click', () => muoviTassello(number));
    return tassello;
 }

function startGame() {
    gameContainer.innerHTML = '';
    for (let i = 1; i <= 15; i++) {
         const tassello = creaTassello(i);
         tasselli.push(tassello);
         gameContainer.appendChild(tassello);
    }
    tasselli.push(creaTassello('')); //casella vuota
    gameContainer.appendChild(tasselli[15]);

    mescola();
}

function mescola() {
    for (let i = tasselli.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [tasselli[i], tasselli[j]] = [tasselli[j], tasselli[i]];
    }
    vittoria = false; // Resetta lo stato di vittoria
    modifica();
}

function muoviTassello(number) {
    if (vittoria) return; // Esce se il gioco è già vinto
    const index = tasselli.findIndex(tassello => tassello.textContent == number);
    const emptyIndex = tasselli.findIndex(tassello => tassello.textContent === '');

    if (adiacente(index, emptyIndex)) {
       [tasselli[index], tasselli[emptyIndex]] = [tasselli[emptyIndex], tasselli[index]];
        modifica();
        controllaVittoria(); // Controlla se è stata raggiunta la vittoria
     }
}

function adiacente(index1, index2) {
    const diff = Math.abs(index1 - index2);
    return (diff === 1 && Math.floor(index1 / 4) === Math.floor(index2 / 4)) ||
               (diff === 4);
}

function controllaVittoria() {
    const ordinati = tasselli.slice(0, -1).every((tassello, index) => tassello.textContent == index + 1);
      if (ordinati) {
            vittoria = true;
            alert("Hai vinto!");
      }
 }

function modifica() {
    gameContainer.innerHTML = '';
     tasselli.forEach(tassello => gameContainer.appendChild(tassello));
 }

Algoritmo di mescolamento Fisher-Yates

L'algoritmo di mescolamento Fisher-Yates, noto anche come algoritmo di Knuth o algoritmo di mescolamento casuale, è un algoritmo ampiamente utilizzato per mescolare gli elementi di un array in modo casuale. L'algoritmo è stato proposto da Ronald A. Fisher e Frank Yates nel contesto della statistica, ma è diventato popolare anche nell'informatica per il suo utilizzo nel mescolamento di dati.

L'idea di base dell'algoritmo è di iterare attraverso l'array da sinistra a destra e, ad ogni passo, scambiare l'elemento corrente con un elemento casuale successivo o precedente. Questo processo viene ripetuto per ogni elemento dell'array, garantendo che ogni elemento venga considerato una volta e solo una volta durante il processo di mescolamento.

Ecco ad esempio come l'algoritmo di mescolamento Fisher-Yates può essere implementato in JavaScript:

function mescolaArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        // Genera un indice casuale compreso tra 0 e l'indice corrente
        const j = Math.floor(Math.random() * (i + 1));

        // Scambia gli elementi all'indice corrente e all'indice casuale
        [array[i], array[j]] = [array[j], array[i]];
    }
}

Nel codice sopra, la variabile i rappresenta l'indice corrente mentre l'iterazione avanza da destra a sinistra nell'array. Inizialmente si genera un numero casuale j compreso tra 0 e l'indice corrente i. Successivamente, gli elementi negli indici i e j vengono scambiati utilizzando la tecnica della "destrutturazione" di array.

L'algoritmo garantisce che ogni elemento abbia la stessa probabilità di finire in qualsiasi posizione nell'array, producendo così un mescolamento casuale. È un algoritmo efficiente con complessità temporale O(n), dove n è la lunghezza dell'array.

Conclusione

In questa lezione abbiamo trovato una possibile soluzione al gioco del 15 online in JavaScript, nelle prossime lezioni ci divertiremo a sviluppare tante altre applicazioni.

Alcuni link utili

Sommario tutorial JavaScript

Rimuovere attributi agli elementi del DOM con JavaScript

Creare attributi agli elementi

Dom in javascript

Come creare una galleria di immagini con javascript

Utilizzare gli array in javascript

Come creare una calcolatrice con javascript

Validare un form con javascript

Saper utilizzare il metodo getElementById

Alcuni esempi con javascript alert