LUAding and Saving

Qualunque programma che si rispetti, e a maggior ragione un gioco, ha necessità di salvare dati in modo tale da recuperarli negli avvii successivi. Il primo metodo che viene in mente consiste nello scrivere i dati in un file che, in fase di caricamento, verrà passato ad un parser per recuperare le informazioni.

Scrivere un parser però è piuttosto impegnativo e necessita di un bel po’ di lavoro. Ma pensiamoci bene. Noi un parser già pronto ce l’abbiamo: LUA! Esattamente! Sfruttiamo Lua come parser per recuperare le informazioni!

-- Base Lua Script for Load/Save

-- Default Value

nome = "NONE"
visite = 0

-- Check if one file exists or not
function file_exists(name)
   local f=io.open(name,"r")
   if f~=nil then io.close(f) return true else return false end
end

function SaveData()
    myfile = io.open("savegame.lua", "w")
    if myfile ~= nil then
        myfile:write("-- Test Lua SaveGame file")
        myfile:write(string.char(10))
        myfile:write(string.char(10))
        myfile:write(string.format("%s%s", "-- File created on: ", os.date()))
        myfile:write(string.char(10))
        myfile:write(string.char(10))
        myfile:write(string.format("%s%s%s", "nome = \"",nome,"\""))
        myfile:write(string.char(10))
        myfile:write(string.format("%s%d", "visite = ",visite))
        myfile:write(string.char(10))
        io.close(myfile)
    end
end
       
function LoadData()
    if file_exists("savegame.lua") then
        dofile("savegame.lua")
    end
end

function Saluti()
    if visite == 0 then
        print("Ciao! E' la prima volta che avvii il programma!")
        print("Dimmi il tuo nome:")
        nome = io.stdin:read()
        visite = 1
    else
        tmp = string.format("%s%s%s","Ciao ", nome, "! Sei tornato!")
        print(tmp)
        tmp = string.format("%s%d", "Il tuo numero di visite e' ", visite)
        print(tmp)
        visite = visite + 1
    end
end

LoadData()
Saluti()
SaveData()

Diamo un occhiata al listato precedente. Cominciamo dalla funzione Saluti. Questa funzione rappresenta ciò che fa il programma: ti saluta e ti ricorda il numero di volte che lo hai avviato. Ovviamente, se è la prima volta che il programma viene avviato vi verrà richiesto il nome.

Ma tutto questo non ci interessa molto. Passiamo al cuore: la funzione SaveData(). Questa funzione è sicuramente la funzione più interessante. Come potete vedere il codice crea un file e lo riempie con del codice Lua valido che rappresenta i dati da salvare. Nel mio caso, ad esempio, il file savegame.lua contiene

-- Test Lua SaveGame file

-- File created on: Thu Jun 23 21:21:08 2011

nome = "Davide Aversa"
visite = 7

In questo semplice caso, in cui le uniche cose da salvare sono il nome e il numero di visite il file darà di sole 4 righe (commenti compresi) ma questo discorso vale anche in generale e per salvataggi di complessità arbitraria! La funzione SaveGame è solitamente lunga e complessa ma piuttosto facile da gestire anche per salvataggi complicati.

Il vantaggio di questa tecnica appare chiarissimo non appena leggiamo la funzione LoadData. Due righe (in realtà basterebbe solo dofile). Non è stupendo? Abbiamo sostituito righe e righe di parser con un solo comando sfruttando il linguaggio stesso: un chiaro esempio di meta-programmazione applicata ad un operazione fondamentale come il salvataggio e la scrittura dei file.

Quando Lua esegue il file savegame automaticamente ingloba tutte le funzioni contenute nel file e, inoltre, questo formato permette agli sviluppatori di agire facilmente sul salvataggio in modo tale da “creare” manualmente salvataggi di situazioni particolari a scopo di debug!

Questo è uno dei metodi di salvataggio dati più facile, efficiente e veloce che io conosca.

Potete provare il programma in questione semplicemente dando

lua loadsave.lua

Buon divertimento e buon salvataggio.

Categorized: C/C++, Lua
Tagged:

4 comments on “LUAding and Saving

  1. Ciao, molto interessante! Questa funzione mi farebbe molto comodo, ma io programmo in Fortran per applicazioni numeriche.

    Sto seguendo con grande interesse i tuoi articoli su Lua, e ho capito che s’interfaccia molto bene con C/C++. Secondo te sarebbe possibile interfacciare Lua (senza troppi grattacapi) con codice Fortran 95/2003 per chiamare le routine computazionalmente dispendiose?

    Grazie per gli articoli! Continua così…

    • Ho appena fatto una prova e ho trovato una soluzione.

      Devi sapere che il fortran si integra praticamente nativamente con il C++. Allora con un semplicissimo passaggio intermedio ho collegato in una decina di righe una funzione Lua con una Fortran. Praticamente il codice C fa solo da tramite fra Lua e il Fortran.

      Poiché la cosa è interessante e lo spazio dei commenti è poco ho deciso di scrivere un articolo su questo. Oggi pomeriggio o domani lo trovi online.

      • Grazie mille! Non vedo l’ora di leggere l’articolo.

        In quanto alla integrazione Fortran-C++ mi sorprendi anche se non ho esperienza diretta con C++. Per usare alcune librerie in C, invece, ti garantisco che mi son dovuto scrivere dei wrappers. Niente di difficilissimo, ma non è certo un’integrazione nativa.

        Ah, grazie anche per la risposta 😉

        • Probabilmente il verso C-in-Fortran è più complicato che Fortran-in-C 😀 Oppure ci sono aspetti che non ho considerato data la mia poca esperienza con Fortran.

          Ma con due righe ho eseguito funzioni Fortran all’interno di codice C (almeno su sistemi Unix-like) quindi non so 😀 Comunque stasera pubblico l’articolo.