PDA

Visualizza la versione completa : [C++] Gestione avanzata degli array bidimensionali


Marigno
13-03-2009, 19:23
Salve.
Vengo subito al dunque: sto creando una orribile e vomitevole copia di The Sims (videogioco di simulazione di vita reale) in forma testuale (via char) per MSDOS, utilizzando il C++.

[...]

Non sono pazzo.
Non sono pazzo.
Non sono pazzo.

Bene, ora che avete appurato che non sono pazzo, posso continuare il discorso.
Avevo intenzione di sfruttare un array bidimensionale di char "mappaDiGioco[10][10]" per ricreare in forma grafica una sorta di mappa.
Bene.
Il problema sta nella gestione. Vi incollo la parte di codice interessata (le parti non necessarie le ho tolte).


#include <iostream>
using namespace std;

// Variabili globali.
bool fineGioco = false;
char tastoMovimento;
char mappaDiGioco[10][10] =
{
{'"', '"', '"', '"', '"', '"', '"', '"', '"', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', '"', '"', '"', '"', '"', '"', '"', '"', '"'},
};

// Funzioni (procedure).
void visualizzaMappa();
void movimentoPersonaggio();

int main()
{
visualizzaMappa();
movimentoPersonaggio();
return 0;
}

// Questa funzione stampa a video la mappa.
void visualizzaMappa()
{
int iRiga = 0;
int iColonna = 0;

system("cls");

for (iRiga = 0; iRiga < 10; iRiga++)
{
for (iColonna = 0; iColonna < 10; iColonna++)
{
cout << mappaDiGioco[iRiga][iColonna];
}
cout << endl;
}
cout << endl;
}

// Questa funzione controlla l'input di movimento.
void movimentoPersonaggio()
{
int iRiga = 0;
int iColonna = 0;

// Controllo la posizione del personaggio.
do
{
cin >> tastoMovimento;
for (iRiga = 0; iRiga < 10; iRiga++)
{
for (iColonna = 0; iColonna < 10; iColonna++)
{
if (mappaDiGioco[iRiga][iColonna] == '*')
{
if (((mappaDiGioco[(iRiga+1) || (iRiga-1)][iColonna]) && (mappaDiGioco[iRiga][(iColonna+1) || (iColonna-1)])) == '"')
{
movimentoPersonaggio();
}
else
{
switch (tastoMovimento)
{
case 'w':
case 'W':
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga-1][iColonna] = '*';
break;
case 'a':
case 'A':
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga][iColonna-1] = '*';
break;
case 's':
case 'S':
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga+1][iColonna] = '*';
break;
case 'd':
case 'D':
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga][iColonna+1] = '*';
break;
default:
break;
}
}
}
}
}
visualizzaMappa();
} while (fineGioco == false);
}

Innanzitutto, non funziona.
Premendo i tasti W e A l'asterisco si muove come stabilito rispettivamente su e a sinistra.
Mentre S e D non funzionano. In parole non molto tecniche, mangiano la maggior parte dei caratteri presenti nell'array.

Inoltre, vorrei che, una volta volta arrivato al carattere ' " ', l'asterisco si fermi. Non faccia niente. Proprio niente.
Ma a quanto pare così non funziona.
Ho ipotizzato che mi sfugge qualcosa sul controllo degli array bidimensionali.

La mia domanda è: dove sbaglio?

Grazie e buona vita.

oregon
13-03-2009, 19:33
Originariamente inviato da Marigno
Non sono pazzo.
Non sono pazzo.
Non sono pazzo.


Intanto, questa if

if (((mappaDiGioco[(iRiga+1) || (iRiga-1)][iColonna]) && (mappaDiGioco[iRiga][(iColonna+1) || (iColonna-1)])) == '"')

e' un po' strana ... cosa volevi fare? Perche' scritta cosi' non ha molto senso ...

E poi, continui a chiamare la funzione

movimentoPersonaggio

anche al suo interno, in maniera ricorsiva ma non controllata ... era tua intenzione?

Marigno
13-03-2009, 19:59
Quella IF serve (servirebbe) a controllare se l'asterisco sta per toccare i bordi della mappa.

movimentoPersonaggio() l'ho richiamata nella stessa funzione per un semplice motivo: ripetere tutto.
Visto che quando l'asterisco sta per toccare i bordi l'IF dovrebbe bloccarlo, lo stesso asterisco non si dovrebbe effettivamente muovere, perché verrebbe richiamata la funzione movimentoPersonaggio, cioè dove richiede l'input del tasto per muoverlo.

Ma, ovviamente, non funziona.

oregon
13-03-2009, 20:08
Originariamente inviato da Marigno
Quella IF serve (servirebbe) a controllare se l'asterisco sta per toccare i bordi della mappa.

movimentoPersonaggio() l'ho richiamata nella stessa funzione per un semplice motivo: ripetere tutto.


Non mi sono spiegato.

Quella if NON e' corretta.

Se ci sono piu' termini da confrontare, non si scrivono in quel modo, ma si ripetono

if(a=='*' || b=='*' || c=='*')

ok?

E poi la funzione richiamata all'interno di se' stessa NON e' il modo corretto per ripeterla ...

Marigno
13-03-2009, 20:19
Ah, capito, scusami. ^^

Ho sistemato la IF così:


