Pagina 1 di 1

[Risolto]Battaglia navale [c++]

Inviato: domenica 15 giugno 2014, 19:08
da raider91
Salve a tutti.Come da titolo sto scrivendo un esercizio in c++ che prevede la simulazione del gioco "battaglia navale".L'esercizio deve essere scritto con la tecnica OOP.Devo dire di essere arrivato ad un buon punto solo che ora ho difficoltà nell'inserire le navi.Per capire il mio problema devo giustamente parlare della mia implementazione.Innanzitutto ho creato una classe campo che costruisce il campo di battaglia,cioè la matrice(32x32) costruita in modo dinamico dove andranno posizionate le navi.Dopo di che ho creato la classe player che costruisce il giocatore.Le classi sono le seguenti:

Codice: Seleziona tutto

class campo{

  private:
short val;    //valore della matrice;
  char** matr;

    public:
campo(){val=32;};
void crea_mat();
void stampa_mat();
void ins_nave(short x,short y);
~campo(){};

};


Codice: Seleziona tutto


class player:private campo{

    private:
short num_p;   
vector<string> nome;
bool cont_ini; 

    public:
player(){num_p=0;};
void setta_num_p();
void stampa_nome();
void ins_cord();
~player(){};

};

Il mio problema come detto risiede nell'inserimento delle navi.Si può vedere chiaramente che nella classe player ho costruito un metodo ins_cord() che non fa altro che prendere delle cordinate in input dall'utente.Queste cordinate costituiscono la posizione della componente della nave.Il problema è che non riesco a inserire nessuna componente nelle posizioni specificate in input nella matrice di partenza.All'inizio pensavo che era un problema di eredetarietà.Cioè pensavo che giustamente non potevo modificare i valori della matrice se non l'ereditavo nella classe player.Per questo ho dichiarato la classe player come derivata della classe campo.Nonostante tutto però quando richiamo il metodo ins_nave() della classe campo non succede niente.Il compilatore non da errore,quindi il programma parte,solo che poi si arresta non costruendomi la nave.Mi sapete dire dove sbaglio?

Per maggiore chiarezza posto anche i codici del metodo ins_cord() e del metodo ins_nave():

Codice: Seleziona tutto


void player::ins_cord(){


                          short x=0,y=0;
                    cout<<"\n\nBisogna posizionare la nave di 2 componenti!";
                    for(short i=0;i<2;i++){
                        x=0,y=0;
                        cout<<"\n\nScegli la x della "<<i+1<<" componente della nave: ";
                        fflush(stdin);
                        cin>>x;
                        cout<<"\n\nScegli la y della "<<i+1<<" componente della nave: ";
                        fflush(stdin);
                        cin>>y;
                        ins_nave(x,y);
       }

}

Codice: Seleziona tutto



void campo::ins_nave(short x,short y){

      *(&matr[0][0]+(val-1)*x+y)='4';

       stampa_mat();

}


Re: Battaglia navale [c++]

