file /PuzzleClass/Scacchiera.java
package PuzzleClass;
import java.awt.*;
import java.util.Random;
/* ----------------------------------------------------------------
* La classe Scacchiera è l'astrazione della matrice di numeri ove
avverrà
* il gioco. Essa ha come attributi, tra gli altri, il numero di righe
della
* scacchiera e il numero di colonne. Inoltre la MAPPA
* sarà una matrice di celle.
* ----------------------------------------------------------------
*/
// DEFINIZIONE
public class Scacchiera {
public final int larghezza = 28; // larghezza standard della cella
public final int altezza = 31; // altezza standard della cella
private int NumRig; // Numero di righe della scacchiera
private int NumCol; // Numero di colonne della scacchiera
public Cella[][] Mappa; // La mappa delle celle del gioco
// METODI
// Scacchiera(int, int)
(costruttore)
// Casuale(int riga, long volte)
// Fatto(String fileI[])
// GetNumCol()
// GetNumRig()
// ScambioCelle(int rig1,int
col1,int rig2,int col2)
/*
-----------------------------------------------------------------
* Classe: Scacchiera
* Metodo: Scacchiera (costruttore)
* E' il metodo costruttore della classe Scacchiera.
* Occorre definire il numero di Righe e Colonne della Scacchiera
* ------------------------------------------------------------------
*/
public Scacchiera(int NRig, int NCol) {
NumRig = NRig;
NumCol = NCol;
Mappa = new Cella[NumRig+1][NumCol+1]; // creazione mappa delle celle
// La mappa viene creata con un numero di righe e colonne superiore ad uno
rispetto
// a quelle definite dall'utente all'atto della creazione dell'oggetto.
// Questo perchè i vettori in Java iniziano sempre dalla posizione
0.
// Definendo quindi una matrice di 5 righe e 5 colonne, per esempio, saranno
// disponibili le posizioni [0..4][0..4]. Così definendo la matrice
di 6 righe e
// 6 colonne, si potranno utilizzare le posizioni [0..5][0..5]. In effetti
ai fini
// del gioco saranno utilizzate solo le posizioni [1..5][1..5].
}
/*
--------------------------------------------------------------------------------
* Classe: Scacchiera
* Metodo Casuale(int riga, long volte): Dispone i numeri
in modo casuale a partire
* dalla riga successiva al parametro "riga". La casualità è
determinata dal
* parametro "volte".Utilizza il generatore di numeri casuali
Math.random()
*
--------------------------------------------------------------------------------
*/
public void Casuale(int riga, long volte) {
int Moss = 0;
int x,y;
while (Moss < volte) {
x=1;
y=1+riga;
for (int i = 1+riga; i < 6; i++){
for (int j = 1; j < 6; j++){
if (Mappa[i][j].GetIsnumero() == false) { // trova la cella vuota.....
y = i; // y = riga cella vuota
x = j; } // x = colonna cella vuota
}}
switch ((int) (Math.random()*4)) {
case 0: if (y > 1+riga) {
ScambioCelle(y,x,y-1,x); // scambia la cella [y][x] con [y-1][x]
Moss = Moss + 1;
}
break;
case 1: if (y < 5){
ScambioCelle(y,x,y+1,x); // scambia la cella [y][x] con [y+1][x]
Moss = Moss + 1;
}
break;
case 2: if (x > 1){
ScambioCelle(y,x,y,x-1); // scambia la cella [y][x] con [y][x-1]
Moss = Moss + 1;
}
break;
case 3: if (x < 5){
ScambioCelle(y,x,y,x+1); // scambia la cella [y][x] con [y][x+1]
Moss = Moss + 1;
}
break;
}
}
} // fine metodo Casuale()
/* --------------------------------------------------------------------------
* Classe: Scacchiera
* Metodo Fatto(String fileI[]) : controlla se il gioco
è stato completato con successo
* restituendo in tal caso True, altrimenti False.
* Per determinare ciò confronta i file delle immagini
* ordinate contenute nel vettore fileI passato come parametro
* con i file delle immagini delle celle.
* ---------------------------------------------------------------------------
*/
public boolean Fatto(String fileI[]) {
boolean vinto;
vinto = true;
for (int i = 0; i < 5; i++)
{for (int j = 0; j < 5; j++){
if (Mappa[i+1][j+1].GetNomeFile() != fileI[i*5+j]) {
vinto = false;
}
}}
return vinto;
} // fine del metodo Fatto
/* -----------------------------------------------------------------
* Classe: Scacchiera
* Metodo: GetNumCol()
* Restituisce un intero pari al numero di colonne della Scacchiera.
* ------------------------------------------------------------------
*/
public int GetNumCol() {
return NumCol;
}
/* -----------------------------------------------------------------
* Classe: Scacchiera
* Metodo: GetNumRig()
* Restituisce un intero pari al numero di righe della Scacchiera.
* ------------------------------------------------------------------
*/
public int GetNumRig() {
return NumRig;
}
/* --------------------------------------------------------------------------
* Classe: Scacchiera.
* Metodo: ScambioCelle(int rig1,int col1,int rig2,int
col2) .
* Scambia, di due celle, le immagini, la proprietà "Isnumero" e i
nomi dei files
* contenenti le immagini. La prima cella ha coord. rig1, col1 e la seconda
* ha coordinate rig2, col2 passate come parametri.
* ---------------------------------------------------------------------------
*/
public void ScambioCelle(int rig1,int col1,int rig2,int col2) {
Image temp; // Immagine temporanea usata per lo scambio
boolean Numtemp; // Boolean temporaneo usato per lo scambio dell'attributo
numero
String FileI; // Stringa temporanea per lo scambio dei nomi dei file delle
immagini
// Salva gli attributi della cella [rig1][col1] in variabili temporanee
temp = Mappa[rig1][col1].GetImage();
Numtemp = Mappa[rig1][col1].Isnumero;
FileI = Mappa[rig1][col1].NomeFile;
// Assegna gli attributi della cella [rig2][col2] alla prima cella [rig1][col1]
Mappa[rig1][col1].SetImage(Mappa[rig2][col2].GetImage());
Mappa[rig1][col1].Isnumero = Mappa[rig2][col2].Isnumero;
Mappa[rig1][col1].NomeFile = Mappa[rig2][col2].NomeFile;
// Assegna i valori salvati alla cella [rig2][col2]
Mappa[rig2][col2].SetImage(temp);
Mappa[rig2][col2].Isnumero = Numtemp;
Mappa[rig2][col2].NomeFile = FileI;
}
}
Ecco ora il sorgente del file
/PuzzleClass/Calcolatrice.java
package PuzzleClass;
/**
* ----------------------------------------------------------------------
* Questa classe implementa l'oggetto CALCOLATRICE del gioco.
* Una calcolatrice consente di gestire il punteggio del gioco (incluso le
* penalizzazioni) e tiene traccia del numero di mosse compiute.
* ----------------------------------------------------------------------
*/
// DEFINIZIONE
public class Calcolatrice {
private int Mosse;
private int Punteggio;
// METODI
// Calcolatrice()
(costruttore)
// DecPunteggio(int valore)
// GetMosse()
// GetPunteggio()
// IncMosse()
// IncPunteggio(int valore)
// Reset()
/* -----------------------------------------------------------------
* Classe: Calcolatrice
* Metodo: Calcolatrice (costruttore)
* E' il metodo costruttore della classe Calcolatrice.
* Non occorre passare alcun parametro, il costruttore inizializza
* una nuova calcolatrice con Mosse e Punteggio uguali a zero.
* ------------------------------------------------------------------
*/
public Calcolatrice() {
Mosse = 0;
Punteggio = 0;
}
/* --------------------------------------------------------------------
* Classe: Calcolatrice
* Metodo: DecPunteggio(int valore)
* Diminuisce il punteggio di una quantità pari al parametro "valore".
* --------------------------------------------------------------------
*/
public void DecPunteggio(int valore) {
Punteggio = Punteggio - valore;
}
/* ------------------------------------------------------------------
* Classe: Calcolatrice
* Metodo: GetMosse()
* Restituisce un intero pari al numero di mosse compiute sino a quel
* momento nel gioco.
* ------------------------------------------------------------------
*/
public int GetMosse() {
return Mosse;
}
/* ---------------------------------------------------------------
* Classe: Calcolatrice
* Metodo: GetPunteggio()
* Restituisce un intero pari al punteggio totalizzato sino a quel
* momento nel gioco.
* ---------------------------------------------------------------
*/
public int GetPunteggio() {
return Punteggio;
}
/* ---------------------------------------------------------------
* Classe: Calcolatrice
* Metodo: IncMosse()
* Incrementa il numero di mosse in conseguenza di una mossa fatta.
* ----------------------------------------------------------------
*/
public void IncMosse() {
Mosse = Mosse + 1;
}
/* --------------------------------------------------------------------
* Classe: Calcolatrice
* Metodo: IncPunteggio(int valore)
* Incrementa il punteggio di una quantità pari al parametro "valore".
* --------------------------------------------------------------------
*/
public void IncPunteggio(int valore) {
Punteggio = Punteggio + valore;
}
/* ----------------------------------------------------
* Classe: Calcolatrice
* Metodo: Reset()
* Resetta la Calcolatrice azzerando Mosse e Punteggio.
* ----------------------------------------------------
*/
public void Reset() {
Mosse = 0;
Punteggio = 0;
}
}
Ecco il sorgente del file
/PuzzleClass/Cella.java
package PuzzleClass;
import java.awt.*;
/**
* -------------------------------------------------------------------------
* Questa classe implementa l'oggetto CELLA della scacchiera del gioco.
* Ogni cella contiene un'immagine di un numero o l'immagine della posizione
* libera della scacchiera. Una matrice di celle compone la SCACCHIERA.
* Ogni cella conosce la propria posizione nella scacchiera data dalla
* coppia (col, rig).
* -------------------------------------------------------------------------
*/
// DEFINIZIONE
public class Cella {
private int col; // Numero colonna della cella all'interno della scacchiera
private int rig; // Numero riga della cella all'interno della scacchiera
private Image immagine; // l'immagine da visualizzare nella cella
protected String NomeFile; // Nome del file contenente l'immagine
protected boolean Isnumero; // True l'immagine= numero, altimenti =cella
vuota
// METODI
// Cella (int riga, int colon,boolean
num, Image Imm, String FileIm)
// GetImage()
// GetIsnumero()
// GetNomeFile()
// SetImage(Image newImage)
// SetIsnumero(boolean
b)
/* -----------------------------------------------------------------
* Classe: Cella
* Metodo: Cella (int riga, int colon,boolean num, Image Imm,
String FileIm )
* E' il metodo costruttore della classe Cella.
* Occorre definire le coordninate della cella (riga, colon)
* e se è una cella che contiene l'immagine di un numero (num = true)
* o l'immagine di una cella vuota (num = false) . Occorre definire
anche
* l'immagine e il nome del file dell'immagine.
* ------------------------------------------------------------------
*/
public Cella(int riga, int colon,boolean num, Image Imm, String FileIm )
{
col = colon;
rig = riga;
Isnumero = num;
immagine = Imm;
NomeFile = FileIm;
}
/* -----------------------------------------------------
* Classe: Cella
* Metodo: GetImage()
* Il metodo fornisce l'immagine della cella
* -----------------------------------------------------
*/
public Image GetImage() {
return this.immagine;
}
/* -------------------------------------------------------
* Classe: Cella
* Metodo: GetIsnumero()
* Il metodo restituisce un boolean che indica
* se la cella contiene un numero (true) o la cella vuota
* (false).
* -------------------------------------------------------
*/
public boolean GetIsnumero() {
return Isnumero;
}
/* ----------------------------------------------------------
* Classe: Cella
* Metodo: GetNomeFile()
* Il metodo restituisce una stringa che contiene
* il nome del file contenente l'immagine della cella.
* ----------------------------------------------------------
*/
public String GetNomeFile() {
return NomeFile;
}
/* ---------------------------------------------------------
* Classe: Cella
* Metodo: SetImage(Image newImage)
* Il metodo imposta la nuova immagine della cella al valore
* dell'immagine "newImage" passato come parametro.
* ---------------------------------------------------------
*/
public void SetImage(Image newImage) {
this.immagine = newImage;
}
/* ---------------------------------------------------------
* Classe: Cella
* Metodo: SetIsnumero(boolean b)
* Il metodo imposta l'attributo Isnumero al valore boolean "b"
* passato come parametro.
* ---------------------------------------------------------
*/
public void SetIsnumero(boolean b) {
Isnumero = b;
}
}
Ecco ora il sorgente dell'applet: file
Puzzle.java
import java.awt.Graphics;
import java.awt.Font;
import java.awt.Color;
import java.awt.Button;
import java.awt.Image;
import java.awt.Event;
import java.applet.AudioClip;
import PuzzleClass.Calcolatrice;
import PuzzleClass.Cella;
import PuzzleClass.Scacchiera;
/*
*
------------------------------------------------------------------------------------
* Questa classe implementa l'oggetto principale del gioco
* Essa è una sottoclasse di applet
*
------------------------------------------------------------------------------------
*/
// DEFINIZIONE
public class Puzzle extends java.applet.Applet implements Runnable{
protected Thread runner;
protected AudioClip Mossa; // variabile suono della mossa
protected AudioClip Vittoria; // variabile suono completamento gioco
protected AudioClip RigaOrdinata; // variabile suono della riga ordinata
protected AudioClip Disordine; // variabile suono del rimescolamento dei
numeri
protected Scacchiera TheScac; // la scacchiera del gioco
protected Graphics g;
protected Button bNewGame; // Button (pulsante) "Nuovo Gioco"
protected String fileIm[] = {"uno.gif", "due.gif", "tre.gif", "qua.gif",
"cin.gif", "sei.gif",
"set.gif", "ott.gif", "nov.gif", "die.gif", "und.gif", "dod.gif", "tred.gif",
"quat.gif", "qui.gif", "sed.gif", "dic7.gif", "dic8.gif", "dic9.gif",
"ven.gif", "ven1.gif", "ven2.gif", "ven3.gif", "ven4.gif","bia.gif"};
protected String strFine; // Stringa contenente la scritta "Fine"
protected String strMosse; // Stringa contenente la scritta "Mosse"
protected String strPunti; // Stringa contenente la scritta "Punti"
protected String strAutore; // Stringa contenente il nome dell'autore
protected boolean rig1; // Se true la riga 1 è stata completata,
altrimenti false
protected boolean rig2; // Se true la riga 2 è stata completata,
altrimenti false
protected boolean rig3; // Se true la riga 3 è stata completata,
altrimenti false
protected boolean rig4; // Se true la riga 4 è stata completata,
altrimenti false
protected boolean rig5; // Se true la riga 5 è stata completata,
altrimenti false
protected boolean suonorig1; // Se la riga 1 completata e la musichetta suonata
è true
protected boolean suonorig2; // Se la riga 2 completata e la musichetta suonata
è true
protected boolean suonorig3; // Se la riga 3 completata e la musichetta suonata
è true
protected boolean suonorig4; // Se la riga 4 completata e la musichetta suonata
è true
protected boolean suonorig5; // Se la riga 5 completata e la musichetta suonata
è true
protected boolean fine; // Se true il gioco
è terminato
protected Calcolatrice Calc; // Oggetto calcolatrice del gioco
protected boolean disord; // Se true occorre disordinare i
numeri
// METODI
// action(Event evt, Object
arg)
// beep_riga()
// Controlli()
// Disordine()
// handleEvent(Event evt)
// init()
// keyDown(Event evt, int tasto)
// paint(Graphics g)
// run()
// start()
// stop()
// update(Graphics g)
// waitToDie()
/*-------------------------------------------------------
* Classe: Puzzle
* Metodo: action(Event evt, Object arg)
* gestisce la pressione del pulsante "New Game"
* -------------------------------------------------------
*/
public boolean action(Event evt, Object arg) {
if (evt.target instanceof Button) { // se è stato premuto il pulsante
New Game
stop(); // arresta il
gioco
System.gc();
Vittoria.play(); // emette il bip della vittoria
TheScac.Casuale(0,400); // richiama il metodo per disporre casualmente i
numeri
Disordine.play(); // emette il bip del disordine
repaint(); // ridisegna il gioco
// Esegue ora una serie di inizializzazioni
Calc.Reset(); // resetta la calcolatrice
fine = false; // quando viene impostata a true, il gioco è terminato.....
rig1 = false; // true se la riga corrispondente è stata completata
rig2 = false;
rig3 = false;
rig4 = false;
rig5 = false;
suonorig1 = false;
suonorig2 = false;
suonorig3 = false;
suonorig4 = false;
suonorig5 = false;
disord = false;
start(); // riavvia il gioco
return true;
} else
return false;
}
/*-------------------------------------------------------
* Classe: Puzzle
* Metodo: beep_riga()
* controlla il completamento di una riga del gioco
* ed eventualmente assegna i punteggi.
* -------------------------------------------------------
*/
public void beep_riga() {
int i;
rig1 = true;
i = 0; // riga 1
for (int j = 0; j < 5; j++){
if (TheScac.Mappa[i+1][j+1].GetNomeFile() != fileIm[i*5+j]) {
rig1 = false; }
}
if ((rig1 == true) & (suonorig1 == false)) {
RigaOrdinata.play(); // emette il bip della vittoria
// ora assegna i punti
Calc.IncPunteggio(1000); // assegna 1000 punti per la prima riga completata
suonorig1 = true;
}
rig2 = true;
i = 1; // riga 2
for (int j = 0; j < 5; j++){
// confronta il nome del file della cella con il nomeFile della scacchiera
originaria ordinata
if (TheScac.Mappa[i+1][j+1].GetNomeFile() != fileIm[i*5+j]) {
rig2 = false; }
}
if ((rig2 == true) & (rig1 == true) & (suonorig2 == false)) {
RigaOrdinata.play(); // emette il bip della vittoria
// ora assegna i punti
Calc.IncPunteggio(2000); // assegna 2000 punti per la seconda riga
completata
suonorig2 = true;
}
rig3 = true;
i = 2; // riga 3
for (int j = 0; j < 5; j++){
// confronta il nome del file della cella con il nomeFile della scacchiera
originaria ordinata
if (TheScac.Mappa[i+1][j+1].GetNomeFile() != fileIm[i*5+j]) {
rig3 = false; }
}
if ((rig3 == true) & (rig2 == true) & (rig1 == true) & (suonorig3
== false)) {
RigaOrdinata.play(); // emette il bip della vittoria
Calc.IncPunteggio(3000); // assegna 3000 punti per la terza riga completata
suonorig3 = true;
}
rig4 = true;
i = 3; // riga 4
for (int j = 0; j < 5; j++){
// confronta il nome del file della cella con il nomeFile della scacchiera
originaria ordinata
if (TheScac.Mappa[i+1][j+1].GetNomeFile() != fileIm[i*5+j]) {
rig4 = false; }
}
if ((rig4 == true) & (rig3 == true) & (rig2 == true) & (rig1
== true) & (suonorig4 == false)) {
RigaOrdinata.play(); // emette il bip della vittoria
// ora assegna i punti
Calc.IncPunteggio(4000); // assegna 4000 punti per la quarta riga
completata
suonorig4 = true;
}
rig5 = true;
i = 4; // riga 4
for (int j = 0; j < 5; j++){
// confronta il nome del file della cella con il nomeFile della scacchiera
originaria ordinata
if (TheScac.Mappa[i+1][j+1].GetNomeFile() != fileIm[i*5+j]) {
rig5 = false; }
}
if (TheScac.Fatto(fileIm) == true){ // se il gioco è stato risolto....
RigaOrdinata.play(); // emette il bip della vittoria
// ora assegna i punti
Calc.IncPunteggio(8000); // assegna 8000 punti per la quinta riga
completata
Vittoria.play(); // emette il bip della vittoria finale
stop(); // ferma il gioco
fine = true;
}
if (Calc.GetMosse() == 800){ // se sono state compiute 800 mosse....
Vittoria.play(); // emette il bip della vittoria
stop(); // ferma il gioco
fine = true;
}
}
/*-------------------------------------------------------
* Classe: Puzzle
* Metodo: Controlli()
* controlla se occorre eseguire la penalizzazione del punteggio.
* -------------------------------------------------------
*/
void Controlli() {
// richiama la procedura beep della riga
if (fine == false) {
beep_riga();
}
if (disord == false) {
if ((Calc.GetMosse() >= 80) & ((Calc.GetMosse() % 80) == 0)) {
disord = true;
Calc.DecPunteggio(350); // Penalizzazione di 350 punti
Disordine();
}
}
if ( ((Calc.GetMosse() % 80) != 0) & (disord == true) ) {
disord = false;
}
} // fine metodo
/*-----------------------------------------------------
* Classe: Puzzle
* Metodo: Disordine()
* Determina quale riga del gioco è ordinata.
* ----------------------------------------------------
*/
public void Disordine(){
if (rig1 == false) {
Disordine.play(); // emette il bip del disordine
TheScac.Casuale(0,Calc.GetMosse());
repaint();
} else
if ((rig1 == true) & (rig2 == false)) { // se è ordinata la prima
riga ....
Disordine.play(); // emette il bip del disordine
TheScac.Casuale(1,Calc.GetMosse());
repaint();
} else
if ((rig2 == true) & (rig3 == false)) { // se è ordinata la seconda
riga ....
Disordine.play(); // emette il bip del disordine
TheScac.Casuale(2,Calc.GetMosse());
repaint();
} else
if ((rig3 == true) & (rig4 == false)) { // se è ordinata la terza
riga ....
Disordine.play(); // emette il bip del disordine
TheScac.Casuale(3,Calc.GetMosse());
repaint();
} else
if ((rig4 == true) & (rig5 == false)) { // se è ordinata la quarta
riga ....
Disordine.play(); // emette il bip del disordine
TheScac.Casuale(4,Calc.GetMosse());
repaint();
}
}
/*----------------------------------------------------
* Classe: Puzzle
* Metodo: handleEvent(Event evt)
* gestisce il click del mouse su un numero.
* ---------------------------------------------------
*/
public boolean handleEvent(Event evt) {
int x,y;
if (runner != null) {
if (evt.id == Event.MOUSE_DOWN) {
x = (int)((evt.x + TheScac.larghezza)/TheScac.larghezza); // x = colonna
della cella su cui si è fatto clic
y = (int)((evt.y + TheScac.altezza)/TheScac.altezza); // y = riga della cella
su cui si è fatto clic
if ((x > 0) & (x < 6) & (y > 0) & (y < 6)) {
if (x-1 > 0) {
if (TheScac.Mappa[y][x-1].GetIsnumero() == false) { // cella vuota
TheScac.ScambioCelle(y,x,y,x-1); //scabia la cella [y][x-1] con [y][x]
Calc.IncMosse(); // Incrementa il contatore Mosse
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
} // else
if (y-1 > 0) {
if (TheScac.Mappa[y-1][x].GetIsnumero() == false) {
TheScac.ScambioCelle(y,x,y-1,x); //scabia la cella [y-1][x] con [y][x]
Calc.IncMosse();
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
} // else
if (x+1 < 6) {
if (TheScac.Mappa[y][x+1].GetIsnumero() == false) {
TheScac.ScambioCelle(y,x,y,x+1); //scabia la cella [y][x+1] con [y][x]
Calc.IncMosse();
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
} // else
if (y+1 < 6) {
if (TheScac.Mappa[y+1][x].GetIsnumero() == false) {
TheScac.ScambioCelle(y,x,y+1,x); //scabia la cella [y+1][x] con [y][x]
Calc.IncMosse();
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
}
} // fine primo if
return true;
} else
return super.handleEvent(evt);
} else
return super.handleEvent(evt);
} // fine metodo handleHevent
/*----------------------------------------------------
* Classe: Puzzle
* Metodo: init()
* inizializzazione dell'applet e del gioco.
* ---------------------------------------------------
*/
public void init() {
Color c = new Color(220,220,220); // colori dell'applet
setBackground(c);
Font f = new Font("TimesRoman",Font.BOLD,15); // imposta il carattere
setFont(f);
setLayout(null);
bNewGame = new Button("New game");
add(bNewGame);
bNewGame.reshape(200,30,75,27); // posiziona il pulsante in 200,60 -
larghezza=75, // altezza=27
strFine = "- FINE -";
strMosse = "Mosse: ";
strPunti = "Punti: ";
strAutore = "Author: Francesco Colucci";
TheScac = new Scacchiera(5,5); // crea un'istanza della scacchiera del gioco
Calc = new Calcolatrice(); // crea un'istanza della calcolatrice del gioco
/* ------------------------------------------------------------------
* Inizializziamo ora la scacchiera richiamando per
* ogni sua cella (TheScac.Mappa[i+1][j+1]) il costruttore.
* Le immagini sono inizializzate attraverso la funzione getImage (che
* preleva le immagini dai file i cui nomi sono nel vettore filIm[]) e
* successivamente passate al costruttore.
* -------------------------------------------------------------------
*/
for (int i = 0; i < TheScac.GetNumRig(); i++)
{for (int j = 0; j < TheScac.GetNumCol(); j++){
TheScac.Mappa[i+1][j+1] = new Cella(
i+1,j+1,true,getImage(getCodeBase(),fileIm[i*5+j]),fileIm[i*5+j] );
}}
// per l'ultima immagine (cella vuota) imposta l'attributo numero = false
TheScac.Mappa[TheScac.GetNumRig()][TheScac.GetNumCol()].SetIsnumero(false);
Mossa = getAudioClip(getCodeBase(),"drop.au");
Vittoria = getAudioClip(getCodeBase(),"vittoria.au");
RigaOrdinata = getAudioClip(getCodeBase(),"riga.au");
Disordine = getAudioClip(getCodeBase(),"disordine.au");
fine = false; // quando è settata a true, il gioco è terminato
rig1 = false;
rig2 = false;
rig3 = false;
rig4 = false;
rig5 = false;
suonorig1 = false;
suonorig2 = false;
suonorig3 = false;
suonorig4 = false;
suonorig5 = false;
disord = false;
TheScac.Casuale(0,400); // richima routine della casualità per 400
volte
Disordine.play(); // emette il bip del disordine
}
/*----------------------------------------------------
* Classe: Puzzle
* Metodo: keyDown(Event evt, int tasto)
* gestisce la pressione di un tasto freccia.
* ---------------------------------------------------
*/
public boolean keyDown(Event evt, int tasto) {
int x,y;
if (runner != null) {
x=1;
y=1;
for (int i = 1; i < 6; i++){
for (int j = 1; j < 6; j++){
if (TheScac.Mappa[i][j].GetIsnumero() == false) {
y = i;
x = j; }
}}
switch (tasto) {
case Event.DOWN: if (y > 1) {
TheScac.ScambioCelle(y,x,y-1,x);
Calc.IncMosse();
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
break;
case Event.UP: if (y < 5){
TheScac.ScambioCelle(y,x,y+1,x);
Calc.IncMosse();
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
break;
case Event.RIGHT: if (x > 1){
TheScac.ScambioCelle(y,x,y,x-1);
Calc.IncMosse();
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
break;
case Event.LEFT: if (x < 5){
TheScac.ScambioCelle(y,x,y,x+1);
Calc.IncMosse();
if (Calc.GetMosse() != 0){
Mossa.play(); // emette il bip della mossa
}
Controlli();
repaint();
}
break;
}
if ((tasto == Event.DOWN) | (tasto == Event.UP) | (tasto == Event.RIGHT)
| (tasto == Event.LEFT)) {
return true;
}
else
return false;
} else
return false;
}
/*----------------------------
* Classe: Puzzle
* Metodo: paint(Graphics g)
* disegna il gioco.
* ---------------------------
*/
public void paint(Graphics g) {
int col =0;
int rig =0;
Color Colore = new Color(220,220,220); // colori dell'applet
g.setColor(Colore.red); // colore rosso
// visualizzazione delle immagini
for (int i = 1; i < 6; i++){
for (int j = 1; j < 6; j++)
{g.drawImage(TheScac.Mappa[i][j].GetImage(),col,rig,this);
if (j == 5)
{col = 0;
rig = rig + 31; }
else
col = col + 28;
}}
if (fine == true) {
g.drawString(strFine,200,90); // fine
}
g.drawString(strMosse + String.valueOf(Calc.GetMosse()),15,185); // mosse
.....
if ((Calc.GetPunteggio() - Calc.GetMosse()) > 0) {
g.drawString(strPunti + String.valueOf(Calc.GetPunteggio() -
Calc.GetMosse()),15,205);
} else { // visualiz. punti
g.drawString(strPunti + String.valueOf(0),15,205);
}
g.setColor(Colore.blue); // colore blu
g.drawString(strAutore,35,270);
}
/*----------------------------
* Classe: Puzzle
* Metodo: run()
* ---------------------------
*/
public void run() {
Thread.currentThread().setPriority (Thread.MIN_PRIORITY);
try
{
Thread.sleep (100);
}
catch (InterruptedException e)
{
}
}
/*----------------------------
* Classe: Puzzle
* Metodo: start()
* ---------------------------
*/
public void start() {
if (runner == null) {
runner = new Thread(this);
runner.start();
}
}
/*----------------------------
* Classe: Puzzle
* Metodo: stop()
* ---------------------------
*/
public void stop() {
if (runner != null) {
runner.stop();
runner = null;
}
}
/*----------------------------
* Classe: Puzzle
* Metodo: update(Graphics g)
* ---------------------------
*/
public void update(Graphics g){
g.setColor(getBackground());
g.fillRect(65,170,50,25); // ridisegna in bianco solo lo spazio della scritta
"Mosse"
g.fillRect(55,195,90,25); // ridisegna in bianco solo lo spazio della scritta
"Punti"
if (fine == false) {
g.fillRect(180,80,100,25); // ridisegna in bianco solo lo spazio della scritta
"Fine"
}
g.setColor(getForeground());
paint(g);
}
/*----------------------
* Classe: Puzzle
* Metodo: waitToDie()
* ---------------------
*/
public synchronized void waitToDie ()
{
try
{
wait ();
}
catch (InterruptedException e)
{
}
}
}
Per eseguire l'applet, i file ottenuti dalla
compilazione del package (Scacchiera.class, Calcolatrice.class, Cella.class),
devono essere posizionati nella sottodirectory /PuzzleClass.
Il codice HTML da inserire nella pagina Web che conterrà l'applet
Puzzle può essere il seguente:
<APPLET CODE="Puzzle.class" WIDTH="300" HEIGHT="230" ALT="Usare un browser
che supporti Java...">
Questo gioco, per essere eseguito, richiede l'uso di un browser che supporti
Java </APPLET>
Il file Puzzle.class deve risiedere invece nella stessa
directory della pagina Web.
Questo è tutto. Se non siete annoiati e avete
voglia di fare qualche modifica, potrebbe essere interessante creare un nuovo
gioco, simile a questo, ma organizzato con più livelli di
difficoltà. Per esempio, in un primo livello si potrebbe richiedere
all'utente l'ordinamento di una scacchiera con i numeri da 1 a 15 per
poi accedere ad un livello successivo per ordinare i numeri da
1 a 24.
Spero che questi articoli abbiano offerto qualche interessante spunto di
riflessione per la costruzione di applicazioni object-oriented.