Numeri casuali con ActionScript 3.0

0
Share:

In questi giorni sto lavorando ad un programma che, tra le varie funzioni, prevede un generatore di numeri casuali. Di conseguenza, ho pensato di cogliere l’occasione per rispolverare un articolo del mio vecchio blog dedicato all’argomento. Un pretesto per ripassare i miei vecchi appunti, e, allo stesso tempo, condividere queste nozioni di base con chi è alle prime armi. Nel tutorial, analizzerò come estrarre sei numeri per il superenalotto usando Flash CS6.

Il metodo random()

Per generare numeri casuali in ActionScript, si ricorre al metodo random() della classe Math.
Tuttavia, è necessaria una doverosa precisazione: il metodo in questione sfrutta una procedura pseudocausale. In altre parole, poiché il meccanismo di funzionamento è pur sempre il frutto di un algoritmo matematico, non si può parlare di una rigorosa estrazione casuale. Dal punto di vista pratico, bisogna però riconoscere, che i risultati simulano ottimamente la casualità. Detto questo, ripassiamo velocemente come funziona il metodo random() della classe Math. Scrivendo nel primo fotogramma di un documento Flash:

trace(Math.random());

Otterremo nella finestra Output un numero compreso tra 0 e 1. Ad esempio: 0.7350577732548118. Di conseguenza, per poter usare concretamente il metodo, è necessario definire un intervallo numerico diverso. Per esempio, se volessimo calcolare un numero compreso tra 0 e 90, dovremmo moltiplicare l’espressione per quel numero:

trace(Math.random()*90);

Il numero ottenuto potrebbe essere in questo caso 70.04687834903598. Resta però un altro problema: i numeri ottenuti sono razionali, ovvero caratterizzati da una parte intera (prima della virgola), e una parte decimale (posta dopo la virgola). Per poter simulare un’estrazione del supernalotto, è quindi necessario ottenere solo la parte intera.
Per ottenere lo scopo, possiamo ricorrere al metodo round() della classe Math.

trace(Math.round(Math.random()*90));

Il metodo round() approssima per eccesso o per difetto al numero intero più vicino. Di conseguenza, il numero 70.04687834903598 diventerebbe 70.
Tornando al nostro scopo finale, resta un ultimo problema che rende la riga di codice inadatta. Tra i numeri estratti, potrebbe capitare anche il numero 0. Un modo sbrigativo per risolvere la questione potrebbe essere questo:

trace(Math.round(Math.random()*89)+1);

Così facendo, se dovessimo estrarre 0 diventerebbe 1, invece, se il numero estratto dovesse essere 89, otterremmo 90.
Simulare l’estrazione del superenalotto presenta anche altri problemi. Il numero non solo deve essere intero e compreso tra 1 e 90, ma deve essere estratto sei volte senza ripetizioni. Per rimediare, si potrebbe creare un breve script che verifica se il numero casuale è stato già estratto e ripetere l’estrazione fino a quando non si ottiene un numero diverso. Tuttavia, dal mio punto di vista, è molto più comodo lasciar perdere questo approccio “arzigogolato” per intraprendere una strada diversa.

Usare gli array

Cosa faremmo nel mondo reale, se volessimo fare un’estrazione tra amici?
Probabilmente prenderemmo una scatola di cartone, e inseriremmo al suo interno 90 bigliettini di carta numerati (e magari per comodità appallottolati). Scuoteremmo vigorosamente la scatola, e poi, senza guardare, preleveremmo una pallina di carta. Successivamente, scuoteremmo nuovamente la scatola prima di prelevare il secondo numero, e così via, fino ad esaurire le sei estrazioni. In questo modo non correremmo il rischio di pescare un numero 0, perché assente nella scatola. Inoltre, ad ogni estrazione non dovremmo temere eventuali ripetizioni, perché la scatola ad ogni numero estratto, manterrebbe al suo interno solo numeri inediti (ovvero ancora da estrarre).
Passando ad ActionScript 3.0, per simulare la scatola di cartone, useremo un array di numeri compresi tra 1 e 90. Per scuotere la scatola di cartone useremo un metodo personalizzato mirato a miscelare casualmente l’ordine dell’array. Infine per pescare un numero, ci limiteremo ad usare il metodo splice() dopo una buona e opportuna “shakerata”.
Prima di passare al codice vero e proprio, ecco un veloce bignami sugli array e i metodi che useremo.
Senza approfondire troppo la questione, un array è una raccolta di elementi. Una sorta di insieme in cui il programmatore può archiviare di tutto: numeri, stringhe, funzioni o persino altri array. Se per esempio scrivo nel primo fotogramma di Flash:

var mioarray:Array=new Array(23,44,55);
trace(mioarray);
//restituisce 23,44,55

Creo una raccolta di elementi composta da tre numeri che il metodo trace mi mostra separati da delle virgole. La cosa interessante (e molto utile) degli array, consiste nella possibilità di individuarli tramite un indice numerico progressivo. Il primo elemento dell’array può essere individuato con mioarray[0], il secondo con mioarray[1] e il terzo con mioarray[2]. Per esempio, scrivendo questo codice otterremo l’ultimo elemento dell’array.

var mioarray:Array=new Array(23,44,55);
trace(mioarray[2]);
//restituisce 55

Un altro modo per individuare l’ultimo elemento di un array è la proprietà length, la quale ci dice quanti elementi ha un array:

var mioarray:Array=new Array(23,44,55);
var indiceultimo:Number=mioarray.length-1;
// mioarray.length vale 3, sottraendo 1 otterremo l’indice 2
trace(mioarray[indiceultimo]);
// restituisce 55

