Wikibooks:Sandbox

Wikibooks, manuali e libri di testo liberi.
Jump to navigation Jump to search
Un castello di sabbia

MODIFICA QUESTA PAGINA!

Benvenuti nella sandbox.

Nei parchi giochi, la sandbox è un'area delimitata, dove i bimbi giocano con paletta e secchiello. Analogamente, su Wikibooks la sandbox è una pagina dove si può scrivere liberamente, senza timore di fare danni in questo progetto che stiamo costruendo anche con il tuo contributo. Qui, se vuoi, puoi anche depositare bozze dei tuoi articoli in attesa di salvarli, anche se è più comodo usare per questo scopo le sottopagine della tua pagina utente (in questo modo: Utente:Nomeutente/Sandbox).

Fate qui le vostre prove!
Clicca qui per modificare il contenuto attuale.
Clicca qui per avere spazio bianco dove scrivere (sarà aggiunto in fondo alla pagina).
La sintassi wiki è spiegata alla pagina Aiuto:Markup. Dopo averla letta, se hai ancora un dubbio su come si fa, clicca qui e lascia un messaggio.

Considera che il tuo testo potrebbe non rimanere a lungo in questa pagina, che viene spesso sovrascritta da altri utenti e "ripulita" con una certa regolarità.


Scrivo in questi punto

È necessario inserire il parametro "contenuto" con la lista dei moduli.

È necessario inserire il parametro "contenuto" con la lista dei moduli.

Template:Sommario V: È necessario inserire il parametro "titolo" con il titolo del libro.

È necessario inserire il parametro "contenuto" con la lista dei moduli.

Template:Sommario: È necessario inserire il parametro "titolo" con il titolo del libro.

Esempio.jpg

C++ Game of Life[modifica]

  1. include <iostream>
  2. include <cstdlib>
  3. include <vector>
  4. include <set>
  5. include<ctime>

//Ho usato quasi solo funzioni "void" perché sono mooolto più belle e perché le funzioni "normali" sono sopravvalutate.

using namespace std; /*Ho provato a dare dei nomi a tutte le funzioni e variabili che aiutani la spiegazione di ciò che succede all'interno di tale funzione o a cosa serve tale variabile, molti sono in inglese perché sono più brevi in inglese e perché l'inglese è una lingua più bella.*/

// Osservabile e osservato contemporaneamente :D, gestisce le regole "biologiche" class Casella{ public: //accessibili dall’esterno e in ogni punto del programma.

   enum stato{vuoto=0,pieno}; //Questa è una enumerazioni, essa è esattamente come i tipi fondamentali e composti, un altro "tipo"
   //essa nello specifico tratta solo valori che possono essere assunti da una variabile enumerazione e questi
   //sono ristretti ad un insieme di valori interi costanti, ad ognuno dei quali viene associato un nome.
   typedef std::set<Casella *> Container; //Typedef ha come scopo quello di semplificare la vita, esso infatti,
   //a differenza di una dichiarazione standard troppo fastidiosa, riesce a rendere il codice moooolto più riutilizzabile 
   //tra un'implementazione e un'altra.
   typedef Container::iterator Iterator; 

private: //utilizzabili soltanto all’interno della classe stessa.

   stato stato_;
   int vicini_futuri;
   int vicini;
   Container osservatori;

public:

   Casella( const Casella::stato & s = Casella::vuoto ) //const non ha bisogno di essere spiegato.
   : stato_(s), vicini_futuri(0), vicini(0){}  

   //non copia gli osservatori
   Casella(const Casella& c): vicini(c.vicini),
           vicini_futuri(c.vicini_futuri), stato_(c.stato_){}
   virtual ~Casella(){}  //Virtual è un pò più difficile da spiegare...è anche questa come int, double, typedef, enum un "tipo" di dichiarazione
   //virtual però è diferso dagli altri tipi di dichiarazioni poichè consente di condizionare l’esecuzione del codice 
   //secondo il tipo dell’istanza oggetto cui si fa riferimento. Scusi se non è molto chiaro ma non ho idea di come spiegarlo...
    
   // Registra gli osservatori a cui notificare i cambiamenti
   inline void Registra(Casella& c) { //Riguardo ad "inline" non sono ancora sicuro cosa faccia, ma credo aumenti le prestazioni...
       //ma ripeto che non sono sicurissimo su questo fatto, scusi se non sono ferrato ma me l'ha consigliato di usare un amico.
       if (&c != this){ //this identifica un puntatore speciale che contiene l’indirizzo dell’istanza della classe 
       //che ha invocato il metodo.
           osservatori.insert(&c);
       }
   } 
 

   inline void Imposta(const Casella::stato& s){
   	stato_=s;
   }

   inline void Muori(){
   	if(stato_==pieno){
       Imposta(Casella::vuoto);
       Notifica(-1);//Utile per la notifica, vedi dopo.
   	}
   }


   inline void Nasci() {
   	if (stato_==vuoto){
       Imposta(Casella::pieno);
       Notifica(1);//Utile per la notifica, vedi dopo.
       }
   } 
    
   // Aggiorna 
   inline void Ciclo() {
      vicini=vicini_futuri;
   }

   // Regole del gioco
   inline void Verifica() {
       if (stato_==pieno){
       	if (vicini<2 || vicini>3) // Modificare questa riga per cambiare le regole di morte
           	Muori();
       }else {
           if (vicini==3) // Modificare questa riga per cambiare le regole di nascita
              Nasci();
	   }
   } 
 
   inline bool Leggi() const{
       return stato_==pieno;
   }


