Ciao Weirestrass,
scusa il disturbo ma sono quasi arrivato alla fine del progetto ed ho bisogno di un piccolo aiuto:
come vedrai dal codice che sto postando sono finalmente riuscito a risolvere il problema precedentemente discusso.
Ora il programma funziona quasi correttamente, ma c’ è un problema: l’ algoritmo che anche tu hai usato impiega in media 15 tentativi per arrivare alla soluzione finale. A parità di soluzioni ho provato anche il tuo e funziona decisamente meglio in quanto utilizza meno tentativi.
Il fatto è che se la soluzione inizia con lettere quali A-B la soluzione arriva più facilmente, perché i possibili tentativi con A-B iniziali sono all’ inizio dell’ array s, mentre se ho delle soluzioni con la prima lettera che inizia con E-F allora il programma impiega circa 15 tentativi al raggiungimento della soluzione.
Non capisco il motivo, dato che l’ algoritmo implementato è lo stesso.
Ad esempio con la soluzione FFFF il mio funziona in questo modo:
Addirittura il programma termina con tentativi -1 e con violazione alla memoria!
Il tuo, invece, funziona correttamente e a partire dal terzo tentativo invece di CAAA inserisce CCCC, come se il tentativo successivo lo facesse in funzione di quelli tentati precedentemente e non solo in funzione del precedente, come è possibile?
Ecco il codice, ho tolto gli and e or , sostituendoli con && e ||, ora spero che compili.
CODICE:
#include <iostream>
#include <conio.h>
#include <windows.h>
#include <time.h>
#include <string>
#include <cstring>
using namespace std;
char car;
bool marca[1296];
int n_attempts=0,c;
float t_dif;
time_t ini,fin;
struct outcome{
int strikes;
int bals;
};
void gotoxy( short column, short line );
int esc_function();
void show_solution();
int main(){
int y;
do{
for(y=0;y<1296;y++){
marca[y]=false;
}
c=1296;
n_attempts=0; //set number of attempts
system("cls");
gotoxy(33,5);
cout<<" MISTER MIND **PLAYER** by Daniele Di Girolamo ";
gotoxy(41,25);
cout<<"Click enter to continue--> ";
do{
car=getch();
}while(car==0 && car!=27);
if(car==27 ) esc_function();
system("cls");
show_solution();
if(car==27) esc_function();
gotoxy(41,25);
cout<<"Click enter to continue--> ";
do{
car=getch();
}while(car==0 && car!=27);
}while(car!=27 && car==13);
return 0;
}
void gotoxy( short column, short line ){ //position of the text on screen 25 lines and 80 columns
COORD pos={column,line};
SetConsoleCursorPosition(GetStdHandle( STD_OUTPUT_HANDLE ),pos);}
int esc_function(){if(car==27){{system("cls");gotoxy(40,15);cout<<"----Thanks to played! bye!---- ";ini=time(NULL);do{ fin=time(NULL); t_dif=difftime(fin,ini);} while(t_dif<3);exit(true);return (0);}}}
void show_solution(){ //funzione cerca la soluzione
string s[1296];
outcome user, comp;
char temporary[4],s_found[4],indication[4]; //temporary per il tentativo precedente, s_found per il possibile tentativo successivo, indication per le indicazioni dell' utente
bool found; //flag per verificare quando si trova un tentativo plausibile in base alle informazioni dell' user
int i, j, k, l, n = 0,indice;
for(i = 0; i < 6; i++)
for(j = 0; j < 6; j++)
for(k = 0; k < 6; k++)
for(l = 0; l < 6; l++){
s[n] = i + 'A';
s[n] += j + 'A';
s[n] += k + 'A';
s[n] += l + 'A';
s[n++];
}
srand(time(NULL));j=0;
if(n_attempts==0){
indice=rand()%1296; //generazione indice random
marca[indice]=true; //marco il primo tentativo
gotoxy(36,5);
cout<<" MISTER MIND **PLAYER** by Daniele ";
gotoxy(10,8);
cout<<" "<<c<<" Try N. "<<n_attempts+1<<" ==> ";
cout<<s[indice]<<" ? ";
n_attempts++;
do{//gestione dell' input controllato
car=getch();
if((car==88 || car==79)&& j!=4){ putch(car);indication[j]=car;j++;} // 88==X 79==O
if((car==120 || car==111) && j!=4 ){car=car-32;putch(car); indication[j]=car; j++;} //caso in cui l'utente abbia il block maiusc disattivo
if (car==8 && j>0 ) {putch(8);putch(32);putch(8);indication[j-1]='0';j--;} //premo backslash se ho sbagliato a dare le informazioni e voglio cambiarle
}while((car!=13 && car!=27));
for(i=0;i<4;i++){ //conteggio degli strikes e bals dell' utente
if(indication[i]=='X') user.strikes++;
if(indication[i]=='O') user.bals++;}
if(user.strikes!=4){//esecuzione del blocco se strikes dell' utente è diverso da 4
n=0; found=false;
do{
strcpy(temporary,s[indice].c_str()); //copio il tentativo fatto su temporary
strcpy(s_found,s[n].c_str());//copio il possibile tentativo successivo in s_found
for ( i=0 ; i<4; i++){
if (temporary[i] == s_found[i]){
s_found[i]='0'; // avoiding count like a bal
temporary[i]='1'; ///avoiding reuse the char
comp.strikes++;} //incremento il numero di strikes dell' computer
}
for ( int x=0 ; x<4; x++){
for ( j=0 ; j<4; j++){
if (s_found[x] == temporary[j]){
s_found[x]='0'; //avoiding double count
temporary[j]='1'; ///avoiding reuse the char
comp.bals++; } //incremento il numero di bals dell' computer
}
}
if(user.strikes==comp.strikes && user.bals==comp.bals) {found=true;c=c-1;marca[n]=true;} //se la condizione è vera: setto il flag found a true per uscire, decremento il numero dei possibili tentativi e marco il tentativo
c=c-1; marca[n]=true; n=n+1; comp.strikes=0;comp.bals=0; // altrimenti vado avanti con n=n+1, scarto il tentativo
}while( n<=1296 && !found && user.strikes!=4 && car!=27);
gotoxy(10,9); //output del secondo tentativo
cout<<" "<<c<<" Try N. "<<n_attempts+1<<" ==> ";
cout<<s[n-1]<<" ? "; n_attempts++;}
}l=10; k=0; //k== nuovo n per gli altri tentativi , l=line del tentativo successivo
//Da qui inizia il terzo tentativo fino alla soluzione
do{
j=0; user.strikes=0; user.bals=0; found=false;
do{//gestione input controllato
car=getch();
if((car==88 || car==79)&& j!=4){ putch(car);indication[j]=car;j++;}
if((car==120 || car==111) && j!=4 ){car=car-32;putch(car); indication[j]=car; j++;}
if (car==8 && j>0 ) {putch(8);putch(32);putch(8);indication[j-1]='0';j--;}
}while((car!=13 && car!=27));
for(i=0;i<4;i++){ //conteggio strikes e bals dell' user
if(indication[i]=='X') user.strikes++;
if(indication[i]=='O') user.bals++;}
do{
strcpy(temporary,s[n-1].c_str()); //indica il tentativo precente
if(marca[k]!=true){ //controllo se il tentativo non sia stato già preso in considerazione
strcpy(s_found,s[k].c_str());
for ( i=0 ; i<4; i++){
if (temporary[i] == s_found[i]){
s_found[i]='0'; // avoiding count like a bal
temporary[i]='1';//avoiding reuse the char
comp.strikes++;}
}
for ( int x=0 ; x<4; x++){
for ( j=0 ; j<4; j++){
if (s_found[x] == temporary[j]){
s_found[x]='0'; //avoiding double count
temporary[j]='1'; ///avoiding reuse the char
comp.bals++; }
}
}
if(user.strikes==comp.strikes && user.bals==comp.bals) {found=true;c=c-1;marca[k]=true;n=k;user.strikes=0; user.bals=0; }
//n=k indica che n avrà il valore del nuovo tentativo che sta per essere stampato a schermo
else{c=c-1; marca[k]=true;}
comp.strikes=0;comp.bals=0;
}
k=k+1;
}while(k<=1296 && !found && user.strikes!=4 && car!=27);
if(user.strikes==4){ cout<<"\t\t ***SOLUTION***";}
else{
gotoxy(10,l++);
cout<<" "<<c<<" Try N. "<<n_attempts+1<<" ==> ";
cout<<s[k-1]<<" ? "; n_attempts++;}
}while(user.strikes!=4 && car!=27);
}
ESEMPIO :
Cosa ne pensi? Cosa posso fare per ottimizzare il codice?
Grazie mille in anticipo!