PI-ITBA / 2024_02

Consultas 2C 2024
4 stars 0 forks source link

TP7_ej8 #77

Open bleite12 opened 1 month ago

bleite12 commented 1 month ago

hola, no se porque cuando corro el programa me genera 2 cartones iguales o me dice que hay un ganador antes de que termine.


typedef  int TipoLinea[5];
typedef  TipoLinea  TipoCarton [3];
#define FILS 3
#define COLS 5

void Gcarton(TipoCarton carton);
int jugar(int bolillero[],TipoCarton jugador1, TipoCarton jugador2);
int sacarBolillaeficiente(int bolillero[], int *cantBolillas);
int controlaCarton(TipoCarton carton, int bolilla);
void buscarBolilla(TipoCarton carton, int bolilla );
int controlarLineas(TipoLinea fila);
void imprimirCarton(TipoCarton carton);

int main(){
int bolillero[90];
for(int i = 0 ; i<90 ; i++ ){
    bolillero[i]=i+1;
}
TipoCarton j1, j2;
Gcarton(j1);
 srand(time(NULL)); 
Gcarton(j2);

jugar(bolillero, j1, j2);
return 0 ;

}

void Gcarton(TipoCarton carton){
    srand(time(NULL));  
    int apariciones[90]={0}; //el maximo numero.

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

        for(int j = 0 ; j < 5 ; j++ ){
             int c;
            do {
                c = rand() % 90 + 1; // Genera un número aleatorio entre 1 y 90
            } while (apariciones[c - 1] == 1); // Verifica si el número ya ha sido generado

            apariciones[c - 1] = 1; // Marca el número como aparecido
            carton[i][j] = c; // Asigna el número al cartón

        }
    }
}

int jugar(int bolillero[],TipoCarton jugador1, TipoCarton jugador2){
int cant=90;
int bolilla;
int ganador = 0;

    while (cant > 0 && ganador == 0) {
        bolilla = sacarBolillaeficiente(bolillero, &cant);
        printf("Bolilla sacada: %d\n", bolilla);

        // Verificar y marcar bolillas en ambos jugadores
        int lineasJugador1 = controlaCarton(jugador1, bolilla);
        int lineasJugador2 = controlaCarton(jugador2, bolilla);

        // Imprimir cartones de los jugadores
        printf("Carton Jugador 1:\n");
        imprimirCarton(jugador1);
        printf("Carton Jugador 2:\n");
        imprimirCarton(jugador2);

        // Condición de victoria (el juego puede terminar cuando un jugador complete 3 líneas)
        if (lineasJugador1 >= 3) {
            printf("¡El Jugador 1 gana!\n");
            ganador = 1;
        } else if (lineasJugador2 >= 3) {
            printf("¡El Jugador 2 gana!\n");
            ganador = 2;
        }
    }

    if (ganador == 0) {
        printf("No hubo ganador.\n");
    }

    return ganador;
}

int sacarBolillaeficiente(int bolillero[], int *cantBolillas) {
    // Genera un número aleatorio entre 0 y cantBolillas-1
    int random = rand() % (*cantBolillas);

    // La bolilla que sale es la que está en la posición 'random'
    int bolilla = bolillero[random];

    // Reducimos el número de bolillas restantes
    (*cantBolillas)--;

    // Intercambiamos la bolilla seleccionada con la última bolilla en el arreglo
    bolillero[random] = bolillero[*cantBolillas];

    // Devolvemos la bolilla seleccionada
    return bolilla;
}

int controlaCarton(TipoCarton carton, int bolilla){
    buscarBolilla(carton, bolilla);
    int linea[COLS];
    int cantidadlineas=0;
    for(int i = 0 ; i<FILS ; i++ ){
        for(int j = 0 ; j<COLS  ; j++ ){
            linea[j]=carton[i][j];
            cantidadlineas += controlarLineas(linea);
        }

   }

  return cantidadlineas;//retorna la cantidad de lineas armadas.

}

void buscarBolilla(TipoCarton carton, int bolilla ){

    for(int i = 0 ; i<FILS; i++ ){
        for(int j = 0 ; j<COLS ; j++ ){
            if(carton[i][j]==bolilla){
                carton[i][j]=0;//lo marco con 0

            }
        }
    }

}

int controlarLineas(TipoLinea fila){//le paso una fila entera (marcada con 0 ?)
    for(int i = 0 ; i<COLS ; i++ ){
        if(fila[i]!=0){
            return 0;
        }
    }
return 1;//si llego aca es que ningun elemento de la linea es distinto de 0 entonces esta completada
}

void imprimirCarton(TipoCarton carton){
    for(int i = 0 ; i<FILS ; i++ ){
        for(int j = 0 ; j<COLS ; j++ ){
            if(carton[i][j]!=0){
                printf("%d\t", carton[i][j]);
            }
        }
        printf("\n");
    }
printf("\n");
}
ImNotGone commented 1 month ago

Proba sacando el srand de Gcarton (no deberia estar ahi) y llamando srand antes de llamar a GCarton con j1

marcelogarberoglio commented 1 month ago

Agrego algo al acertado comentario de Gonzalo: lean la "letra chica" de los enunciados. En el Mastermind dice:

(*): en esta función es bastante común que el algoritmo para generar X dígitos aleatorios sin repetir sea el siguiente: Crear un vector auxiliar de 9 chars en cero Para i desde 0 hasta X-1 hacer Elegir un dígito al azar entre 1 y 9 Si ya estaba marcado en el vector auxiliar volver al punto 2.a Marcarlo en el vector auxiliar Guardar el dígito en la posición i del vector incognita

El problema con este algoritmo es que si X es cercano a 9 (por ejemplo 7), a medida que avanza i se incrementa la posibilidad de que el dígito ya haya salido, y algo similar pasará con el juego del bingo: las primeras bolillas se mostrarán rápidamente pero a medida que avanza el juego tardará más tiempo es mostrar las nuevas bolillas, ya que el algoritmo planteado arriba sería similar a: sacar una bolilla del bolillero, si no había salido entonces anunciarla, volver a meter la bolilla en el bolillero.
Se debería encontrar un algoritmo que asegure que el siguiente dígito no sea uno de los que ya salieron, y lo mismo al sacar una bolilla en el bingo.

Cómo hacer en forma eficiente para obtener bolillas lo podés encontrar en #75

bleite12 commented 1 month ago

tambien te queria consultar como es que funciona lo de pasarle la fila directamente, porque yo recuerdo que cuando le pasaba una fila a una funcion tenia que hacer 2 for y guardar la fila en un vector auxuliar.

int controlaCarton(TipoCarton carton, int bolilla){
    buscarBolilla(carton, bolilla);
    int cantidadlineas=0;

   for(int i = 0 ; i < FILS ; i++) {
    cantidadlineas += controlarLineas(carton[i]);  // Pasás directamente la fila 'carton[i]'
    }

  return cantidadlineas;//retorna la cantidad de lineas armadas.

}

int controlarLineas(TipoLinea fila){//le paso una fila entera (marcada con 0 ?)
    for(int i = 0 ; i<COLS ; i++ ){
        if(fila[i]!=0){
            return 0;
        }
    }
return 1;//si llego aca es que ningun elemento de la linea es distinto de 0 entonces esta completada
}
marcelogarberoglio commented 1 month ago

Así está bien. No es necesario guardar en un vector auxiliar. Un cartón es una "matriz" de 3 filas por 5 columnas, pero para el compilador en realidad es un vector de 3 elementos, donde cada elemento es un vector de 5 enteros, entonces en la función controlarCarton, carton[i] es la fila i, o sea el i-ésimo elemento de carton: un vector de 5 enteros. Y TipoLinea es un alias para un vector de enteros, entonces es lo mismo decir int controlarLineas(TipoLinea fila){ que int controlarLineas(int fila[]){

Cualquier duda avisanos.