Infine per concludere la nostra ricetta, ci servono altri due ingredienti: i metodi push() e splice() dell’array. Il primo dei due si limita ad aggiungere un elemento ad un array.

var mioarray:Array=new Array(23,44,55);
mioarray.push(90);
trace(mioarray);
// restituisce 23,44,55,90

In altre parole, scrivendo questo codice, aggiungiamo il numero 90 come ultimo elemento dell’array.
Per quanto riguarda splice(), questo metodo (utilissimo in numerose circostanze), se usato nella sua funzione essenziale, permettere di eliminare uno o più elementi di un array.
Facciamo un esempio:

var mioarray:Array=new Array(23,44,55);
var n:int=mioarray.splice(0,1);
trace(mioarray);
// restituisce 44,55

In questo caso abbiamo dato come primo parametro di splice() l’indice 0, ovvero abbiamo specificato di voler eliminare gli elementi dell’array a partire dal primo elemento. Come secondo parametro di splice() abbiamo scritto 1: così facendo, abbiamo indicato il numero di elementi da eliminare. Di conseguenza, nella finestra output otterremo solo gli ultimi due elementi dell’array iniziale.
Chiariti tutti gli ingredienti, possiamo entrare nel vivo della ricetta.

Un esempio di estrazione casuale in Flash CS6

Apriamo Flash CS6 e nella parte sinistra dello stage, creiamo un campo di testo dinamico multiriga il cui nome di istanza è c_scatola. Nella parte destra creiamo una serie di campi di testo dinamici, chiamati rispettivamente: campo1, campo2, campo3, campo4, campo5, e campo6.
Posizioniamo due pulsanti denominati p1 e p2 nella parte bassa dello stage.
Infine, indichiamo nel pannello proprietà come classe documento Estrazione.
Ecco di seguito il codice di Estrazione.as:

package{
import flash.display.MovieClip;
import flash.text.TextField;
import flash.events.MouseEvent;
public class Estrazione extends MovieClip{
var mioarray:Array=new Array();
var c:int=1;
function Estrazione(){
crea();
p1.addEventListener(MouseEvent.CLICK,ripeti);
p2.addEventListener(MouseEvent.CLICK,scuoti);
}
private function crea():void{
for(var i:int=0;i<90;i++){
mioarray[i]=i+1;
}
c_scatola.text=String(mioarray);
}
private function preleva(suffisso:int):void{
var estratto:int = Math.floor(Math.random()*mioarray.length);
trace(estratto);
this[“campo”+suffisso].text=mioarray.splice(estratto,1);
c_scatola.text=String(mioarray);
}
public function ripeti(event:MouseEvent):void{
if(this[“campo”+c].text!=””){
preleva(c);
c++;
if (c==7){
p1.removeEventListener(MouseEvent.CLICK,ripeti);
}
}
}
public function scuoti(event:MouseEvent):void{
var nuovoarray:Array = new Array();
while (mioarray.length > 0){
var miorandom:int = Math.floor(Math.random()*mioarray.length);
nuovoarray.push(mioarray[miorandom]);
mioarray.splice(miorandom,1);
}
c_scatola.text=String(nuovoarray);
mioarray=nuovoarray;
}
}
}

Vediamo in cosa consistono queste 44 righe di codice. Nella parte iniziale abbiamo importato i pacchetti necessari. In particolar modo l’occorrente per gestire i campi di testo e gli eventi del mouse. Dopo aver dichiarato la classe, abbiamo indicato il nome di un array e una variabile che ci servirà più avanti (mioarray e c). Nella funzione di costruzione compiamo due operazioni:

1) chiamiamo la funzione crea() per aggiungere i numeri nel nostro array.

2) Associamo ai due pulsanti p1 e p2 i metodi ripeti() e scuoti(). Il primo metodo estrae un numero da mioarray e il secondo mescola i vari elementi (la famosa shakerata di cui abbiamo parlato prima).

Il metodo crea(), come si può osservare nel codice, usa un banale ciclo for per popolare l’array e mostrare i numeri (compresi tra 1 e 90) nel campo di testo. Il metodo preleva(), elimina un elemento a caso da mioarry e lo passa ad uno dei campi di testo posti nella parte destra dello stage. Il nome del campo di testo è il frutto di un’espressione che varia in base al valore della variabile suffisso. Se suffisso vale 1 avremo campo1, se vale 3 campo3, e così via. In questo modo evitiamo di specificare un codice per ogni singolo campo dinamico.
Il metodo ripeti() estrae il numero tramite preleva(), e allo stesso tempo, verifica alcune condizioni. In particolare, fa in modo di passare il valore estratto al campo di testo corretto procedendo progressivamente da campo1 fino a campo6. Al primo click passiamo un numero al primo campo, al secondo click passiamo un numero al campo successivo è così via.
Inoltre, quando termina la procedura di estrazione dei sei numeri, disabilita il gestore di evento del pulsante p1.
Per concludere, passiamo al metodo scuoti() il cui compito è quello di mescolare l’ordine degli elementi.
Questo metodo, estrae casualmente un elemento da mioarray per collocarlo in nuovoarray. L’operazione viene ripetuta fino a quando il primo array non è completamente vuoto (grazie al ciclo while). Quando lo svuotamento è completato, nel campo di testo viene visualizzato il nuovo ordinamento del nuovo array. Inoltre gli elementi di nuovoarray vengono ripassati a mioarray affinché quest’ultimo sia pronto per una nuova estrazione.

Share:

Leave a reply

*