PI-ITBA / 2024_02

Consultas 2C 2024
4 stars 0 forks source link

TP7 ejercicio 6 (MASTERMIND) #75

Open marr64 opened 5 days ago

marr64 commented 5 days ago

Hola buenas! Esta es mi version del mastermind! funcionar funciona bien pero me encantaria ver que onda el tema de la eficiencia y estilo. Que mejoras le harian... con la unica funcion que tengo muy segura que no hay eficiencia es con la de contarRegular. Desde ya, Muchas gracias!

`#include

include

include "getnum.h"

include "random.h"

include

define X 3

void generarAleatorio(int incognita[]); int elegirNivel(void); void leerNumero(int numero[]); bool coincideNumero(int numero[], int incognita[]); int cantidadBien(int numero[], int incognita[]); int cantidadRegular(int numero[], int incognita[]); int isValid(int numerito);

int main(void){

randomize();

int randVec[X];
int number[X];
int nivel;
int haGanado = 0;
int j;

generarAleatorio(randVec);
putchar('\n');

nivel = elegirNivel();

for(j = 0; (j< nivel) && (haGanado == 0); j++){//cantidad de intentos

    leerNumero(number);
    if(coincideNumero(randVec,number)){
        haGanado = 1;
    }

}

if(j == (nivel)&& haGanado == 0){
    printf("Usted a perdido. Se quedo sin Intentos\n");
}else{
    printf("Usted a ganado en el intento numero %d de %d\n", j, nivel);
}

return 0;

}

void generarAleatorio(int incognita[]){ // Arma un arreglo de X elementos no repetidos

int vecAux[9] = {0};
int num;
srand(time(NULL));

for(int i = 0; i < X ; i++){ 

    num = randInt(1,9);

    if(vecAux[num]==0){
    incognita[i]=num;
    vecAux[num] += 1;
    }else{
        --i; // si el numero ya esta, reintenta
    }

}

}

int elegirNivel(void){

int level;

do{
   level = getint("Nivel:\nIngrese un numero del 1 al 10:\n");
}while(level < 1 || level > 10);

return level;

}

void leerNumero(int numero[]){

int aux;
int aux2;

printf("!!Recuerde que el numero es de longitud %d y todos digitos distintos.\n", X);
do{
        aux = getint("Numero:\n");
    }while(!isValid(aux));

for(int k = (X-1); k >= 0; k--){

    aux2 = (aux%10);
    numero[k] = aux2;
    aux /= 10;

}

}

int isValid(int numerito) { int digits[10] = {0}; // Máximo 10 dígitos posibles (0-9) int count = 0; int temp = numerito;

while (temp > 0) {
    int dig = temp % 10;

    if (digits[dig] > 0) {
        return 0;  // Dígito repetido
    }
    digits[dig]++;
    temp /= 10;
    count++;
}

return count == X;  // Verifica si tiene exactamente X dígitos

}

bool coincideNumero(int numero[], int incognita[]){

int bien = cantidadBien(numero, incognita);
int regular = cantidadRegular(numero, incognita);

printf("La cantidad de numeros que coinciden en digito y lugar son %d\n", bien);
printf("La cantidad de numeros que coinciden en digito pero no en lugar son %d\n", regular);

return bien == X;  // Si todos los digitos coinciden, devuelve true

}

int cantidadBien(int numero[], int incognita[]){

int countBien = 0;

for(int m = 0; m < X; m++){
    if(numero[m] == incognita[m]){
        countBien++;
    }
}

return countBien;

}

int cantidadRegular(int numero[], int incognita[]){

int countReg = 0;

for(int b = 0; b < X; b++){
    for(int l = 0; l < X; l++){
        if((numero[b] == incognita[l]) && (b!=l)){
            countReg++;
        }
    }
}

return countReg;

} `

marcelogarberoglio commented 5 days ago

Acá estás cambiando el iterador dentro del ciclo y también en la línea donde está el for, eso es confuso

for(int i = 0; i < X - 1 ; i++){ 
    num = randInt(1,9);

    if(vecAux[num]==0){
    incognita[i]=num;
    vecAux[num] += 1;
    }else{
        --i;
    }

}

