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
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.
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.
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 indiciindex1
eindex2
. Questo fornisce la distanza tra gli indici sulla griglia.return (diff === 1 && Math.floor(index1 / 4) === Math.floor(index2 / 4)) || (diff === 4);
: Restituiscetrue
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, restituiscefalse
.
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
Rimuovere attributi agli elementi del DOM con JavaScript
Creare attributi agli elementi
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
Complimenti il gioco è divertente e funziona benissimo.
Grazie 🙂
Bellissimo, funziona na meraviglia.
Grazie 🙂
Ottimo! Suggerimento: si dovrebbe fare in modo che il gioco sia sempre risolvibile (in metà dei casi lo schema è impossibile)
devo ancora capire molte cose mai viste prima sul corso, oppure mi sono sfuggite, ad esempio “queryselector”