wxWidgets

Gioco della Tombola

Si genera un'urna contenente 90 numeri, si disegna il tabellone, si estrae, a caso, un numero dall'urna e lo si disegna sul tabellone. Ad ogni estrazione si controlla se si è formata una delle combinazioni valide: Ambo, Terno, …

avviare un nuovo progetto wxDev-C++ basato su wxWidgets Frame. Salvare il progetto con il nome Tombola

Sul frame inserire:

Nuove proprietà della classe TombolaFrm.

Aprire la scheda TombolaFrm.h, raggiungere la dichiarazione della classe ed aggiungere una sezione private.

Nella sezione private dichiarare le proprietà della classe:


class TombolaFrm : public wxFrame
{
    private:
        int Urna[90], NrDentro, punteggi[18];
        int prossVinc;
	private:
		DECLARE_EVENT_TABLE();

Mescolare i numeri.

Passare alla scheda TombolaFrm.cpp.

Posizionarsi alla fine della funzione CreateGUIControls() ed aggiunegere le seguenti righe:


  ////GUI Items Creation End
  
  // creazione dei 90 numeri
  for (int i=0; i<90; i++) Urna[i] = i+1;
	
  // evitare che i numeri casuali si ripetano
  // ad ogni lancio del programma
  srand(time(NULL));
  
  // mescola i 90 numeri nell'urna
  int caso, tmp;
  for (int i=89; i>1; i--) {
    caso = rand()%i;
    tmp = Urna[caso];
    Urna[caso] = Urna[i];
    Urna[i] = tmp;
  }

  // inizializza le altre proprietà della classe
  NrDentro=90;
  for (int i=0; i<18; i++) punteggi[i]=0;
  prossVinc=0;

}

L'algoritmo per mescolare i numeri opera togliendo in ciclo un numero a caso dall'urna e scambiando la sua posizione con quello che occupa l'ultima posizione. Ad ogni ciclo l'intervallo dei numeri si riduce di 1, per non spostare gli elementi estratti.

Disegnare il tabellone.

Selezionare la scheda TombolaFrm.wxForm. Nella scheda delle proprietà selezionare il frame. Passare alla scheda Eventi e fare clic sulla riga onPaint. Aggiungere un gestore di evento e cmpletarlo come segue:

  wxClientDC dc( WxPanel1 );
  Tabellone(dc);

Posizionarsi prima del gestore di evento ed aggiungere la definizione della funzione Tabellone:

  void Tabellone(wxDC &dc) {  
    dc.SetPen(wxPen(*wxBLACK, 2, wxSOLID));
    dc.SetTextForeground(*wxBLACK);
    int x, y, num;
    wxString numS;
    for (y=10, num=1; y< 180; y+=20) {
      for (x=10; x<200; x+=20, num++) {
        numS.Printf(_("%d"), num);
        dc.DrawText(numS, x, y);
      }
    }
}

Osservare la prima espressione del primo ciclo for: for (y=10, num=1; y< 180; y+=20)
In C la virgola (come in una dichiarazione) assume il significato di Operatore Elenco, ovvero consente di specificare un elenco di assegnazioni. In questo caso si specifica che prima di iniziare il ciclo bisogna assegnare il valore a due variabiliy e num.

Il secondo ciclo for: for (x=10; x<200; x+=20, num++)
prima di ripetere il ciclo esegue due operazioni: incrementa x di 20 e incrementa num di 1.

Ad ogni ciclo viene stampato un numero distante 20 pixel dal precedente.

Estrazione

Associare il gestore al pulsante Estrai:

	// insert your code here
	if (NrDentro<1) return;
	int caso, x, y, riga;
	wxString numS;

    // prima conta quanti numeri sono rimasti 
    // e poi estrae un numero dall'urna
	caso = Urna[--NrDentro];
	
	// calcola la posizione sul tabellone
	y = (caso-1)/10;
	x = (caso-1)%10;

    // disegna un cerchio con bordo rosso e interno rosa
	wxClientDC dc( WxPanel1 );
	dc.SetPen(wxPen(*wxRED, 2, wxSOLID));
    dc.SetBrush(wxBrush(wxColour(234, 200, 206), wxSOLID));
    dc.DrawCircle(x*20+15, y*20+15, 10);
    
    // all'interno del cerchio riscrive il numero
    numS.Printf(_("%d"), caso);
    dc.SetTextForeground(*wxRED);
    dc.DrawText(numS, x*20+10, y*20+10);
    
    // controlla punteggio
    // calcola la riga in cui si trova il numero estratto
    // considerando che in ogni riga ci siano 5 numeri
    riga = (caso-1) / 5;
    
    // conta quanti numeri sono stati già collocati su quella riga
    ++punteggi[riga];
    
    // se si è ottenuta una combinazione vincente la si segnala
    // e si passa in attesa della prossima combinazione
    if (punteggi[riga]==2 && prossVinc==0) {
        WxMemo1->AppendText(_("\nAmbo"));
        prossVinc++;
    }
    if (punteggi[riga]==3 && prossVinc==1) {
        WxMemo1->AppendText(_("\nTerno"));
        prossVinc++;
    }
    if (punteggi[riga]==4 && prossVinc==2) {
        WxMemo1->AppendText(_("\nQuaterna"));
        prossVinc++;
    }
    if (punteggi[riga]==5 && prossVinc==3) {
        WxMemo1->AppendText(_("\nCinquina"));
        prossVinc++;
    }
    
    // per verificare la tombola si considera che
    // in ogni sottocartella ci devono stare 15 numeri.
    if (prossVinc==4) {
        for(int i=0; i<18; i+=3)
          if ((punteggi[i]+punteggi[i+1]+punteggi[i+2])==15) {
            WxMemo1->AppendText(_("\nTombola"));
            // fermare il gioco e proporre nuova partita
          }
    }

    // si stampa la quantità di numeri estratti.
    numS.Printf(_("Estratti %d numeri"), 90-NrDentro);
    WxStaticText1->SetLabel(numS);

Esercizi.

Disegnare una griglia sul tabellone, segnando con una linea doppia le sottocartelle.

Aggiungere un componente wxMemo in cui segnare i numeri che di volta in volta vengono estratti.