Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TP7 ejercicio 6 (MASTERMIND) #75

Open
MarrMalleville opened this issue Oct 1, 2024 · 4 comments
Open

TP7 ejercicio 6 (MASTERMIND) #75

MarrMalleville opened this issue Oct 1, 2024 · 4 comments

Comments

@MarrMalleville
Copy link

MarrMalleville commented Oct 1, 2024

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 <stdio.h>
#include <stdbool.h>
#include "getnum.h"
#include "random.h"
#include <time.h>

#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
Copy link
Member

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

@MarrMalleville
Copy link
Author

MarrMalleville commented Oct 2, 2024

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

@MarrMalleville
Copy link
Author

MarrMalleville commented Oct 2, 2024

codigo corregido:

`#include <stdio.h>
#include <stdbool.h>
#include "getnum.h"
#include "random.h"
#include <time.h>

#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
Copy link
Member

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()

This was referenced Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants