Newsgroup: it.comp.lang.c++
Titolo: [NEWBIE] Confronto fra array (lunghetto)

    Salve a tutti, sono nuovo del NG, e principiante anche per quanto
riguarda la programmazione in c++.
Sto studiando Fondamenti di Informatica 1, Ing. Inf., primo anno, e (+ per
diletto che per altro) sto sviluppando per dos il gioco "Master Mind", nn so
se lo conoscete.
In poche parole:
Il prog. sceglie 4 interi random fra 0 e 7 (possono esserci ripetizioni), e
li mette in un array: lo scopo del gioco sta nell'indovinare i 4 numeri, e
la loro esatta posizione.
L'utente quindi inserisce 4 valori interi (che finiscono in un altro array),
cercando di indovinare quelli scelti dal gioco, che confrontando i 2 array
dirà al giocatore:
    - se ha indovinato un numero ma nn la sua posiz.
    - se ha indovinato un numero e la sua posiz.
Il codice per il confronto degli array è questo:
(arraySoluz è l'array dove vanno i valori inseriti dal giocatore, ed
arrayRandom quello dei numeri scelti dal gioco)
-----------
[cut]
for (i = 1; i <= 4; i++)
    {
    for(j = 1; j <= 4; j++)
      {
        if(arraySoluz[ i ]==arrayRandom[ j ])
        {
                if(i == j)
                    cout<<arraySoluz[ i ]<<" e' esatto!\n";
                else if (i!=j)
                    cout<<arraySoluz[ i ]<<" e' giusto, ma non la sua
posizione!\n";
        }
      }
    }
[cut]
----------
Il problema è che se il giocatore inserisce 2 o + valori uguali il confronto
viene eseguito per ogni valore, portando il gioco a fornire informazioni
ridondanti o sbagliate;
in poche parole, se il codice da indovinare è [ 1 2 3 1 ]
e il giocatore inserisce [ 1 1 4 6 ], il gioco scriverà:
- 1 è esatto! //infatti la *prima* entrata è uguale negli array
- 1 è giusto ma non la sua posizione //(confrontando la *prima* entrata di
arraySoluz con la *quarta* di arrayRandom)
- 1 è giusto ma non la sua posizione //(confrontando la *seconda* entrata di
arraySoluz con la *prima* di arrayRandom)
- 1 è giusto ma non la sua posizione //(confrontando la *seconda* entrata di
arraySoluz con la *quarta* di arrayRandom)
Come posso ovviare a questo inconveniente?
Chiedo scusa se sono stato un po prolisso, ma non sarei riuscito ad essere
chiaro in meno righe :-)
(ammesso che sia stato chiaro! ;-))
Saluti, tanti auguri di buon anno, alla prox!!
-------------------------
sav(at)
despammed.com
-------------------------

 ----------
Prima di tutto non mi convince il fatto che tu abbia utilizzato come indice
iniziale per gli array il valore 1 quando invece avrebbe dovuto essere 0;
controlla che ciò non ti dia qualche problema, sebbene non dovrebbe avere a
che fare con ciò di cui parlavamo.
Torniamo quindi alle soluzioni.
Nel primo caso (inclusione degli elementi già indovinati) la soluzione più
semplice, ed anche efficace, mi sembra quella di inserire un flag da testare
nel secondo ciclo for e attivare (ovviamente all'interno) nel caso si trovi
una corrispondenza, in modo da interrompere il ciclo più interno e passare a
quello più esterno (ossia passare al valore successivo) evitando così quei
confronti e quegli output inutili.
Nel secondo caso (esclusione) bisogna sempre utilizzare il meccanismo del
flag ed in più tenere traccia degli elementi già indovinati. Ciò si può fare
in diversi modi; le soluzioni migliori che adesso mi vengono in mente sono
due:
1. Ogni volta che viene trovata una corrispondenza, sostituire nel primo
array (quello random) al valore trovato un valore di "status" (indovinato)
che non sia valido per il gioco, ad esempio -1, e impostare il confronto in
modo che quando si incontra questo valore non lo si consideri e si passi
semplicemente a quello successivo;
2. Creare un array di strutture con due campi, valore e status, con
quest'ultimo ad indicare se il valore è stato già indovinato, impostando poi
debitamente il confronto in modo da tenerne conto.
Il secondo è forse un tantino più dispendioso, ma ti permette di conservare
l'integrità dei valori dell'array ed è secondo me più elegante.
Spero di essere stato chiaro e d'aiuto.
Saluti e buon anno a te,
Sergio

    - se ha indovinato un numero e la sua posiz.
Io farei cosi':
  // Quanti per colore
  int n_sol[8]={0};
  int n_tent[8]={0};
 
  // Risposta
  int neri=0,bianchi=0;
  for (int i=0; i<4; i++)
  {
    if (soluzione[i] == tentativo[i])
    {
      // Colore giusto al posto giusto
      neri++;
    }
    else
    {
      // Conta dividendo per colore altrimenti
      n_sol[soluzione[i]]++;
      n_tent[tentativo[i]]++;
    }
  }
  // Calcola i bianchi
  for (int col=0; col<8; col++)
    bianchi += min(n_sol[col],n_tent[col]);
In questo modo quelli giusti come posizione non sono
considerati quando conti quelli di colore giusto ma
posizione sbagliata.
Nota anche che nel master mind originale non si
diceva *quali* fossero quelli giusti come posizione
o come colore ... il gioco e' piu' divertente se
dici solo *quanti* sono quelli giusti per ogni categoria.
Dire quali sono quelli giusti come colore ma sbagliati
come posizione e' anche qualcosa che non ha secondo
me molto senso... supponi che la combinazione segreta
sia 0123 e il tentativo sia 3232: quale sarebbe la
posizione di quelli in colore giusto e in posizione
errata ? Secondo le regole che conosco io in questo
caso la risposta e' semplicemente "ce ne sono 2 giusti
in posizione sbagliata".
Secondo me e' anche istruttivo cercare di scrivere
un programma che prova a *risolvere* il gioco :-)
HTH
Andrea

 errata ?
[CUT]
    Hai centrato il problema...è proprio li' che mi sono inceppato!
    Grazie dell'aiuto, ciao :-)
--------------------------
sav(at)
despammed.com
--------------------------

newbie! ;-))    */
Esistono delle funzioni di libreria per min e max,
sostanzialmente fanno qualcosa come:
  int min(int x,int y)
  {
    if ( x < y ) return x;
    return y;
  }
Per usare quella standard C++ devi aggiungere
#include <algorithm> e scrivere std::min(x,y)
per avere il minimo fra x e y.
HTH
Andrea

 wrote:
[CUT]
Sei stato chiarissimo, grazie mille ;-)
Ora ho capito tutto. Alla prox :-) grazie ancora.
---------------
sav(at)
despammed.com
---------------