#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

typedef struct str {
    char* child;
    struct str* next;
} NO;

typedef struct {
    NO* head;
} LIST;



int SizeList(LIST *l) {
    NO* p = l->head->next;
    int tam = 0;
    while (p != l->head)
    {
        tam++;
        p = p->next;
    }
    return(tam);
}

void showList(LIST *l) {
    NO* p = l->head;
    printf("head->");
    while(p->next != l->head)
    {
        p = p->next;
        printf("%s->", p->child);
    }
    if(p->next == l->head) printf("head \n");
    printf("\n\n");
}

void IniList(LIST* l) {
    l->head = (NO*)malloc(sizeof(NO));
    l->head->next = l->head;
    
    //assim mesmo que imprima o valor do head não estara a aceder a uma zona de memoria invalida
    l->head->child = malloc(sizeof(char)); 
    *(l->head->child) = '\0';
}

NO* nChild(LIST *l, int n, NO** bef) {
    NO* p = l->head->next;
    *bef = l->head;//iniciliazação que estava em falta de bef
    int i = 0;
    while ((p != l->head) && (i < n)) //aqui de n-1 para n
    {
        *bef = p;
        p = p->next;
        i++;
    }

    return i >= SizeList(l) ? NULL : p; //troquei if para ternario assim como condição
}

NO* LastChild(LIST *l) {
    NO* p = l->head->next;
    if(p == l->head) return l->head;
    while(p->next != l->head)
    {
        p = p->next;
    }
    return p;
}

void insChild(LIST* l, char name[]) { //simplifiquei bastante o código
    NO* p = LastChild(l);
    NO* newnode = (NO*)malloc(sizeof(NO)); //conjuguei declaração com atribuição
    newnode->child = malloc((strlen(name)+1)*sizeof(char)); 
    strcpy(newnode->child, name);
    newnode->next = l->head;
    p->next = newnode;
}

void DelChild (LIST* l)
{
    int slist = SizeList(l);
    if (slist == 1 )
    {
        NO* p = l->head->next;
        printf("\nCriança Vencedora: %s\n", p->child);
        return;
    }
    else
    {
        int del = rand() % slist; //de slist-1 para slist
        printf("RANDOM: %d\n", del);

        NO* bef;
        NO* p = nChild(l, del, &bef);
        if (p)//retirei o if(!p) return; que assim fica mais simples
        {
            bef->next = p->next;
            free(p);
        } 
    }
}

int main() {
    LIST l;
    IniList(&l);
    int op = 0;

    while (op != 3)
    {
        printf("\nDigite o numero a operacao desejada:\n");
        printf("\n\n1.Inserir Crianca \t\t2.Remover Crianca \t\t3.Exit\n\n");
        scanf("%d", &op);

        char name[100];
        switch(op)
        {

        case 1:
            printf("\nDigite o nome a inserir:\n");
            scanf("%s", name);
            insChild(&l, name);
            showList(&l);
            break;

        case 2:
            DelChild(&l);
            showList(&l);
            break;
        case 3:
            break;
        default:
            printf("Digite uma opção válida!\n");
        }
    }

    return 0;
}
