PDA

Visualizza la versione completa : Muovere un elemento in una griglia c++


caciucco
14-10-2013, 15:04
#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_; }
};

caciucco
14-10-2013, 15:07
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;
}


scusate ma non bastavano i caratteri, ho modificato un programma trovato sul web che si chiama Il gioco della vita che forse alcuni di voi conosceranno.
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

Loading