samedi 15 août 2020

C program compiles and runs but skips if-else evaluation randomly when executed

EDIT: Filled in complete code, sorry.

I am having trouble with a simple program that compiles and runs, but sometimes when it is executed it does not evaluate an if-else statement correctly and runs away into an infinite loop.

I thought it was pretty simple, straight-forward code, but for some reason it's buggy.

It is two structs of type Character evaluating an attack value and removing that amount from each of their health attributes in turn. It is supposed to evaluate whether the particular character's health is at or below 0 after adjusting the health value and exit the loop accordingly.

It worked fine when I wrote it with just one struct, but now that I have two structs in the function it seems to be hit or miss.

It all works correctly otherwise, the random attack value calculation, the adjustment of the health attribute, printing the struct info to console, but the loop doesn't always break, so it's not always evaluating to 'true' as it should.

Any thoughts on this on what may make this if-else evaluation sensitive?

Running Raspbian on Pi 3 B+

Compiling with gcc

Writing code in Visual Studio Code

Exact code

// main.c

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

#define WEAPON_INV_SIZE     5

/* Weapon, attack types */
enum Hand_type
{
    ONE_H,
    TWO_H,
    RANGED,
    MAGIC
};

struct Weapon
{
    char            name[64];
    int             level;
    int             minDamage;
    int             maxDamage;
    unsigned char   type;
};

/* Holds player current and maximum health amount */
struct Health
{
    unsigned int    currentHealth;
    unsigned int    maxHealth;
};

/* Holds player attributes */
struct Character
{
    char            name[64];
    unsigned int    expPoints;
    struct Health   health;

    float           attackBonus[4];

    struct Weapon * weaponInventory[WEAPON_INV_SIZE];
    struct Weapon * currentWeapon;
};

/* Holds weapon attributes */
struct Weapon * GetWeapon (char * name, int minDamage, int maxDamage, unsigned char type)
{
    struct Weapon * w = (struct Weapon *)malloc (sizeof(struct Weapon));
    strcpy (w->name, name);
    w->level = 1;
    w->minDamage = minDamage;
    w->maxDamage = maxDamage;
    w->type = type;
    return w;
}

/* Get random int from range between two ints */
int Random_Range (int lower, int greater)
{
    return (rand () % (greater - lower)) + lower;
}

/* Adjust character health */
void AdjustHealth (struct Character * character, int minAmount, int maxAmount)
{
    character->health.currentHealth += minAmount;
    character->health.maxHealth += maxAmount;
}


/* Two character battle sequence */
void Battle_2 (struct Character * char1, struct Character * char2)
{
    int min1 = (int)((float)char1->currentWeapon->minDamage * char1->attackBonus[char1->currentWeapon->type]);
    int max1 = (int)((float)char1->currentWeapon->maxDamage * char1->attackBonus[char1->currentWeapon->type]);
    int diff1 = max1 - min1;

    int min2 = (int)((float)char2->currentWeapon->minDamage * char2->attackBonus[char2->currentWeapon->type]);
    int max2 = (int)((float)char2->currentWeapon->maxDamage * char2->attackBonus[char2->currentWeapon->type]);
    int diff2 = max2 - min2;

    while (1)
    {
        AdjustHealth (char2, -(min1 + rand () % diff1), 0);

        if (char2->health.currentHealth <= 0)
        {
            printf ("Character 2 is dead!!!\n");
            break;
        }
        else
        {
            printf ("%3d/%3d : %3d/%3d\n",  char1->health.currentHealth, 
                                            char1->health.maxHealth,
                                            char2->health.currentHealth, 
                                            char2->health.maxHealth);
        }

        AdjustHealth (char1, -(min2 + rand () % diff2), 0);
        
        if (char1->health.currentHealth <= 0)
        {
            printf ("Character 1 is dead!!!\n");
            break;
        }
        else
        {
            printf ("%3d/%3d : %3d/%3d\n",  char1->health.currentHealth, 
                                            char1->health.maxHealth,
                                            char2->health.currentHealth, 
                                            char2->health.maxHealth);
        }
    }
    
}

int main ()
{
    srand (time (0));

    struct Character myChar01 = 
    {
        "My name",
        0,
        {100, 100},
        {1, 1.5, 1, .75},
        {},
        0
    };

    struct Character myChar02 = 
    {
        "Not my name",
        0,
        {100, 100},
        {1, 1.5, 1, .75},
        {},
        0
    };  

    /* Populate weapon inventory with new weapons */
    myChar01.weaponInventory[0] = GetWeapon ("Dagger", 1, 5, ONE_H);
    myChar01.weaponInventory[1] = GetWeapon ("Sword", 4, 8, TWO_H);
    myChar01.weaponInventory[2] = GetWeapon ("Wood Bow", 1, 6, RANGED);
    myChar01.weaponInventory[3] = GetWeapon ("Root Wand", 3, 7, MAGIC);

    /* Assign current weapons */
    myChar01.currentWeapon = myChar01.weaponInventory[0];
    myChar02.currentWeapon = myChar01.weaponInventory[2];

    /* Enter Battle sequence */
    Battle_2 (&myChar01, &myChar02);
    
    return 0;
    
}

Aucun commentaire:

Enregistrer un commentaire