#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>


typedef enum { BEAR, BIRD, PANDA} AnimalType;

typedef enum { ALIVE, DEAD } AnimalStatus;

typedef struct {
    int x;
    int y;
} Location;

typedef enum { FEEDING, NESTING, WINTERING } SiteType;

typedef struct {
    /** animal can be DEAD or ALIVE*/
    AnimalStatus status;
    /** animal type, bear, bird, panda*/
    AnimalType type;
    /** its location in 2D site grid*/
    Location location;
} Animal;

/*example usage*/
Animal bird, bear, panda;

/** type of Hunter*/
typedef struct {
    /** points indicate the number of animals, a hunter killed*/
    int points;
    /** its location in the site grid*/
    Location location;
} Hunter;

/** type of a site (a cell in the grid)*/
typedef struct {
    /** array of pointers to the hunters located at this site*/
    Hunter **hunters;
    /** the number of hunters at this site*/
    int nhunters;
    /** array of pointers to the animals located at this site*/
    Animal **animals;
    /** the number of animals at this site*/
    int nanimals;
    /** the type of site*/
    SiteType type;
} Site;

/** 2D site grid*/
typedef struct {
    /** number of rows, length at the x-coordinate*/
    int xlength;
    /** number of columns, length at the y-coordinate*/
    int ylength;
    /** the 2d site array*/
    Site **sites;
} Grid;

/* initial grid, empty*/
Grid grid = {0, 0, NULL};

/**
 * @brief initialize grid with random site types
 * @param xlength
 * @param ylength
 * @return Grid
 */
Grid initgrid(int xlength, int ylength) {
    grid.xlength = xlength;
    grid.ylength = ylength;

    grid.sites = (Site **)malloc(sizeof(Site *) * xlength);
    for (int i = 0; i < xlength; i++) {
        grid.sites[i] = (Site *)malloc(sizeof(Site) * ylength);
        for (int j = 0; j < ylength; j++) {
            grid.sites[i][j].animals = NULL;
            grid.sites[i][j].hunters = NULL;
            grid.sites[i][j].nhunters = 0;
            grid.sites[i][j].nanimals = 0;
            double r = rand() / (double)RAND_MAX;
            SiteType st;
            if (r < 0.33)
                st = WINTERING;
            else if (r < 0.66)
                st = FEEDING;
            else
                st = NESTING;
            grid.sites[i][j].type = st;
        }
    }

    return grid;
}

/**
 * @brief
 *
 */
void deletegrid() {
    for (int i = 0; i < grid.xlength; i++) {
        free(grid.sites[i]);
    }

    free(grid.sites);

    grid.sites = NULL;
    grid.xlength = -1;
    grid.ylength = -1;
}

/**
 * @brief prints the number animals and hunters in each site
 * of a given grid
 * @param grid
 */
void printgrid() {
    for (int i = 0; i < grid.xlength; i++) {
        for (int j = 0; j < grid.ylength; j++) {
            Site *site = &grid.sites[i][j];
            int count[3] = {0}; /* do not forget to initialize*/
            for (int a = 0; a < site->nanimals; a++) {
                Animal *animal = site->animals[a];
                count[animal->type]++;
            }

            printf("|%d-{%d, %d, %d}{%d}|", site->type, count[0], count[1],
                   count[2], site->nhunters);
        }
        printf("\n");
    }
}

/**
 * @brief prints the info of a given site
 *
 */
void printsite(Site *site) {//bu üstteki kısmın aynısı gibi//GPTDE BUNU DA YAZMAMIŞ AQ
    int count[3] = {0}; /* do not forget to initialize*/
    for (int a = 0; a < site->nanimals; a++) {
        Animal *animal = site->animals[a];
        count[animal->type]++;
    }
    printf("|%d-{%d,%d,%d}{%d}|", site->type, count[0], count[1], count[2],
           site->nhunters);
}

/*
============================================================= 
TODO: you need to complete following three functions 
DO NOT CHANGE ANY OF THE FUNCTION NAME OR TYPES
============================================================= 
*/

void move(Animal *animal, Site *site){
    srand(time(0));
    int dx=rand() %3 - 1 ;//-1 0 1
    int dy=rand() %3 - 1 ;
    
    animal->location.x += dx;
    animal->location.y += dy;
     
    if (animal->location.x < 0) animal->location.x = 0;
    if (animal->location.y < 0) animal->location.y = 0;
    if (animal->location.x >= grid.xlength) animal->location.x = grid.xlength - 1;
    if (animal->location.y >= grid.ylength) animal->location.y = grid.ylength - 1;
    
    return ???//
    
    
}


/**
 * @brief  it moves a given hunter or animal
 * randomly in the grid
 * @param args is an animalarray
 * @return void*
 */