if ((((mappaDiGioco[(iRiga+1) || (iRiga-1)][iColonna]) == '"') || ((mappaDiGioco[iRiga][(iColonna+1) || (iColonna-1)])) == '"'))

Ed ho eliminato il richiamo alla stessa funzione.
Ho semplicemente lasciato le due parentesi graffe.
Dovrebbe andar bene, no? Il ciclo, teoricamente, viene ripetuto.

Però ci sono ancora dei problemi.
I tasti S e D continuano a non funzionare.

oregon
13-03-2009, 20:24
La if non e' affatto sistemata

Non puoi scrivere ...

mappaDiGioco[(iRiga+1) || (iRiga-1)][iColonna]

Devi RIPETERE ogni elemento ...

(mappaDiGioco[iRiga+1][iColonna] == '"') || (mappaDiGioco[iRiga-1][iColonna] == '"')

YuYevon
13-03-2009, 20:27
L'operatore || (OR) restituisce un valore booleano (vero o falso, 1 o 0), non uno dei due operandi, come probabilmente la stai intendendo tu :)

Marigno
13-03-2009, 20:39
Okay, grazie per la pazienza.
Ho finalmente capito.

Yosh.
Ora i tasti funzionano, ma male.
Invece di spostarti di uno spazio, si spostano di tre o più.

Tra l'altro, devo pensare ad un metodo migliore per evitare i bordi: ora come ora, se arrivo vicino al bordo, non posso premere più niente. Perché ovviamente è questa la funzione per cui è stato creato.

Marigno
13-03-2009, 21:39
Ahem, scusate il doppio post.
Sono riuscito definitivamente a risolvere il problema dei bordi.
Ora il codice è ottimizzato.
Lo posto (non mi permette di modificare il primo post, pertanto lo metto qui).


#include <iostream>
using namespace std;

// Variabili globali.
bool fineGioco = false;
char tastoMovimento;
char mappaDiGioco[10][10] =
{
{'"', '"', '"', '"', '"', '"', '"', '"', '"', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', '*', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', '"'},
{'"', '"', '"', '"', '"', '"', '"', '"', '"', '"'},
};

// Funzioni (procedure).
void visualizzaMappa();
void movimentoPersonaggio();

int main()
{
visualizzaMappa();
movimentoPersonaggio();
return 0;
}

// Questa funzione stampa a video la mappa.
void visualizzaMappa()
{
int iRiga = 0;
int iColonna = 0;

system("cls");

for (iRiga = 0; iRiga < 10; iRiga++)
{
for (iColonna = 0; iColonna < 10; iColonna++)
{
cout << mappaDiGioco[iRiga][iColonna];
}
cout << endl;
}
cout << endl;
}

// Questa funzione controlla l'input di movimento.
void movimentoPersonaggio()
{
int iRiga = 0;
int iColonna = 0;

// Muovo il personaggio.
do
{
cin >> tastoMovimento;
for (iRiga = 0; iRiga < 10; iRiga++)
{
for (iColonna = 0; iColonna < 10; iColonna++)
{
if (mappaDiGioco[iRiga][iColonna] == '*')
{
switch (tastoMovimento)
{
case 'w':
case 'W':
if (mappaDiGioco[iRiga-1][iColonna] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga-1][iColonna] = '*';
}
break;
case 'a':
case 'A':
if (mappaDiGioco[iRiga][iColonna-1] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga][iColonna-1] = '*';
}
break;
case 's':
case 'S':
if (mappaDiGioco[iRiga+1][iColonna] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga+1][iColonna] = '*';
}
break;
case 'd':
case 'D':
if (mappaDiGioco[iRiga][iColonna+1] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga][iColonna+1] = '*';
}
break;
}
}
}
}
visualizzaMappa();
} while (fineGioco == false);
}

Ora il problema che mi pongo è lo scorretto funzionamento dei tasti S e D.
Mi correggo per quanto detto nel post precedente, non saltano solo tre posti, ben TUTTI, fino ad arrivare al blocco. Mah.
Suggerimenti?

oregon
13-03-2009, 22:11
Dai un'occhiata alle modifiche in rosso



void movimentoPersonaggio()
{
int iRiga = 0;
int iColonna = 0;
int moved;

// Muovo il personaggio.
do
{
moved=0;
cin >> tastoMovimento;
for (iRiga = 0; iRiga < 10; iRiga++)
{
for (iColonna = 0; iColonna < 10; iColonna++)
{
if (mappaDiGioco[iRiga][iColonna] == '*')
{
switch (tastoMovimento)
{
case 'w':
case 'W':
if (mappaDiGioco[iRiga-1][iColonna] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga-1][iColonna] = '*';
moved=1;
}
break;
case 'a':
case 'A':
if (mappaDiGioco[iRiga][iColonna-1] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga][iColonna-1] = '*';
moved=1;
}
break;
case 's':
case 'S':
if (mappaDiGioco[iRiga+1][iColonna] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga+1][iColonna] = '*';
moved=1;
}
break;
case 'd':
case 'D':
if (mappaDiGioco[iRiga][iColonna+1] != '"')
{
mappaDiGioco[iRiga][iColonna] = ' ';
mappaDiGioco[iRiga][iColonna+1] = '*';
moved=1; }
break;
}
}

if(moved) break;
}
}

visualizzaMappa();
} while (fineGioco == false);
}

Loading