mardi 24 novembre 2020

Dynamically allocate and initialize new object with 30% probability

I'm writing a program that will simulate a randomized race between runners who are climbing up a mountain where dwarf orcs (dorcs) are coming down the mountain to attack the runners. It begins with two runners named harold and timmy at the bottom of the mountain. The runners make their way up the mountain in randomized moves where they may make progress forward up the mountain, or they may slide back down the mountain. Dorcs are randomly generated, and they inflict damage on a runner if they collide. The simulation ends when one of the runners reaches the top of the mountain, or when both runners are dead.

I'm struggling with a part where I have to implement the actual race loop. Once the race is initialized, the race loop will iterate until the race is over. This happens when either a winner has been declared, or when all runners are dead.

Every iteration of the race loop will do the following:

with 30% probability, dynamically allocate a new dorc as an EntityType structure, and initialize it as follows:

(a) a dorc’s avatar is always “d”

(b) each dorc begins the race at the top of the mountain, which is at row 2

(c) with equal probability, the dorc may be placed either in the same column as timmy, or in the same column as the harold, or in the column exactly half-way between the two

(d) add the new dorc to the race’s array of dorcs

(e) using the pthread_create() function, create a thread for the new dorc, and save the thread pointer in the dorc’s entity structure; the function that each dorc thread will execute is the void* goDorc(void*) function that you will implement in a later step; the parameter to the goDorc() function will be the EntityType pointer that corresponds to that dorc

I guess I'm confused with the logic of how to approach this. I decided to make a function called isOver() to indicate if the race is over, and then a separate function called addDorc() to initialize the Dorc elements and do all the requirements above.

In isOver(), I attempt to add a dorc object to the dorcs array by doing addDorc(race); with every iteration of the race loop/if the race hasn't ended or no one died. But I keep getting the error:

control.c:82:3: error: too few arguments to function ‘addDorc’
   addDorc(race);

The problem is I don't think I can manually declare all the parameters in addDorc() because some elements like the "path" argument are based on probability. As mentioned above, with equal probability, the dorc may be placed either in the same column as timmy, or in the same column as the harold, or in the column exactly half-way between the two. The issue is I don't know how to factor this random value when calling addDorc() and would appreciate some help. I also don't know if I'm doing the "with 30% probability, dynamically allocate a new dorc as an EntityType structure" correctly and would be grateful for some input on that as well.

defs.h

typedef struct {
  pthread_t thr;
  char avatar[MAX_STR];
  int  currPos; 
  int  path; 
} EntityType;

typedef struct {
  EntityType ent;
  char name[MAX_STR];
  int  health;
  int  dead; 
} RunnerType;

typedef struct {
  int numRunners;
  RunnerType *runners[MAX_RUNNERS];  
  int numDorcs;
  EntityType *dorcs[MAX_DORCS]; 
  char winner[MAX_STR]; 
  int  statusRow; 
  sem_t mutex;
} RaceInfoType;

void launch();
int addDorc(RaceInfoType*, char*, int, int);
int isOver(RaceInfoType*);
void initRunners(RaceInfoType*);
int addRunner(RaceInfoType*, char*, char*, int, int, int, int);

int  randm(int);

void *goRunner(void*);
void *goDorc(void*);

RaceInfoType *race;

control.c

void launch(){

    race = malloc(sizeof(RaceInfoType));
    race->numRunners = 0;
    
    initRunners(race);
    
    if (sem_init(&race->mutex, 0, 1) < 0) {
        printf("semaphore initialization error\n");
        exit(1);
    }
    
    strcpy(race->winner, " ");
    
    
    srand((unsigned)time(NULL));
    
    int i;
    for(i = 0; i < race->numRunners; ++i){
        pthread_create(&(race->runners[i]->ent.thr), NULL, goRunner, " ");
    }
    
    race->numDorcs = 0;
}



int addDorc(RaceInfoType* race, char *avatar, int path, int currPos){ 
    if(race->numDorcs == MAX_DORCS){ 
        printf("Error: Maximum dorcs already reached. \n");
        return 0;
    }       
    race->dorcs[race->numDorcs] = malloc(sizeof(EntityType));
    
    int timmysColumn = race->dorcs[race->numDorcs]->currPos;
    int haroldsColumn = race->dorcs[race->numDorcs]->currPos;
    int halfwayColumn = (timmysColumn+haroldsColumn)/2;
    
    int r = rand()%100;
    
    pthread_t dorc;
    
    if(r <= 30){
        strcpy(race->dorcs[race->numDorcs]->avatar, "d");
        race->dorcs[race->numDorcs]->currPos = 2;
        if(r <= 33){
            race->dorcs[race->numDorcs]->path = timmysColumn;
        }else if(r <= 66){
            race->dorcs[race->numDorcs]->path = haroldsColumn;
        }else{
            race->dorcs[race->numDorcs]->path = halfwayColumn;
        }
        pthread_create(&dorc, NULL, goDorc, " ");
    }
    race->numRunners++;
}

int isOver(RaceInfoType* race){ 
    int i;
    for(i = 0; i < race->numRunners; ++i){
        if((race->winner != " ") || (race->runners[race->numRunners]->dead = 1)){
            return 1;
        }
        addDorc(race);
        return 0;
    }
}
void initRunners(RaceInfoType* r){
    addRunner(r, "Timmy", "T", 10, 35, 50, 0); 
    addRunner(r, "Harold", "H", 14, 35, 50, 0); 
}


int addRunner(RaceInfoType* race, char *name, char *avatar, int path, int currPos, int health, int dead){
    if(race->numRunners == MAX_RUNNERS){ 
        printf("Error: Maximum runners already reached. \n");
        return 0;
    }       
    race->runners[race->numRunners] = malloc(sizeof(RunnerType));
    strcpy(race->runners[race->numRunners]->name, name);
    strcpy(race->runners[race->numRunners]->ent.avatar, avatar);
    race->runners[race->numRunners]->ent.path = path;
    race->runners[race->numRunners]->ent.currPos = currPos;
    race->runners[race->numRunners]->health = health;
    race->runners[race->numRunners]->dead = dead;
    race->numRunners++;
    return 1;
}



Aucun commentaire:

Enregistrer un commentaire