void *simulateanimal(void *args) {
    /*TODO: complete this function:
        get animal type,
        check if animal dies,
        then chose random direction and move
        make sure to update site.animals
        then sleep
    */
    
     Animal *animal = (Animal *)args;
     srand(time(0));
      animal->location.x = rand() % grid.xlength;
      animal->location.y = rand() % grid.ylength;
     

    while (1) {
        // Check if the animal is dead
        if (animal->status == DEAD) {
            // Free resources and terminate the thread
            pthread_exit(NULL);
        }
 

        Site *site = &grid.sites[animal->location.x][animal->location.y];

        // Animal behavior based on the site type
        switch (site->type) {
            case NESTING:
                // Populate 1 of its kind at that site and move to a neighboring random location
              //  if (site->nanimals < site->capacity) {//BI KAPASITE VAR MI Kİ YOKMUŞ O YÜZDEN IFSIZCE YAPILIR
                    // Create a new animal of the same type
                    
                    Animal *new_animal = (Animal *)malloc(sizeof(Animal));
                   // Animal *new_animal = createanimal(animal->type, animal->location.x, animal->location.y);
                    *new_animal = *animal;
                    new_animal->location = animal->location;
                    site->animals[site->nanimals++] = new_animal;//CREATE ANIMAL DIYE FONK MU VAR AMK
                    
                    pthread_t animal_threads[num_animals+1];
                    pthread_create(&animal_threads[num_animals+1], NULL, simulateanimal, (void *)new_animal);
             //   }

                // Move to a neighboring random location
                move(animal, site); 
                break;
            case WINTERING:
                // Die with 0.5 probability or live and move to a neighboring random location
                if (rand() % 2 == 0) {
                    // Die
                    animal->status = DEAD;
                } else {
                    // Move to a neighboring random location
                    move(animal, site);
                }
                break;
            case FEEDING:
                // Stay with 0.8 probability or move to a neighboring random location
                if (rand() % 10 < 2) {
                  
              
                    // Move to a neighboring random location
                    move(animal, site);//BU NEYI RETURN EDER
                }
                break;
        }

        // Sleep for 1 millisecond
        sleep(0.001);
    }
    
    
    
    return NULL;
}

/**
 * @brief simulates the moving of a hunter
 *
 * @param args
 * @return void*
 */
void *simulatehunter(void *args) {
    /*TODO: get random position and move,
    then  kill all the animals in this site,
    increase count,
    then sleep*/
    
    Hunter *hunter = (Hunter *)args;  
       srand(time(0));
        hunter->location.x= rand() % grid.xlength;
        hunter->location.y= rand() % grid.ylength;
         
    while (1) {   
        // Get a random position and move
        srand(time(0));
        int newX = rand() %3 - 1 ;//-1 0 1
        int newY=rand() %3 - 1 ;
      

        // Update the hunter's location
        hunter->location.x += newX;
        hunter->location.y += newY;
        
        if (hunter->location.x < 0) hunter->location.x = 0;
        if (hunter->location.y < 0) hunter->location.y = 0;
        if (hunter->location.x >= grid.xlength) hunter->location.x = grid.xlength - 1;
        if (hunter->location.y >= grid.ylength) hunter->location.y = grid.ylength - 1;

        // Kill all the animals in the site and increase the count
        Site *site = &grid.sites[hunter->location.x][hunter->location.y];
        for (int i = 0; i < site->nanimals; i++) {
            site->animals[i]->status = DEAD;
            hunter->points++;
        }

        // Sleep for 1 millisecond
        sleep(0.001);//1 milisaniye 
    }
    
    
    return NULL;
}

/**
 * the main function for the simulation
 */
int main(int argc, char *argv[]) {
  /*TODO argv[1] is the number of hunters*/
   if (argc != 2) {
        printf("Hata:Mesela ./main 2 şeklinde yazmanız gerekir. \n", argv[0]);
        return 1;
    }
    int num_hunters = atoi(argv[1]);//BU KISIM YERINE 4 VS GIREREK DENENEBILIR SORUNSA
    int num_animals=3;
    
    initgrid(5, 5);
    /*TODO: init threads for each animal, and hunters, 
        the program should end after 1 second
     */
     Animal animals[] = {bird, bear, panda};//BUNU YAZMAK GEREKSIZ BENCE
    
    Hunter hunters[num_hunters];
     
      pthread_t animal_threads[num_animals];
    for (int i = 0; i < num_animals; i++) {
        pthread_create(&animal_threads[i], NULL, simulateanimal, (void *)&animals[i]);
    }
     
      pthread_t hunter_threads[num_hunters];
    for (int i = 0; i < num_hunters i++) {
        pthread_create(&hunter_threads[i], NULL, simulatehunter, (void *)&hunters[i]);
    }
    
     for (int i = 0; i < num_animals; i++) {
        pthread_join(animal_threads[i], NULL);
    }

     for (int i = 0; i < num_hunters; i++) {
        pthread_join(hunter_threads[i], NULL);
    }
    //BURDA 1 SN USLEEP DEMIŞ AMA BILMIYOM  BUNU DÖNGÜLETMEK GEREKEBILIR
    printgrid();
   deletegrid();
}
What are the mistakes in this code