
Programmare in java: 4. Duello sotto la luna – simulazione animata in console
Introduzione
Nella storia dell’informatica, il gioco è stato più di un passatempo: è stato un esperimento.
Quando nel 1952 il matematico Alexander “Sandy” Douglas creò OXO — una versione elettronica del tris per il computer EDSAC — non cercava intrattenimento, ma un modo per dimostrare l’interazione tra uomo e macchina. Pochi anni dopo, nel 1958, William Higinbotham sviluppò Tennis for Two su un oscilloscopio: due linee, un punto luminoso e un’idea nuova di partecipazione.
Il gioco, da dimostrazione tecnica, divenne linguaggio. Negli anni Sessanta, nei laboratori universitari e nei centri di ricerca, nacquero Spacewar! e i primi prototipi di simulazioni: mondi chiusi governati da regole, in cui il caso era programmato e la vittoria significava comprendere il sistema.
Con la diffusione delle prime console e dei personal computer negli anni Settanta e Ottanta, il videogioco passò dal laboratorio al salotto, trasformandosi da esperimento accademico a forma culturale. Eppure, alla base, restò invariata la sua essenza: una sfida tra ordine e imprevisto, tra algoritmo e intuizione.
Oggi, scrivere un gioco in codice significa ripercorrere quella stessa traiettoria: progettare strutture, simulare mondi, restituire alla macchina la capacità di sorprendere. In fondo, ogni gioco — anche digitale — è una metafora dell’intelligenza stessa: un luogo dove la logica modella, e la mente gioca con sé stessa.
Ogni videogioco, anche il più semplice, è un atto di traduzione — l’idea diviene un linguaggio formale nella forma, e la mente trova nel codice un nuovo spazio per immaginare.
Risultato
Il programma è stato sviluppato in Java con un approccio orientato alla chiarezza logica e alla modularità.
L’architettura si fonda sull’uso estensivo delle interfacce, che costituiscono il punto di contatto tra astrazione e implementazione concreta.
In un linguaggio fortemente tipizzato come Java, le interfacce definiscono un contratto astratto: ogni classe che le implementa è tenuta a fornire le implementazioni concrete dei metodi dichiarati astratti, pur lasciando piena libertà sul comportamento interno. Sul piano più generale, assicurano compatibilità tra tipizzazione e modularità, favorendo l’estendibilità, l’evolvibilità e il controllo semantico.
Nel caso specifico, la scelta di utilizzare l’interfaccia comune per i personaggi consente di sostituire o aggiungere nuove abilità e/o avatar senza alterare il comportamento del sistema. Pur utilizzando nel codice un’unica istanza della classe Abilita, l’approccio permette di introdurre in futuro varianti o comportamenti differenziati per ciascun avatar, senza compromettere la logica esistente.
In modo analogo, l’impiego del costrutto switch con espressioni lambda mostra la capacità del linguaggio di modellare processi condizionali in forma compatta e funzionale.
Tale scelta, oltre a migliorare la leggibilità, traduce in codice l’idea di un sistema dinamico: regole precise che generano comportamenti emergenti e riproducibili. Al contempo, rappresenta l’incontro tra struttura e creatività: un sistema governato dalla logica, ma animato dall’imprevedibilità dell’interazione.
“Un piccolo duello, tra codice e immaginazione, dove la logica si fa gioco e la console diventa teatro.”
Link utili
▶ Esegui il programma su Replit:
- Clicca sul link Apri su Replit per accedere al progetto.
- Se non hai un account Replit, registrati gratuitamente oppure accedi con Google/GitHub.
- Una volta nel progetto, premi “Run” per avviare l’esecuzione.
- Puoi consultare il file sorgente e, se desideri, scaricarlo o copiarlo dal pannello di codice a sinistra.
▶ Requisiti:
- Java JDK 8 o superiore installato (verifica con
java -version). - Console o IDE compatibile con UTF-8.
- Larghezza della finestra console consigliata: almeno 100 caratteri, per evitare interruzioni di riga durante l’animazione e garantire una resa ottimale dei duelli.
▶ Scarica la versione portatile del codice:
- Effettua queste tre semplici operazioni:
- Clicca sul link Scarica File per scaricare il file Main.txt, che contiene il codice sorgente completo in formato .txt.
- Clicca sul link Scarica File per scaricare il file Abilita.txt, che contiene il codice sorgente completo in formato .txt.
- Clicca sul link Scarica File per scaricare il file Animate.txt, che contiene il codice sorgente completo in formato .txt.
- Clicca sul link Scarica File per scaricare il file AvatarsCombat.txt, che contiene il codice sorgente completo in formato .txt.
- Clicca sul link Scarica File per scaricare il file Combat.txt, che contiene il codice sorgente completo in formato .txt.
- Clicca sul link Scarica File per scaricare il file LunaCombat.txt, che contiene il codice sorgente completo in formato .txt.
- Clicca sul link Scarica File per scaricare il file Personaggio.txt, che contiene il codice sorgente completo in formato .txt.
- Rinomina i file cambiando l’estensione da .txt a .java.
- A. Se usi un IDE Java (VS Code, IntelliJ, NetBeans, Eclipse), crea un nuovo progetto java vuoto e aggiungi il package personaggi; poi importa i sette file e avvia la classe Main.java come Java Application.
- B. Se invece vuoi eseguirlo senza IDE, crea una cartella chiamata personaggi e inserisci al suo interno i sette file .java.
- B. Apri il terminale nella cartella che contiene personaggi/ e usa uno dei comandi seguenti:
macOS / Linux :
mkdir -p out && javac -encoding UTF-8 -d out $(find . -name "*.java") && java -Dfile.encoding=UTF-8 -cp out personaggi.Main
Windows (PowerShell):
mkdir out; javac -encoding UTF-8 -d out (Get-ChildItem -Recurse -Filter *.java).FullName; java -Dfile.encoding=UTF-8 -cp out personaggi.Main
Windows (Prompt dei comandi): esegui i comandi uno alla volta (senza ; tra di essi). Esempio:
mkdir out
javac -encoding UTF-8 -d out *.java
java -Dfile.encoding=UTF-8 -cp out personaggi.Main
▶ Utilizzo:
Dopo l’avvio, la console ti guida passo-passo nella simulazione:
- Tuttavia, l’utente può impostare nel Main, per ciascun round, la fase lunare e l’avatar in tre modalità:
- Da codice, modificando i parametri dell’avatar e/o della luna piena (es. “eroe”, “vampiro”, “licantropo” per l’avatar, e “on”, “off” per impostare lo scenario con la luna piena). Questa modalità è utile per test o configurazioni personalizzate già predefinite.
- In modalità interattiva, inserendo la parola “input” nei parametri dell’avatar e/o della luna piena: in questo caso, durante l’esecuzione il programma chiederà in console di digitare i valori tra quelli sopra menzionati.
- In modalità automatica (“auto”) per impostare l’avatar e analogamente impostare lo scenario, in particolare l’avatar e lo scenario vengono scelti casualmente.
- Se in un round i due avatar coincidono, il programma attiva automaticamente la modalità allenamento, permettendo un duello del personaggio con sé stesso.
- In caso di errore dei parametri modificati da codice o input non valido (es. scrivere nomi errati per la scelta dell’avatar o valori diversi da “input” / “auto”/”on” / “off” come sopra descritto), il sistema applica valori di default garantendo comunque l’esecuzione del round. Questo comportamento implementa un principio di resilienza logica: il programma non interrompe mai il flusso, ma si adatta e mantiene sempre una configurazione valida. È una scelta progettuale che:
- mantiene il Main snello e leggibile,
- preserva la modularità del codice,
- e conferisce al sistema un comportamento “intelligente”, tipico delle simulazioni interattive robuste.
Codice
Il progetto è articolato in più classi e interfacce che collaborano secondo ruoli distinti ma complementari.
Personaggio e Abilita gestiscono lo stato e la forza dei combattenti.
Le interfacce LunaCombat e AvatarsCombat aggiungono logiche specifiche di contesto, come la fase lunare o la scelta dell’avatar: modella tre strategie di comportamento diverse, implementate tramite metodi default e statici. Inoltre nel licantropo cambia lo stato iniziale della forza e l’abilità di combattimento a seconda della fase lunare: un piccolo pattern “Observer” naturale — il mondo cambia e il personaggio interagisce con il suo nuovo stato. Cosicché l’animazione in console non è solo un effetto grafico, ma la rappresentazione testuale di un ciclo di vita: la scena si aggiorna, i personaggi reagiscono, e il mondo (la luna) continua a influenzarli.
La classe Combat coordina il flusso principale di gioco e l’interazione con l’utente, mentre Animate estende Combat per la resa visiva, mostrando una breve animazione in console dei combattenti.
Il punto di ingresso del programma, contenuto nel file Main.java, orchestra i round di combattimento richiamando progressivamente le classi e le interfacce descritte, rendendo visibile in console l’evoluzione della simulazione.
La combinazione di queste componenti realizza un sistema polimorfico a livello logico-funzionale, dove il tipo di avatar determina il comportamento e la forza del personaggio, in un ambiente influenzato dallo stato della luna.
Allo stesso modo, la separazione delle responsabilità e la modularità del codice rispecchiano un principio di chiarezza logica: ogni interfaccia e classe opera come parte di un sistema coerente, dove il flusso del gioco si mantiene trasparente, leggibile e adattabile.
In sintesi, l’intero sistema si comporta come un piccolo ecosistema interattivo, in cui logica, animazione e mondo simulato si riflettono a vicenda in un equilibrio dinamico e leggibile.
