Grazie mille per l'aiuto che mi hai dato, penso finalmente d'esser riuscito a far funzionare bene sta briscola
shodan ha scritto:
Come prima, l'errore è da un'altra parte e per la precisione in:
int TavoloBriscola::trovaVincitore(const int leader)
{
cout << "Calcolo il seme." << endl;
setSeme(leader);
int winner = leader;
Carta max = carte[leader];
int indice = leader + 1; // (punto 1)
cout << "Calcolo la carta piu' alta." << endl;
for (int i = 1; i < carteAttuali; i++) // scorre tutte le carte finché non ha trovato la vincitrice di mano
{
if (indice == carteAttuali) // (punto 2)
indice = 0;
else // altrimenti incrementato
++indice;
if (confronta(carte[indice], max) == true) // (punto 3)
...
In pratica, quando leader vale 0 succede che indice vale 1 (punto 1). In (punto 2) la if fallisce il confronto (carteAttuali vale 2) e incrementa indice che ora vale 2.
Ora stai accedendo a carte[2] che non esiste! Quell'array ha due locazioni non tre, e ne imposti la dimensione nel costruttore di Tavolo.
sì, quella funzione faceva schifo, come setSeme, perché inizialmente avevo impostato il tavolo come un array che
non conteneva in modo ordinato le carte, ma ogni indice indicava la carta che ha scartato il corrispettivo giocatore (ma appunto non erano in ordine, nella mia testa il giro era dal giocatore 0-1-2-3 in senso antiorario), e poi in partitaBriscola.cpp con la funzione addCarta non mi ero accorto che ero tornato esattamente indietro: i metodi per trovare il vincitore e il seme si basavano su questo pensiero del "so che carta hai lanciato", però l'array anziché essere riempito per indici veniva riempito in ordine, ecco quindi il casino.
shodan ha scritto:
(Per la cronaca, per trovare l'errore ho dovuto usare std::vector<Carte> in modo che il debugger mostri locazioni e numero di elementi contenuti. Capisco il progetto scolastico, ma questo dimostra che, quando possibile, è meglio usare i vector rispetto agli array con raw pointer).
guarda, ho subito voglia di imparare sti vector e inizio a pocciare qualcosa perché veramente i raw pointer mi hanno stancato abbastanza dopo sti problemi
shodan ha scritto:
Tra l'altro nel costruttore di tavolo stai usando una strategia di controllo allocazione diversa (e inutile) da quella che usi da altre parti (corretto controllo eccezioni).
Un controllo simile funziona solo quando si scrive:
carte = new Carta[n] nothrow; // nothrow forza l'uso di un operator new che non lancia eccezioni, ma ritorna nullptr (NULL)
if (carte != NULL)
{
qui sono stato colto da un dubbio amletico: se l'allocazione non andava a buon fine cosa facevo?
improvvisamente mi ricordo del c, dove le eccezioni non c'erano e se la malloc (su cui sapevo si basava l'operatore new) non allocava correttamente restituiva un puntatore nullo. così da furbone penso di poter fare sto controllo in c++ anche, poi leggo su cppreference che invece la new lancia la bad_alloc e, ovviamente, mi scordo di modificare tutti i sorgenti
shodan ha scritto:
P.S.
Non capisco il senso dell'allocazione nella funzione swap() contenuta in mazzo.cpp
intendi allocare dinamicamente temp?
in effetti non è stato molto furbo (come altre cose del resto), speravo contasse qualcosa a livello di prestazioni ma non è saggio scomodare il sommo heap per una stupida temp.
ti ringrazio ancora per l'aiuto