Tic Tac Toe (Tris), Tetris, Campo minato
Creare un Gioco con uno Spreadsheet e Google Apps Script
Con i Fogli di Google è possibile creare dei giochi interattivi che ci fanno tornare indietro nel tempo. Il risultato, sicuramente non sempre performante in base alle caratteristiche richieste dal gioco, non ha niente da invidiare alle versioni originali in termini di funzionalità, gestione del punteggio (score) ed usabilità.
Esistono progetti online con cui poter giocare ma che permettono allo stesso tempo di consultare il codice con i quali sono stati realizzati.
Ne cito un paio tra i più noti:
Tetris on Google Sheet, direi che non ha bisogno di presentazioni, Fig. 1:
Carino graficamente, sicuramente da perfezionare (nel caso siano previsti avanzamenti del progetto dallo sviluppatore) in quanto non offre una buona usabilità e, essendo costantemente in runtime, genera l'eccezione relativa al tempo massimo di esecuzione superato dopo il raggiuingimenti dei 6 minuti di gioco (come mostrato in Fig. 1.). Al netto di questo è però uno sviluppo abbastanza complesso che vale la pena essere studiato e che può fornire spunti per altro tipo di sviluppo.
Un altro gioco è Sheet Sweeper, meglio noto come campo minato. Genera un menu nello Spreadsheet dal quale avviare il nuovo gioco e poi in tutto e per tutto paragonabile al noto gioco di Windows, Fig. 2:
Realizzato con un codice più semplice rispetto al precedente ma al tempo stesso non meno interessante da consultare.
Preso dalla voglia di provarci ho messo un tassello anch'io su questo argomento e mi sono concentrato sul più classico dei giochi della mia infanzia, il gioco del Tic Tac Toe (o Tris, come lo chiamavamo).
Sicuramente non complesso nella sua realizzazione rispetto ai precedenti giochi descritti,ad ogni modo con un po' di accortezze ho cercato di renderlo il più possibile usabile.
Gestisce il turno dei giocatori, assegna il punteggio al relativo giocatore in base ad ogni vittoria evidenziando per un attimo la cella aggiornata e avvia in automatico una nuova partita quando la precedente è conclusa (anche in caso di pareggio). Sicuramente migliorabile ma fa quello che serve:
Avendolo realizzato personalmente posso condividere il codice senza alcuna remora:
var winConditions = [[0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]];
var ss = SpreadsheetApp.getActive();
var ss_gridRange = ss.getRange("A1:C3");
var x_side = "X";
var o_side = "O";
var cell_x_win_cnt = "E3";
var cell_o_win_cnt = "F3";
var cell_current_turn = "F1";
function onOpen() {
ss_gridRange.clearContent();
ss.getRange(cell_current_turn).setValue(x_side); // all'apertura del file inizia sempre X
ss.getRange(cell_x_win_cnt+":"+cell_o_win_cnt).setValues([[0,0]]);
}
function onEdit(e) {
if (e) {
var range = e.range;
// Mi assicuro che il range di celle sia quello del gioco
if (range.getColumn() < 4 && range.getRow() < 4) {
// Gestisce il turno del giocatore
var turnRange = ss.getRange(cell_current_turn);
var turn = turnRange.getValue();
// Verifica se la checkbox è stata selezionata
if (range.getValue() == true) {
if(turn == x_side) {
// Inserisce la X nella cella e cambia il turno a O
range.setValue(x_side);
if (winChecker(x_side)) { setWinAndRestart(cell_x_win_cnt); }
turnRange.setValue(o_side);
} else if (turn == o_side) {
// Inserisce la O nella cella e cambia il turno a X
range.setValue(o_side);
if (winChecker(o_side)) { setWinAndRestart(cell_o_win_cnt); }
turnRange.setValue(x_side);
} else {
range.setValue("");
}
}
}
}
}
function winChecker(side) {
var board = ss_gridRange.getValues(); // es, da [[X, , O], [X, O, ], [X, , ]]
// converto in array 1D: es, da [[X, , O], [X, O, ], [X, , ]] a [X, , O, X, O, , X, , ]
var board1Dconvert = [];
var cell_empty = 0;
for(var i = 0; i < board.length; i++) {
board1Dconvert = board1Dconvert.concat(board[i]);
}
// verifico se una condizioni si verifica
for(var i = 0; i < winConditions.length; i++) {
var sum = 0;
var w = winConditions[i];
for(var b = 0; b < w.length; b++) {
if(board1Dconvert[w[b]] === side) {
sum++
}
}
if(sum === 3) {
return true;
}
}
// in caso di pareggio (se non ci sono celle vuote) ripristino la griglia
for(var i = 0; i < board1Dconvert.length; i++) {
if (board1Dconvert[i] == '') { cell_empty = cell_empty + 1; }
}
if (cell_empty == 0) { ss_gridRange.clearContent(); }
return false;
}
function setWinAndRestart(cell) {
var cell_total = ss.getRange(cell);
SpreadsheetApp.flush();
cell_total.setBackground('green');
var cell_total_val = cell_total.getValue();
cell_total.setValue(parseFloat(cell_total_val) + 1);
ss_gridRange.clearContent();
cell_total.setBackground('white');
}
Molto interessante la parte sul controllo del vincitore, effettuata ad ogni turno, con la funzione winChecker, e l'uso dei trigger semplice onOpen() ma soprattutto onEdit(e) sul quale si basa tutto il funzionamento del gioco.
Se avete altre idee o progetti simili lasciate un commento qui sotto!
Puoi trovare molte altre informazioni sulla gestione degli Spreadsheet da Apps Script, e molto altro in più su come utilizzare al meglio questo linguaggio di sviluppo, nel mio libro "Punta in alto con... Google Apps Script":
ACQUISTA ORA IL LIBRO SU AMAZON:
Se sei pronto a diventare un esperto nella programmazione in Google Apps Script non posso fare altro che augurarti una buona lettura e soprattutto... Buon divertimento!
Vorrei riuscire a creare un videogioco 3d con google app script... si può?
Ciao Alessandra,
considerando che è possibile realizzare giochi 3D in JavaScript, puoi eseguire quel codice in uno script di Google Apps Script pubblicato come applicazione web.
Esistono librerie utili come three.js, basata su WebGL (un'API che viene usata per il rendering della grafica 2D e 3D per i Web browser) che semplificano lo sviluppo 3D.