Un modello comune nella programmazione è la creazione di una rappresentazione dei dati di un concetto, ad esempio i comandi del personaggio che è possibile passare e trattare come dati all'interno del codice. In questo minigioco, i comandi devono essere trattati come dati da generare dall'interazione UI e passare al personaggio da eseguire.
In questo progetto, un comando è rappresentato come una classe abstract e ogni comando specifico è una sottoclasse di questa classe command ad esempio forward_command e turnright_command. L'utilizzo di una classe astratta per il comando significa che gli unici comandi validi sono le sottoclassi che non sono astratte. Se si tenta di creare direttamente un'istanza della classe command, si otterrà un errore quando si tenta di compilare il codice.
Poiché i comandi del personaggio sono sottoclassi della classe command, è possibile utilizzarli ovunque sia prevista la classe command, ad esempio la funzione ExecuteCommand() del personaggio nello step precedente. Il primo parametro in ExecuteCommand() prevede il tipo di comando, il che significa che è possibile utilizzare un'istanza di una sottoclasse command come argomento senza problemi.
Ogni sottoclasse fornisce la propria implementazione di DebugString() in modo che quando si stampa un valore di comando sia associato al testo corretto, ma è possibile aggiungere ulteriori differenze alle classi, se necessario.
Queste classi hanno anche lo specificatore univoco per confrontare le istanze delle classi. Questo specificatore li rende paragonabili.
Le classi hanno anche lo specificatore calcolo in modo da poterne creare istanze nell'ambito del modulo (direttamente nel modulo Commands. Ciò significa che è possibile creare una singola istanza univoca per rappresentare ogni comando, ad esempio Commands.Forward per il comando forward.
In questo esempio vengono utilizzate istanze di sottoclassi di comandi anziché il tipo enum per aggiungere altri comandi in un secondo momento creando altre sottoclassi. Con un tipo enum, non è possibile modificarlo o aggiungere altri valori all'enum dopo la versione pubblicata iniziale del progetto, quindi il tipo enum è migliore quando non si prevede che i dati cambino dopo la pubblicazione del progetto.
Di seguito è riportato il codice completo per l'implementazione del comando.
# This file contains the data representation of all the commands that the NPC can receive
# and utilities for the data to help with debugging and troubleshooting issues.
# Each type of command that the NPC can perform will be an instance of this class.
# The class has the unique specifier to make instances of the class comparable.
# The class has the computes specifier to be able to instantiate it at module-scope.
# The class has the abstract specifier so it cannot be instantiated directly, and
# requires subclasses to implement any non-initialized functions, like DebugString().
command := class<computes><unique><abstract>:
DebugString():string
Step successivo
Abbiamo definito i comandi e mostrato come aggiungerne quanti ne vuoi.
Nello step successivo viene illustrato come vengono utilizzati questi comandi nella UI e come aggiungere una UI personalizzata per il controllo del carattere.