[C++] Battaglia Navale
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
[C++] Battaglia Navale
Faccio un esempio. Io ho una matrice 10x10, con dei valori tra 0 e 2 inseriti dall'utente. Il programma chiede di inserire numero di riga e di colonna per i valori che vogliono essere modificati, ad esempio 5,4 e copia il valore in un vettore di una certa lunghezza; poi il programma chiede all'utente di inserire nuovamente riga e colonna di un valore qualsiasi che si vuole modificare nella matrice, se inserisco di nuovo 5,4 e modifico il valore vorrei che il valore venisse modificato anche nel vettore. Le due operazioni (modifica e copia nel vettore, nuova modifica) vengono fatte da due funzioni diverse. Io ho provato con i puntatori però mi viene un casino, quando compilo mi viene un errore strano dove mi si dice di usare cast ma non ho idea di come si faccia e mi sa di qualcosa che mi incasina il programma. Qualcuno potrebbe aiutarmi? Magari mi sono incasinato la vita da solo, però non riesco ad uscirne
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
Puoi usare le reference_wrapper del C++11:
Codice: Seleziona tutto
#include <iostream>
#include <functional>
#include <vector>
int main ()
{
// creo e stampo vettore
std::vector<int> v (5, 1);
std::cout << "v = ";
for (auto& i : v)
{
std::cout << i << " ";
}
std::cout << std::endl;
// creo e stampo vettore di referenze
std::vector<std::reference_wrapper<int>> v2;
v2.push_back (v[1]);
std::cout << "v2 = ";
for (auto& i : v2)
{
std::cout << i << " ";
}
std::cout << std::endl;
// modifico e stampo vettore originale
v[1] = 5;
for (auto& i : v)
{
std::cout << i << " ";
}
std::cout << std::endl;
// stampo vettore di referenze
std::cout << "v2 = ";
for (auto& i : v2)
{
std::cout << i << " ";
}
std::cout << std::endl;
return 0;
}
Se invece vuoi attenerti al vecchio standard, devi usare i puntatori. Quindi posta quello che avevi fatto (o ancora meglio: un esempio minimale e compilabile che riproduca il problema), dicci l'errore che hai e vediamo cosa c'è che non va
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
Codice: Seleziona tutto
void inserisci (int m[max_size][max_size],int r,int c,int k,int cg[max_size],int n) {
m[r][c] = k;
cg[n] = m[r][c];
}
Codice: Seleziona tutto
void turno (int m[max_size][max_size],int k,int cg[max_size],int csg,int ctg,int cig,int cpg,int totg,int r,int c) {
if (m[r][c] == k) {
cout << " Nave Colpita! ";
m[r][c] = 0;
}
else
cout << " Colpo in Mare ";
for (int i = 1;i<=4;i++) {
if (cg[i] == 0) {
while (csg != 0)
csg = csg - 1;
}
}
for (int i = 5;i<=10;i++) {
if (cg[i] == 0) {
while (ctg != 0)
ctg = ctg - 1;
}
}
for (int i = 11;i<=16;i++) {
if (cg[i] == 0) {
while (cig != 0)
cig = cig - 1;
}
}
for (int i = 17;i<=20;i++) {
if (cg[i] == 0) {
while (cpg != 0)
cpg = cpg - 1;
}
}
totg = csg+ctg+cig+cpg;
}
nel main i turni di gioco sono implementati come segue:
Codice: Seleziona tutto
while (tot1 || tot2 == 0) {
cout << " Turno del giocatore " << player1 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia2,2,c2,cs2,ct2,ci2,cp2,tot2,r,c);
cout << " Turno del giocatore " << player2 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia1,1,c1,cs1,ct1,ci1,cp1,tot1,r,c);
}
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
Non devi definire il vettore come puntatore alla matrice ma gli elementi del vettore come puntatori agli elementi della matrice:Hoiya_85 [url=http://forum.ubuntu-it.org/viewtopic.php?p=4727703#p4727703][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Se definisco il vettore come puntatore alla matrice mi viene fuori un doppio puntatore o qualcosa del genere e in fase di compilazioni mi da errore del tipo int* a int**
Codice: Seleziona tutto
#include <iostream>
int main ()
{
int* vec[4];
int mat[2][2];
mat[0][0] = 0;
mat[0][1] = 1;
mat[1][0] = 2;
mat[1][1] = 3;
vec[0] = &mat[0][0];
vec[1] = &mat[0][1];
vec[2] = &mat[1][0];
vec[3] = &mat[1][1];
std::cout << "Contenuto vettore: ";
for (std::size_t i = 0; i < 4; ++i)
{
std::cout << *(vec[i]) << " ";
}
std::cout << std::endl;
std::cout << "Modifico la matrice" << std::endl;
mat[0][0] = 10;
mat[0][1] = 11;
mat[1][0] = 12;
mat[1][1] = 13;
std::cout << "Contenuto vettore: ";
for (std::size_t i = 0; i < 4; ++i)
{
std::cout << *(vec[i]) << " ";
}
std::cout << std::endl;
return 0;
}
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
La condizione del while per altro, se capisco le tue intenzioni, è sbagliata. Cosa volevi intendere?
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
La condizione che hai scritto esegue il ciclo fintanto che è vera almeno una delle seguenti condizioni:Hoiya_85 ha scritto:vorrei eseguire la funzione turno fino a quando tot1 o tot2 non siano uguali a zero
-) tot1 è diverso da zero
-) tot2 è uguale a zero.
Cioè esce dal ciclo quando tot1==0 e contemporaneamente tot2!=0
Posta la funzione e l'istruzione con cui la chiamiHoiya_85 ha scritto:ho provato a dichiarare la funzione turno come int invece che void aggiungendo la riga return totg. però non cambia nulla, non so se è quello che intendevi te
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
Codice: Seleziona tutto
int turno (int m[max_size][max_size],int k,int *cg[max_size],int csg,int ctg,int cig,int cpg,int totg,int r,int c) {
if (m[r][c] == k) {
cout << " Nave Colpita! ";
m[r][c] = 0;
}
else
cout << " Colpo in Mare ";
for (int i = 1;i<=4;i++) {
if (cg[i] == 0) {
while (csg != 0)
csg = csg - 1;
}
}
for (int i = 5;i<=10;i++) {
if (cg[i] == 0) {
while (ctg != 0)
ctg = ctg - 1;
}
}
for (int i = 11;i<=16;i++) {
if (cg[i] == 0) {
while (cig != 0)
cig = cig - 1;
}
}
for (int i = 17;i<=20;i++) {
if (cg[i] == 0) {
while (cpg != 0)
cpg = cpg - 1;
}
}
totg = csg+ctg+cig+cpg;
return totg;
}
Codice: Seleziona tutto
while (tot1 || tot2 == 0) {
cout << " Turno del giocatore " << player1 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia2,2,c2,cs2,ct2,ci2,cp2,tot2,r,c);
cout << " Turno del giocatore " << player2 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia1,1,c1,cs1,ct1,ci1,cp1,tot1,r,c);
}
if (tot1 && tot2 == 0)
cout << " La partita e' terminata in pareggio " << endl;
if (tot2 == 0)
cout << " Complimenti! " << player1 << " , Hai Vinto! " << endl;
if (tot1 == 0)
cout << " Complimenti! " << player2 << " , Hai Vinto! " << endl;
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
Btw, non è così che si fa a "far uscire" da una funzione le modifiche che fai a un valore che passi in ingresso. Cioè, funziona, ma non si fa, perché è di difficile mantenimento, lettura e comprensione. Devi passare un puntatore a tot alla funzione turno
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
allora ho modificato il while e ho modificato l'if della prima condizione (in effetti avevi ragione tu, non avevo inserito il valore per tot1)1001001 ha scritto:Ok, ma non hai cambiato la condizione del while (gli if in fondo stampano solo, ma non escono dal ciclo...senza contare che anche la condizione del primo if è sbagliata) e non hai salvato il valore di ritorno della funzione turno da nessuna parte
Btw, non è così che si fa a "far uscire" da una funzione le modifiche che fai a un valore che passi in ingresso. Cioè, funziona, ma non si fa, perché è di difficile mantenimento, lettura e comprensione. Devi passare un puntatore a tot alla funzione turno
Codice: Seleziona tutto
cout << " Turno del giocatore " << player1 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia2,2,c2,cs2,ct2,ci2,cp2,tot2,r,c);
cout << " Turno del giocatore " << player2 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia1,1,c1,cs1,ct1,ci1,cp1,tot1,r,c);
while (tot1 != 0 || tot2 != 0) {
cout << " Turno del giocatore " << player1 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia2,2,c2,cs2,ct2,ci2,cp2,tot2,r,c);
cout << " Turno del giocatore " << player2 << endl;
cout << " Inserisci le coordinate della casella da colpire " << endl;
cout << "Inserisci la riga " << endl;
cin >> r;
cout << "Inserisci la colonna " << endl;
cin >> c;
turno (griglia1,1,c1,cs1,ct1,ci1,cp1,tot1,r,c);
}
if (tot1 == 0 && tot2 == 0)
cout << " La partita e' terminata in pareggio " << endl;
if (tot2 == 0)
cout << " Complimenti! " << player1 << " , Hai Vinto! " << endl;
if (tot1 == 0)
cout << " Complimenti! " << player2 << " , Hai Vinto! " << endl;
ti riporto la dichiarazione delle variabili nel main
[codeint dim;
int r;
int c;
int navi1=10;
int navi2=10;
int griglia1[max_size][max_size];
int griglia2[max_size][max_size];
char player1[max_size];
char player2[max_size];
int *c1[max_size];
int *c2[max_size];
int cs1 = 4;
int cs2 = 4;
int ct1 = 3;
int ct2 = 3;
int ci1 = 2;
int ci2 = 2;
int cp1 = 1;
int cp2 = 1;
int tot1 = 0;
int tot2 = 0;
bool ris;
int dimt = 2;
int dimi = 3;
int dimp = 4;][/code]
c1 e c2 sono i due vettori di lunghezza 20 che una volta inserite tutte le navi hanno valori tutti 1 e tutti 2 rispettivamente per giocatore 1 e giocatore 2: le posizioni si riferiscono per i primi quattro elementi ai sommergibili, per quelli dal 5 al 10 ai torpedinieri, dal11 al 16 per gli incrociatori e dal 17 al 20 per la portaerei.cs,ci,ct,cp sono i contatori del tipo di nave.dimt,dimi,dimp sono le dimensioni delle navi che occupano più di una casella.
Adesso quello che succede è che il programma non fa il while, direttamente mi dice che tutti e due i giocatori vincono, esegue solo il primo turno fuori dal while, a questo punto credo che il problema sia legato a tot1 e tot2 che vengono modificati dalla funzioni ma il main non legge il valore e quindi forse dovrei utilizzare i puntatori per tot1 e tot2, solo che non ho capito bene quello che mi avevi detto tu: dovrei definire tot1 e tot2 come per esempio
Codice: Seleziona tutto
int *tot1=0;
int *tot2 = 0;
oppure non ho capito nulla?
perché facendo così poi il & lo metto a cosa? tot nella funzione è uguagliato alla somma dei contatori della nave.
inoltre quando mi dici di salvare il valore dei tot da qualche parte che intendi? eseguendo la funzione turno che restituisce il valore di tot, il while non
dovrebbe "vedere" tot1 e tot2 e verificare la condizione sulla base dei valori restituiti dal while?
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
*) prima di tutto
Codice: Seleziona tutto
while (tot1 != 0 || tot2 != 0)
*)
Che senso ha inizializzare tot1 e tot2 a zero, se sono il numero totale di navi rimaste ai due giocatori? Inizializzali direttamente al numero iniziale di naviHoiya_85 ha scritto:come vedi ho inserito un turno fuori dal while perché tot1 e tot2 erano inizializzati a zero e quindi non mi eseguirebbe il while mai
*)
Esattamente. Quando il main arriva al while tot1 e tot2 sono zero entrambi, quindi la condizione e falsa e nel while non ci entra.Hoiya_85 ha scritto:Adesso quello che succede è che il programma non fa il while, direttamente mi dice che tutti e due i giocatori vincono, esegue solo il primo turno fuori dal while, a questo punto credo che il problema sia legato a tot1 e tot2 che vengono modificati dalla funzioni ma il main non legge il valore
*)
No, tot1 e tot2 vanno definiti come interi. È la funzione turno che poi deve prendere in ingresso due puntatori a int ed essere chiamata su &tot1 e &tot2, in modo che le modifiche ai due interi escano dalla funzione.Hoiya_85 ha scritto:solo che non ho capito bene quello che mi avevi detto tu: dovrei definire tot1 e tot2 come per esempioe di conseguenza modificarli nell'argomento della funzione?Codice: Seleziona tutto
int *tot1=0; int *tot2 = 0;
oppure non ho capito nulla?
perché facendo così poi il & lo metto a cosa?
*)
Se proprio non vuoi usare i puntatori (e io ti consiglio di usarli..se vuoi programmare in C, non puoi non essere a tuo agio con i puntatori) devi salvare da qualche parte il valore di ritorno della funzione turno, in modo da assegnare poi questo valore a tot1 e tot2. Se no come fai a cambiare il valore di queste due variabili nel main?Hoiya_85 ha scritto:inoltre quando mi dici di salvare il valore dei tot da qualche parte che intendi? eseguendo la funzione turno che restituisce il valore di tot, il while non
dovrebbe "vedere" tot1 e tot2 e verificare la condizione sulla base dei valori restituiti dal while?
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
sul resto ci sono, però decidendo per usare i puntatori non capisco che intendi sorry, ma io all'interno della funzione turno ho la variabile totg che poi nel while, in base a di chi è il turno totg diventa tot1 o tot2. Quindi non capisco come faccio ad inserire due puntatori ad interi, almeno che tu non stia parlando di un puntatore a funzione, in quel caso dovrei inserire tra gli argomenti della funzione turno una funzione del tipo1001001 ha scritto:No, tot1 e tot2 vanno definiti come interi. È la funzione turno che poi deve prendere in ingresso due puntatori a int ed essere chiamata su &tot1 e &tot2, in modo che le modifiche ai due interi escano dalla funzione.
Codice: Seleziona tutto
(*turnoPtr) (int *,int *)
Se invece uso
Codice: Seleziona tutto
turno(...) = &tot1;
Codice: Seleziona tutto
*turno(...)
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
Che poi, fra l'altro, mi sono appena ricordato che in realtà tu stai programmando in C++...ma il discorso non cambia. L'unica differenza è che in C++ puoi usare le references oltre che i puntatori per "portare fuori" le modifiche a una variabile da una funzione.
Se ti dico "passaggio per valore", "passaggio per referenza" e "passaggio per indirizzo" sai di cosa sto parlando? Lo chiedo onestamente, per capire come risponderti
-
- Prode Principiante
- Messaggi: 69
- Iscrizione: venerdì 27 febbraio 2015, 2:06
- Sesso: Maschile
- Località: Baldissero D'Alba
Re: Matrice-Vettore in c++
-
- Entusiasta Emergente
- Messaggi: 1506
- Iscrizione: mercoledì 22 dicembre 2010, 18:09
- Desktop: Unity
- Distribuzione: Ubuntu 14.04.1 LTS 64bit
- Località: Verona
Re: Matrice-Vettore in c++
In particolare:
È proprio questo che succede con tot1 e tot2! Vengono passate alla funzione turno per valore, e tale valore nel main non cambia!Hoiya_85 ha scritto:se passo un argomento per valore ad una funzione questo viene modificato solo nella funzione ma il suo valore nel main non cambia,
Mentre:
Questo è quello che devi fare. Come dicevo prima, se fossimo in C avresti solo il passaggio per indirizzo, mentre in C++ hai anche quello per riferimento. In sostanza, devi fare una cosa del genere:Hoiya_85 ha scritto:invece nel passaggio per riferimento si ha anche la modifica del valore nel main... quello per indirizzo è simile al passaggio per riferimento ma la funzione può restituire più di un valore
1) per riferimento:
Codice: Seleziona tutto
void turno (int m[max_size][max_size],int k,int cg[max_size],int csg,int ctg,int cig,int cpg,int& totg,int r,int c)
{
...
}
[...]
turno (griglia2,2,c2,cs2,ct2,ci2,cp2,tot1,r,c);
Codice: Seleziona tutto
void turno (int m[max_size][max_size],int k,int cg[max_size],int csg,int ctg,int cig,int cpg,int* totg,int r,int c)
{
...
}
[...]
turno (griglia2,2,c2,cs2,ct2,ci2,cp2,&tot1,r,c);
Chi c’è in linea
Visualizzano questa sezione: 0 utenti iscritti e 16 ospiti