Inviato: domenica 15 giugno 2014, 23:11
da raider91
ragazzi nessuno riesce a darmi una mano? :(

Re: Battaglia navale [c++]

Inviato: domenica 15 giugno 2014, 23:14
da jackynet92
Ciao, come da regolamento:
Nel caso in cui la richiesta rimanga senza valide risposte l'utente potrà riportarla in evidenza inserendo non più di una volta al giorno una qualsiasi risposta alla discussione stessa oppure usando la funzione del forum «Riporta su» (il cosiddetto «up»).
Non sono passate neanche 24 ore, bisogna portare pazienza.

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 13:54
da ixamit
@raider91
Sinceramente non ho guardato molto del tuo codice anche perché ci sono delle istruzioni che non mi piacciono proprio, tipo la fflush stdin che VA tolta (undefined behavior).
Poi se stai programmando in C++ perché non utilizzi vector per la tua matrice?

Codice: Seleziona tutto

void foo (vector<vector<char> > &matr, unsigned int y, unsigned int x)
{
    matr[y][x]=SIGNED;
}
....
    vector< vector<char> > matr(MAX_Y, vector<char>(MAX_X, EMPTY));
....

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 13:59
da vaeVictis
@ixamit
Non è che se programmi in C++ devi per forza usare un vector di vector.
Diciamo che lo usi se ti serve l'armamentario dei metodi che ti mette a disposizione la classe.
In questo caso io non lo userei.

Detto questo, a me non sembra che il programma sia stato strutturato un gran che bene.
Penso si possa evitare di dover rendere friend la classe, per esempio.

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 14:41
da raider91
vaeVictis [url=http://forum.ubuntu-it.org/viewtopic.php?p=4600048#p4600048][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto: Detto questo, a me non sembra che il programma sia stato strutturato un gran che bene.
Penso si possa evitare di dover rendere friend la classe, per esempio.
tipo?cioè come potrei fare in alternativa?....tieni presente che come ho specificato ho dovuto far derivare la classe player dalla classe campo per richiamare poi il metodo ins_nave() che è della classe campo nella classe ins_cord() che è della classe player.Comunque oltre questo,che sembra più che altro un problema basato sulla scelta di implementazione mi sapresti dire perchè non riesco ad inserire le navi?Cioè il problema è che una volta che inserisco le coordinate e le passo al metodo ins_nave() non riesco a inserire nella matrice,nella posizione delle cordinate scelte in input,la nave.

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 14:46
da vaeVictis
Come in ogni richiesta di supporto, se vuoi che qualcuno ti dica perché qualcosa non funziona, dovresti come minimo postare un esempio minimale di codice che compila e che riproduce il problema.
Altrimenti il lavoro di chi ti deve aiutare supera di gran lunga la disponibilità che si può dare su un forum :)

Pertanto, posta un esempio minimale di codice che compila e riproduce il tuo problema.
Poi su quello si discute.

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 15:06
da raider91
ok fornirò un'esempio minimale di codice che compila.A quelli già presenti aggiungo:

Il main:

Codice: Seleziona tutto


#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<vector>

using namespace std;



int main(){

      campo var; //dichiariamo una variabile per la classe campo;
      player p;

    var.crea_mat();      //creiamo la matrice di gioco;
    var.stampa_mat();     //stampiamo la matrice di gioco;
    p.ins_cord();

    return 0;
}

Il metodo per stampare la matrice della classe campo:

Codice: Seleziona tutto


void campo::stampa_mat(){
     cout<<"\n\n";

    for(short i=0;i<val;i++){
     for(short j=0;j<val;j++){
           cout<<"|"<<matr[i][j];
     }cout<<"\n";
       }cout<<"\n";

}

Il metodo per creare la matrice della classe campo:

Codice: Seleziona tutto

void campo::crea_mat(){

     matr=new char*[val];
    for(short i=0;i<val;i++)
      matr[i]=new char[val];

    //Inizializziamo la matrice a zero;
      for(short i=0;i<val;i++)
        for(short j=0;j<val;j++)
       matr[i][j]=NULL;
}

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 15:57
da Dahman
Cioè il problema è che una volta che inserisco le coordinate e le passo al metodo ins_nave() non riesco a inserire nella matrice,nella posizione delle cordinate scelte in input,la nave.
In realtà ci riesci, ma le stai inserendo in un campo diverso.

L'errore di impostazione delle classi ti ha generato questo problema.
Innazitutto, Player non può derivare da campo, non c'entra niente dal punto di vista logico.
Il player é una entità e Campo é un'altra completamente indipendente.

Tornando al tuo problema:
Da una parte crei una variabile var di tipo campo che rappresenta un campo dove ti aspetti di trovare la nave che piazzerai.
Ovviamente non troverai niente, perché le coordinate inserite precedentemente non sono in questo campo ma nel campo p.

Dopo crei la variabile p come player (che é anche un campo) e chiami la funzione ins_cord legata a p. Stai inserendo le coordinate nel campo che é rappresentato dalla variabile p e non nel campo che hai definito primA.

Ovviamente non troverai niente.

La soluzione sarebbe quella di definire una classe Campo come hai già fatto, una classe Player che non derivi da Campo ma che può accedere alla variabile campo.
Per questo ci sono diverse soluzioni.
Una semplice semplice: definire la funzione di inserimento come

Codice: Seleziona tutto

void player::ins_cord(Campo &c)
....
No so se ci sono altri problemi ma questo é sicuramente quello principale

ciao
dahman

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 18:44
da raider91
Quindi essenzialmente mi conviene,dopo aver eliminato l'eredetarietà,eliminare del tutto il metodo ins_nave() della classe player e modificare direttamente il metodo ins_cord() nel seguente modo:

Codice: Seleziona tutto

void player::ins_cord(campo &matr){

                            short x=0,y=0;
                    cout<<"\n\nBisogna posizionare la nave di 2 componenti!";
                    for(short i=0;i<2;i++){
                        x=0,y=0;
                        cout<<"\n\nScegli la x della "<<i+1<<" componente della nave: ";
                        fflush(stdin);
                        cin>>x;
                        cout<<"\n\nScegli la y della "<<i+1<<" componente della nave: ";
                        fflush(stdin);
                        cin>>y;
                        matr[x][y]='4';
                   
       }

}




In queso modo non solo scelgo in input le cordinate ma inserisco anche direttamente la nave.Nel caso in cui sia questa la soluzione,mi puoi dire gentilmente come faccio a richiamare tale metodo dal main?

Re: Battaglia navale [c++]

Inviato: lunedì 16 giugno 2014, 19:44
da ixamit
vaeVictis ha scritto:@ixamit
Non è che se programmi in C++ devi per forza usare un vector di vector.
Diciamo che lo usi se ti serve l'armamentario dei metodi che ti mette a disposizione la classe.
In questo caso io non lo userei.
Hai ragione, l'allocazione dinamica non serve per una grid da pochi byte.

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 8:39
da Dahman
In queso modo non solo scelgo in input le cordinate ma inserisco anche direttamente la nave.Nel caso in cui sia questa la soluzione,mi puoi dire gentilmente come faccio a richiamare tale metodo dal main?
aggiungendo semplicemente il parametro campo nel main che hai già scritto

Codice: Seleziona tutto

      campo var; //dichiariamo una variabile per la classe campo;
      player p;

    var.crea_mat();      //creiamo la matrice di gioco;
    var.stampa_mat();     //stampiamo la matrice di gioco;
    p.ins_cord(var);
ciao
dahman

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 11:09
da vaeVictis
ixamit [url=http://forum.ubuntu-it.org/viewtopic.php?p=4600275#p4600275][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:
vaeVictis ha scritto:@ixamit
Non è che se programmi in C++ devi per forza usare un vector di vector.
Diciamo che lo usi se ti serve l'armamentario dei metodi che ti mette a disposizione la classe.
In questo caso io non lo userei.
Hai ragione, l'allocazione dinamica non serve per una grid da pochi byte.
No, aspe.
L'allocazione dinamica serve se la dimensione non è nota a priori.
Quello che non serve è tutto il resto dell'implementazione dei vector.

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 11:40
da raider91
Ti ringrazio per la risposta.Ora però ho un'altro problema.Quando provo ad eseguire il compilatore mi segnala un errore nel metodo ins_cord().Precisamente la riga d'errore è la seguente:

Codice: Seleziona tutto


matr[x][y]='4';

L'errore che mi segnala è il seguente:

Codice: Seleziona tutto

error: no match for 'operator[]' (operand types are 'campo' and 'short int')|
Ovviamente il metodo ins_cord() l'ho impostato come avevamo detto precedentemente quindi scrivendo il metodo in questo modo:

Codice: Seleziona tutto

void player::ins_cord(campo &matr){
   ................................................................................
   ................................................................................
   ................................................................................
       
 matr[x][y]='4';
}
Nell'header file,nei metodi player,questa è la sua intestazione:

Codice: Seleziona tutto

void ins_cord(campo &matr);
Inoltre l'ho richiamato nel main sempre per come mi è stato suggerito.Dunque non capisco quest'errore cosa sia e da dove venga fuori.Come posso risolvere?

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 12:10
da Dahman
Inoltre l'ho richiamato nel main sempre per come mi è stato suggerito.Dunque non capisco quest'errore cosa sia e da dove venga fuori.Come posso risolvere?
Confondi l'oggetto campo con la sua matrice e sopratutto penso che non ti sia chiaro il concetto di un oggetto nella programmazione.
quando scrivi
void player::ins_cord(campo &matr){
.....
.....
matr[x][y]='4';
}
Il parametro che tu passi alla funzione é un oggetto di tipo campo e anche se lo chiami matr non é una matrice.

Prova a ripristinare la funzione ins_nave e fai qualcosa del genere, e cambia nome al parametro per non confonderti

Codice: Seleziona tutto

void player::ins_cord(campo &c){
.....
.....
// qui dovresti usare la matrice dell'oggetto c per inserire i dati
// per esempio c.mat[x][y]=...
// ma essendo privata non puoi accederci direttamente
//! quindi usi la funzione publica di campo per poterlo fare
 c.ins_nave(x, y);   // passa all'oggetto campo le coordinate attraverso questa funzione
}
P.S.
Ti sarà un pò difficile proseguire questo programma se non ti sono chiari questi concetti.

ciao
dahman

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 12:51
da raider91
Sei un grande.Grazie al tuo aiuto sono riuscito a capire un concetto un po'ostico che non avevo capito alla perfezione e a risolvere il mio problema.Ora infatti riesco benissimo ad inserire una nave nella posizione che desidero.Un'ultima cosa però vorrei chiarire.Come si può vedere la griglia da me stampata non è il massimo.Infatti questa non è altro che una semplice matrice nxn stampata a video.Vorrei cercare di stampare la matrice mettendo su ogni riga e su ogni colonna i valori da 1 ad n.Sapresti dirmi come posso fare?Inoltre come faccio ad inserire un codice ascii nella posizione della nave.Cioè io per ora quando inserisco una nave marco quella posizione con il valore 4.Questo non è sicuramente il massimo.Come potrei fare ad inserire un valore ascii invece che un valore numerico.Aspetto tue notizie.Grazie ancora di cuore.

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 14:03
da Dahman
come faccio ad inserire un codice ascii nella posizione della nave
se conosci il codice ASCI basta fare un cast per stamparlo
tipo

Codice: Seleziona tutto

int codice_asci = 12;
cout << (char) codice_asci;
per la matrice potresti stampare ogni riga usando le tabulazioni
e poi separare le varie righe con un endl
esempio di una matrice 3x3 riempita col carattere 12

Codice: Seleziona tutto

    int codice_asci = 12;
    int tab = 10;
    for (int riga=0; riga<3; riga++)
    {
        for (int col=0; col<3; col++)
        {
            cout << setw(tab) << (char) codice_asci ; 
        }
        cout << endl;
    }
ciao
dahman

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 17:51
da raider91
Ti ringrazio per la risposta ma per quanto riguarda la struttura del campo non è proprio quello che intendevo.Io intendevo una cosa simile a questa:


[img]
https://www.google.it/search?q=battagli ... 1280%3B720
[/img]

Sapresti dirmi come posso fare a generare una matrice del genere?

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 18:01
da vaeVictis
A parte quanto ti ha suggerito Dahman, quella immagine contiene solamente il carattere pipe ( | ) e il carattere underscore ( _ )

Re: Battaglia navale [c++]

Inviato: martedì 17 giugno 2014, 22:13
da raider91
Ragazzi sono riuscito a risolvere il problema.Grazie a tutti quelli che mi hanno aiutato.Alla prossima! :ciao: