PI-ITBA / 2024_01

8 stars 0 forks source link

hangmanADT parcial 2C 2016 #308

Closed nicanovotny closed 3 months ago

nicanovotny commented 3 months ago

Hola Marcelo, quería ver las correcciones del código. Saludos.

#include "hang.h"
#define BLOQUE 10
#include <stdlib.h>
#include <string.h>
#include "../../../random.h"

typedef struct 
{
    int dim; // cantidad
    int size; // espacio reservado
    char ** vec;
}lvl;

struct hangmanCDT
{
    lvl *vec;
    int maxLevel;
};

/* Crea la estructura que dará soporte al almacenamiento y selección de palabras
** maxLevel: la cantidad máxima de niveles de dificultad que soportará (como mínimo 1)
** Los niveles válidos serán de 1 a maxLevel inclusive
 */
hangmanADT newHangman(unsigned int maxLevel)
{
    hangmanADT new = malloc(sizeof(struct hangmanCDT));
    new->maxLevel = maxLevel;
    new->vec = calloc(maxLevel, sizeof(lvl));
    return new;
}

/* Agrega un conjunto de palabras asociadas a un nivel de dificultad.
** El arreglo words[] está finalizado en NULL
** Si alguna de las palabras de words[] ya existe en el hangmanADT para ese nivel de dificultad
** se ignora.
** No se realiza una copia local de cada palabra sino únicamente los punteros recibidos
** Si el nivel supera la cantidad máxima definida en newHangman, se ignora y retorna -1
** Retorna cuántas palabras se agregaron al nivel
*/
int addWords(hangmanADT h, char * words[], unsigned int level)
{
    if (level < 1 || level > h->maxLevel)
        return -1;
    int idx = level - 1;
    int resp = 0;
    for (int i = 0, flag; words[i] != NULL; i++)
    {
        flag = 1;
        for (int j = 0; flag && j < h->vec[idx].dim; j++)
        {
            if (strcmp(words[i], h->vec[idx].vec[j]) == 0)
                flag = 0;
        }
        if (flag)
        {
            if (h->vec[idx].dim == h->vec[idx].size)
            {
                h->vec[idx].size += BLOQUE;
                h->vec[idx].vec = realloc(h->vec[idx].vec, h->vec[idx].size * sizeof(char *)); 
            }
            h->vec[idx].vec[h->vec[idx].dim++] = words[i];
            resp++;
        }
    }
    return resp;
}

/* Retorna cuántas palabras hay en un nivel, -1 si el nivel es inválido */
int size(const hangmanADT h, unsigned int level)
{
    if (level < 1 || level > h->maxLevel)
        return -1;
    return h->vec[level - 1].dim;
}

/* Retorna una palabra al azar de un nivel determinado, NULL si no hay palabras de ese nivel
** o si el nivel es inválido. 
*/
char * word(const hangmanADT h, unsigned int level)
{
    int idx = level - 1;
    if (level < 1 || level > h->maxLevel || h->vec[idx].dim == 0)
        return NULL;
    int random = randInt(0, h->vec[idx].dim - 1);
    return h->vec[idx].vec[random];
}

/* Retorna todas las palabras de un nivel, o NULL si el nivel es inválido
** El último elemento del vector es el puntero NULL
*/
char ** words(const hangmanADT h, unsigned int level)
{
    if (level < 1 || level > h->maxLevel)
        return NULL;
    int idx = level - 1, nuevaDim;
    char ** resp = NULL;
    for (nuevaDim = 0; nuevaDim < h->vec[idx].dim; nuevaDim++)
    {
        if (nuevaDim % BLOQUE == 0)
            resp = realloc(resp, (nuevaDim + BLOQUE) * sizeof(char *));
        resp[nuevaDim] = malloc(strlen(h->vec[idx].vec[nuevaDim]) + 1);
        strcpy(resp[nuevaDim], h->vec[idx].vec[nuevaDim]);
    }
    resp = realloc(resp, (nuevaDim + 1) * sizeof(char *));
    resp[nuevaDim] = NULL;
    return resp;
}
marcelogarberoglio commented 3 months ago

Está muy bien En la función words podrías hacer un malloc para el vector, porque ya sabés cuántas palabras tiene