Además estás verificando si un un dígito ya salió o no. Eso puede servir si tu número tiene muy pocos dígitos, pero qué pasa si X pasa a ser 7. Y algo similar pasará cuando tengan que programar el bingo, al extraer una bolilla del bolillero. Si la solución es similar a esta sería como si cuando sale una bolilla la vuelven a meter, y cada vez que sale una preguntan si ya salió o no, a medida que avanza el juego se pone muy lento. Podrías generar un vector con todos los valores a usar y después una de dos: 1) Mezclar el vector y extraer los primeros X valores 2) Ir obteniendo en forma aleatoria el índice, primero entre 0 y 8, si sale 3 reemplazás vecAux[3] con vecAux[8], luego un aleatorio entre 0 y 7, etc.

El resto me parece que está bien

marr64 commented 5 days ago

Genial!! gracias Marcelo. Lo corrijo y dejo la nueva version cuando este. Buenas noches :)

marr64 commented 5 days ago

codigo corregido:

`#include

include

include "getnum.h"

include "random.h"

include

define X 3

define MIN 0

define MAX 8

void generarAleatorio(int incognita[]); int elegirNivel(void); void leerNumero(int numero[]); bool coincideNumero(int numero[], int incognita[]); int cantidadBien(int numero[], int incognita[]); int cantidadRegular(int numero[], int incognita[]); int isValid(int numerito);

int main(void){

randomize();

int randVec[X];
int number[X];
int nivel;
int haGanado = 0;
int j;

generarAleatorio(randVec);

//Para probar mas rapido si funciona jeje /*for(int w = 0; w< X; w++){ printf("%d\t",randVec[w]);

}
putchar('\n');*/ 

nivel = elegirNivel();

for(j = 0; (j< nivel) && (haGanado == 0); j++){//cantidad de intentos

    leerNumero(number);
    if(coincideNumero(randVec,number)){
        haGanado = 1;
    }

}

if(j == (nivel)&& haGanado == 0){
    printf("Usted a perdido. Se quedo sin Intentos\n");
}else{
    printf("Usted a ganado en el intento numero %d de %d\n", j, nivel);
}

return 0;

}

void generarAleatorio(int incognita[]){ // Arma un arreglo de X elementos no repetidos

int vecAux[] = {1,2,3,4,5,6,7,8,9};
int num;
srand(time(NULL));

for(int i = 0; i< X; i++){

    num = randInt(MIN,MAX-i); //Indice random
    incognita[i]= vecAux[num];
    vecAux[num] = vecAux[MAX-i];
}

}

int elegirNivel(void){

int level;

do{
   level = getint("Nivel:\nIngrese un numero del 1 al 10:\n");
}while(level < 1 || level > 10);

return level;

}

void leerNumero(int numero[]){

int aux;
int aux2;

printf("!!Recuerde que el numero es de longitud %d y todos digitos distintos.\n", X);
do{
        aux = getint("Numero:\n");
    }while(!isValid(aux));

for(int k = (X-1); k >= 0; k--){

    aux2 = (aux%10);
    numero[k] = aux2;
    aux /= 10;

}

}

int isValid(int numerito) { int digits[10] = {0}; // Máximo 10 dígitos posibles (0-9) int count = 0; int temp = numerito;

while (temp > 0) {
    int dig = temp % 10;

    if (digits[dig] > 0) {
        return 0;  // Dígito repetido
    }
    digits[dig]++;
    temp /= 10;
    count++;
}

return count == X;  // Verifica si tiene exactamente X dígitos

}

bool coincideNumero(int numero[], int incognita[]){

int bien = cantidadBien(numero, incognita);
int regular = cantidadRegular(numero, incognita);

printf("La cantidad de numeros que coinciden en digito y lugar son %d\n", bien);
printf("La cantidad de numeros que coinciden en digito pero no en lugar son %d\n", regular);

return bien == X;  // Si todos los digitos coinciden, devuelve true

}

int cantidadBien(int numero[], int incognita[]){

int countBien = 0;

for(int m = 0; m < X; m++){
    if(numero[m] == incognita[m]){
        countBien++;
    }
}

return countBien;

}

int cantidadRegular(int numero[], int incognita[]){

int countReg = 0;

for(int b = 0; b < X; b++){
    for(int l = 0; l < X; l++){
        if((numero[b] == incognita[l]) && (b!=l)){
            countReg++;
        }
    }
}

return countReg;

} `

marcelogarberoglio commented 5 days ago

Está muy bien. Sólo sacaría esta línea

srand(time(NULL));

porque eso se debe hacer una sola vez al principio del programa, y ya lo estás haciendo al invocar randomize()