private:

   // Notifica ai vicini nascita o morte
   inline void Notifica(int msg) const{
       for (Iterator it = osservatori.begin(); it != osservatori.end(); ++it){ //A fare sta parte ci ho messo 2 giorni.
           (*it)->RiceviNotifica(msg);//Per questa infatti mi sono dovuto studiare una libreria intera.
       }
   }
    
    // Ricevi la notifica dai vicini
   inline void RiceviNotifica(int msg) {
       vicini_futuri += msg; //Stessa cosa per sta dannata parte
   }
}; 

// Contenitore di caselle, che genera automaticamente le corrispondenze tra vicini. // Gestisce le regole "topologiche" --> termine preso da wikipedia class Griglia{ public:

   typedef std::vector<Casella> Container;
   typedef Container::iterator Iterator;

private: //utilizzabili soltanto all’interno della classe stessa.

   int righe_;
   int colonne_;
   int time;
   Container griglia;

public: //accessibili dall’esterno e in ogni punto del programma.

   virtual ~Griglia(){}
    
   Griglia(const int& righe, const int& colonne)
   :righe_(righe), colonne_(colonne)    {
      if (righe_ < 5) righe_=5;
      if (colonne_ < 5) righe_=5;
      griglia.reserve(righe_*colonne_);
      griglia.resize(righe_*colonne_);
   }
   
   inline Casella& operator[](const int n) {
      return griglia[n];
   }
   
   inline void Cicla() {    
      for (int i = 0; i < righe_*colonne_;++i)
          griglia[i].Ciclo();
   }

   void Verifica(){
       for (int i = 0; i < righe_*colonne_;++i)
          griglia[i].Verifica();
    }

   inline void Imposta (const int& pos) {
       if ((pos >=0)&&(pos < griglia.size()))     	  
          griglia[pos].Nasci();
    }

   inline void Resetta (const int& pos) {
       if ((pos >=0)&&(pos < griglia.size()))	  
          griglia[pos].Muori();
    }
    

   // Modificare questa per cambiare le regole topologiche di vicinanza
   inline void Genera(){ //Scusi se questa parte è un poco incasinata ma non avevo trovato modi per scrivere più "ristretto" 
   //e comunque in un modo "chiaro e capibile".
       bool primo, ultimo;
       for (int indice=0; indice< righe_*colonne_;++indice){
       	primo = ( (indice%colonne_) == 0);
           ultimo = ( (indice%colonne_) == colonne_-1);

        	if (indice > colonne_){      
          		if (!primo)
             		griglia[indice].Registra(griglia[indice-colonne_ - 1]);
          		griglia[indice].Registra(griglia[indice-colonne_]);
           if (!ultimo)
             	griglia[indice].Registra(griglia[indice-colonne_ + 1]);
       }
        
       if (!primo)
          griglia[indice].Registra(griglia[indice-1]);
       if (!ultimo)
          griglia[indice].Registra(griglia[indice+1]);
   
       if (indice < ((colonne_)*(righe_-1)) ){
       	if (!ultimo)
            	griglia[indice].Registra(griglia[indice+colonne_+1]);
          	griglia[indice].Registra(griglia[indice+colonne_]);      
          	if (!primo)
            	griglia[indice].Registra(griglia[indice+colonne_-1]);
       	}	 
       } 
   }

   inline const int Righe() const { return righe_; }
   inline const int Colonne() const { return colonne_; }

};


//Stampa a schermo la griglia. Gestione !statica! delle dimensioni. Per variare, utilizzare griglia.Righe() e Colonne() void Stampa( Griglia& g) {

   cout << "\n\n"; //ne abbiamo messi 2 per bellezza
   cout << "+--------------------+\n|";
   for (int indice=0;indice < 400;++indice){ //Caratteri.
    	bool ultimo = ( (indice%20) == 19);
    	g[indice].Leggi()?cout << "O":cout << " ";
    	if (ultimo){
      		if (indice !=399)
        	{cout << "|\n|";}
      		else
        	{cout << "|\n";}
    	}
   }
   cout << "+--------------------+\n"; 
}


int main () {

   Griglia griglia(20,20); 
   griglia.Genera();

   // Inizializza la griglia casualmente, con fattore di 
   // riempimento un ottavo.
   // Gestione !statica! delle dimensioni. Per variare, utilizzare griglia.Righe() e Colonne()
   srand(time(0));
   for (int i=0; i < 100;++i){
    	griglia.Imposta((rand()>>4) %400);
   }

  	while (1){
    	Stampa(griglia);   
    	griglia.Cicla();   
    	griglia.Verifica();
    	// Aspetta la pressione di enter
    	cin.get(); //Comando che è stra utile poichè registra la pressione del tasto, e quindi è stra utile.
  }
  	// Mai raggiunto
  	return 0;

}