Muovere un elemento in una griglia

di il
1 risposte

Muovere un elemento in una griglia

Ho modificato un programma trovato sul web che si chiama Il gioco della vita che forse alcuni di voi conosceranno.
#include <iostream>
 #include <cstdlib>
 #include <vector>
 #include <set> 
 
 using std::cout;
 using std::cin;
 using std::dec;
 using std::hex;
 

 class Casella{
 public:

     enum stato{vuoto=0,pienoA,pienoB}; 	
     typedef std::set<Casella *> Container;
     typedef Container::iterator Iterator; 
 private:
     stato stato_;
     int vicini_futuri;
     int vicini;
     Container osservatori;
 
 public:
     Casella( const Casella::stato& s = Casella::vuoto ) 
      : stato_(s), vicini_futuri(0), vicini(0){}  
 
     Casella(const Casella& c): vicini(c.vicini),
             vicini_futuri(c.vicini_futuri), stato_(c.stato_){}
     virtual ~Casella(){}  

     inline void Registra(Casella& c) {
         if (&c != this){
                osservatori.insert(&c);
         }
     } 
 
 
     inline void Imposta(const Casella::stato& s){
        stato_=s;
     }
     
       inline void MuoriA(){
       if(stato_==pienoA){
        Imposta(Casella::vuoto);
        Notifica(-1);
       }
     }
 
       inline void MuoriB(){
       if(stato_==pienoB){
        Imposta(Casella::vuoto);
        Notifica(-1);
       }
     }
 
     inline void NasciA() {
        if (stato_==vuoto){
         Imposta(Casella::pienoA);
         Notifica(1);
        }
     } 
     
     inline void NasciB() {
        if (stato_==vuoto){
         Imposta(Casella::pienoB);
         Notifica(1);
        }
     } 
 
     
     inline void Ciclo() {
       vicini=vicini_futuri;
     }
 
   
     inline void Verifica() {
         if (stato_==pienoB){
            if (vicini<2 || vicini>3) 
               MuoriB();
         }else {
            if (vicini==3) 
               NasciB();
           }
    
         if (stato_==pienoA){
            if (vicini<1 || vicini>2) 
               MuoriA();
         else {
            if (vicini==2) 
               NasciA();
           }
     } 
     }

     inline bool LeggiA() const{
         return stato_==pienoA;
     }
     
     inline bool LeggiB() const{
         return stato_==pienoB;
     }
 
 
 private:

     inline void Notifica(int msg) const{
         for (Iterator it = osservatori.begin(); it != osservatori.end(); ++it){
             (*it)->RiceviNotifica(msg);
         }
     }
 
     inline void RiceviNotifica(int msg) {
         vicini_futuri += msg;//equivale a vicini_futuri=vicini_futuri + msg
     }
 }; 
 
 class Griglia{
 public:
     typedef std::vector<Casella> Container;
     typedef Container::iterator Iterator;
 
 private:
     int righe_;
     int colonne_;
     Container griglia;
 
 public:
     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) { //'operator' Returns a reference to the element at position n in the vector container
       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 ImpostaB (const int& pos) {
         if ((pos >=0)&&(pos < griglia.size()))           
           griglia[pos].NasciB();
     }
      inline void ImpostaA (const int& pos) {
         if ((pos >=0)&&(pos < griglia.size()))           
           griglia[pos].NasciA();
     }
     inline void ResettaA (const int& pos) {
         if ((pos >=0)&&(pos < griglia.size()))   
           griglia[pos].MuoriA();
     }
     
     inline void ResettaB (const int& pos) {
         if ((pos >=0)&&(pos < griglia.size()))   
           griglia[pos].MuoriB();
     }
 
     inline void Genera(){
       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_; }
 }; 
 
 
 
 void Stampa( Griglia& g) {
      
   cout << "\n\n";
   cout << "--------------------\n|";
   for (int indice=0;indice < 200;++indice){//arriva fino a 400 perchè la matrice è 20x20
     bool ultimo = ( (indice%10) == 9);//come detto prima ultimo è 19 se ho 20 colonne, indice%20 fa la divisione con il resto tra indice e 20
     g[indice].LeggiB()?cout << "B":cout << " "; 
     g[indice].LeggiA()?cout << "A":cout << " ";//stampa O
     if (ultimo){
       if (indice !=199)
         {cout << "|\n|";}
       else
         {cout << "|\n";}
         }
       
     
     
     }
   
   cout << "--------------------\n";
 }


 
 
 int main () {
   Griglia griglia(20,20) ;
   griglia.Genera();
 
  
   srand(time(0));
   for (int i=0; i < 100;++i){
     griglia.ImpostaB((rand()>>2) %200);
     griglia.ImpostaA((rand()>>2) %200);
   }
  
   while (1){
     Stampa(griglia);   
     griglia.Cicla();   
     griglia.Verifica();
     
     cin.get();
   }
   return 0;
}
Ora, come prima cosa vorrei avere una conferma, ovvero se la funzione "Genera", genera effettivamente gli 8 vicini di una determinata casella nelle 8 posizioni: indice-colonne-1,indice-colonne, indice-colonne+1, indice-1, indice+1, indice+colonne+1, indice+colonne, indice+colonne-1.

Poi il problema più grande per me, sta nel fatto che vorrei creare un terzo stato, pienoC, il quale sia in grado di muoversi nella griglia seguendo un certo criterio, per esempio quello di controllare se la casella sotto di lui sia vuota e in caso positivo trasferircisi. Al di la della creazione delle varie funzioni NasciC MuoriC ecc ecc non capisco come posso nominargli la casella che ha sotto.
potete aiutarmi? Se ho sbagliato qualcosa nella pubblicazione di questo post perdonatemi ma è la prima volta che scrivo su un forum di programmazione.

Grazie

1 Risposte

Devi accedere o registrarti per scrivere nel forum
1 risposte