[Risolto]Battaglia navale [c++]

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

[Risolto]Battaglia navale [c++]

Messaggio 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();

}

Ultima modifica di raider91 il martedì 17 giugno 2014, 22:14, modificato 1 volta in totale.
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio da raider91 »

ragazzi nessuno riesce a darmi una mano? :(
Avatar utente
jackynet92
Moderatore Globale
Moderatore Globale
Messaggi: 13413
Iscrizione: sabato 3 settembre 2011, 1:41
Desktop: Mate
Distribuzione: Ubuntu 16.04 64bit
Sesso: Maschile
Località: Torino

Re: Battaglia navale [c++]

Messaggio 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.
ixamit
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 499
Iscrizione: giovedì 14 novembre 2013, 10:16

Re: Battaglia navale [c++]

Messaggio 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));
....
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: Battaglia navale [c++]

Messaggio 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.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio 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.
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: Battaglia navale [c++]

Messaggio 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.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio 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;
}
Dahman
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1013
Iscrizione: mercoledì 31 ottobre 2007, 8:29
Località: Torino

Re: Battaglia navale [c++]

Messaggio 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
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio 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?
ixamit
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 499
Iscrizione: giovedì 14 novembre 2013, 10:16

Re: Battaglia navale [c++]

Messaggio 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.
Dahman
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1013
Iscrizione: mercoledì 31 ottobre 2007, 8:29
Località: Torino

Re: Battaglia navale [c++]

Messaggio 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
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: Battaglia navale [c++]

Messaggio 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.
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio 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?
Dahman
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1013
Iscrizione: mercoledì 31 ottobre 2007, 8:29
Località: Torino

Re: Battaglia navale [c++]

Messaggio 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
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio 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.
Dahman
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1013
Iscrizione: mercoledì 31 ottobre 2007, 8:29
Località: Torino

Re: Battaglia navale [c++]

Messaggio 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
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio 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?
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: Battaglia navale [c++]

Messaggio da vaeVictis »

A parte quanto ti ha suggerito Dahman, quella immagine contiene solamente il carattere pipe ( | ) e il carattere underscore ( _ )
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
raider91
Prode Principiante
Messaggi: 164
Iscrizione: giovedì 28 marzo 2013, 13:09
Desktop: gnome-fallback
Distribuzione: ubuntu 12.04.2 LTS x86_64

Re: Battaglia navale [c++]

Messaggio da raider91 »

Ragazzi sono riuscito a risolvere il problema.Grazie a tutti quelli che mi hanno aiutato.Alla prossima! :ciao:
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 7 ospiti