ELEC2645 (2019/20) / Mbed 2 deprecated ELEC2645_Project_el18gs

Dependencies:   mbed

Inventory/Ghost/Ghost.cpp

Committer:
el18gs
Date:
2020-05-11
Revision:
8:4220d116f17c
Parent:
7:220d3ebf74cf
Child:
16:3b298bea3a70

File content as of revision 8:4220d116f17c:

#include "Ghost.h"
#include "mbed.h"

const string Ghost::_suffix = ".ghost";


Ghost::Ghost(const std::string path, const std::string root, SDFileSystem &sd)
{
   string names[20] = {"Saul", "Airon", "Aiden", "Delic", "Airian",
              "Guya", "Tormey", "Muse", "Shayepe", "Lite",
              "Umber", "Haeven", "Elisum", "Fade", "Sentina",
              "Angis", "Lloial", "Aeren", "Angel", "Shayde"
             };
    for(int i = 0; i < 20; i++){
        _names.push_back(names[i]);
    }
    
    _root = root;

    // Connections to SD card holder on K64F (SPI interface)
    //SDFileSystem sd(PTE3, PTE1, PTE2, PTE4, "sd"); // MOSI, MISO, SCK, CS

    FILE *fp;

    fp = fopen(path.c_str(), "r");

    int lines=0;  // going to store the number of lines in the file
    stringvec values;

    if (fp == NULL) {  // if it can't open the file then print error message
        printf("Error! Unable to open file: %s\n", path.c_str());
        listdir(path, sd);
    } else {
        //Since we may not know the
        // number of lines in the files ahead of time, we'll first count them
        // * means scan but don't save

        while (fscanf(fp, "%*s") != EOF) {
            lines++;  // increment counter when read a line
        }

        rewind(fp); // 'scrolled' to end of file, so go back to beginning

        char buffer[15];

        for(int i = 0; i < lines; i++) {
            fscanf(fp, "%s", buffer);
            if(buffer[0] != '/') {
                values.push_back(buffer);
            }
        }

        _type = string_to_type(values[0]);
        _name = values[1];
        sscanf(values[2].c_str(), "%d", &_attack);
        sscanf(values[3].c_str(), "%d", &_defense);
        sscanf(values[4].c_str(), "%d", &_level);
        sscanf(values[5].c_str(), "%d", &_xp);
        sscanf(values[6].c_str(), "%d", &_value);
        sscanf(values[7].c_str(), "%d", &_hp_max);
        sscanf(values[8].c_str(), "%d", &_hp);
        sscanf(values[9].c_str(), "%d", &_uid);

        fclose(fp);
    }
}

Ghost::Ghost(int num, int nameNumber, const std::string root, SDFileSystem &sd)
{
    string names[20] = {"Saul", "Airon", "Aiden", "Delic", "Airian",
              "Guya", "Tormey", "Muse", "Shayepe", "Lite",
              "Umber", "Haeven", "Elisum", "Fade", "Sentina",
              "Angis", "Lloial", "Aeren", "Angel", "Shayde"
             };
             
    for(int i = 0; i < 20; i++){
        _names.push_back(names[i]);
    }
    _root = root;
    _uid = gen_uid(sd);
    int type = 0;
    if ((num > 0) && (num < 50)) {
        type = 0;
    } else if ((num >= 50) && (num < 70)) {
        type = 1;
    } else if ((num >= 70) && (num < 85)) {
        type = 2;
    } else if ((num >= 85) && (num < 95)) {
        type = 3;
    } else {
        type = 4;
    }

    if(type == 0) {
        _attack = 10;
        _defense = 10;
        _level = 1;
        _xp = 0;
        _value = 10;
        _hp_max = 10;
        _hp = _hp_max;
        _type = BASIC;
    } else if(type == 1) {
        _attack = 15;
        _defense = 5;
        _level = 1;
        _xp = 0;
        _value = 15;
        _hp_max = 7;
        _hp = _hp_max;
        _type = ECTO;
    } else if(type == 2) {
        _attack = 5;
        _defense = 15;
        _level = 1;
        _xp = 0;
        _value = 15;
        _hp_max = 13;
        _hp = _hp_max;
        _type = POLTER;
    } else if(type == 3) {
        _attack = 15;
        _defense = 15;
        _level = 1;
        _xp = 0;
        _value = 20;
        _hp_max = 5;
        _hp = _hp_max;
        _type = ORB;
    } else if(type == 4) {
        _attack = 5;
        _defense = 5;
        _level = 10;
        _xp = 10;
        _value = 10;
        _hp_max = 20;
        _hp = _hp_max;
        _type = FUNNEL;
    }
    
    _name = _names[nameNumber];
}

void Ghost::listdir(std::string path, SDFileSystem &sd)
{
    printf("Listing directory: %s\n", path.c_str());
    DIR *d;
    struct dirent *p;

    d = opendir(path.c_str());
    if (d != NULL) {
        while ((p = readdir(d)) != NULL) {
            printf(" - %s\n", p->d_name);
        }
    } else {
        printf("Could not open directory!\n");
    }
    closedir(d);
}

void Ghost::save(SDFileSystem &sd)
{
    FILE *fp; // this is our file pointer

    std::string filepath = "/sd";

    filepath.append(_root);

    char buf[10];
    sprintf(buf, "%d", _uid);

    filepath.append(buf);
    filepath.append(_suffix);

    fp = fopen(filepath.c_str(), "w");

    if (fp == NULL) {  // if it can't open the file then print error message
        printf("Error! Unable to open file!\n");
    } else {  // opened file so can write
        fprintf(fp, "/Type\n");
        fprintf(fp, "%s\n", get_type_string().c_str());
        fprintf(fp, "/Name\n");
        fprintf(fp, "%s\n", get_name().c_str());
        fprintf(fp, "/Attack\n");
        fprintf(fp, "%d\n", get_attack());
        fprintf(fp, "/Defense\n");
        fprintf(fp, "%d\n", get_defense());
        fprintf(fp, "/Level\n");
        fprintf(fp, "%d\n", get_level());
        fprintf(fp, "/XP\n");
        fprintf(fp, "%d\n", get_xp());
        fprintf(fp, "/Value\n");
        fprintf(fp, "%d\n", get_value());
        fprintf(fp, "/HP_Max\n");
        fprintf(fp, "%d\n", get_hp_max());
        fprintf(fp, "/HP\n");
        fprintf(fp, "%d\n", get_hp());
        fprintf(fp, "/UID\n");
        fprintf(fp, "%d\n", get_uid());
        fclose(fp);  // ensure you close the file after writing
    }
}

int Ghost::sell(SDFileSystem &sd)
{

    std::string filepath = "";

    filepath.append(_root);

    char buf[10];
    sprintf(buf, "%d", _uid);

    filepath.append(buf);
    filepath.append(_suffix);

    delete_file(filepath.c_str(), sd);

    return _value;
};

void Ghost::feed(int ammount, SDFileSystem &sd)
{
    _xp = _xp + ammount;

    int new_level = 0;

    if(_xp > 1200) {
        new_level = 10;
    } else if(_xp > 600) {
        new_level = 9;
    } else if(_xp > 300) {
        new_level = 8;
    } else if(_xp > 150) {
        new_level = 7;
    } else if(_xp > 75) {
        new_level = 6;
    } else if(_xp > 38) {
        new_level = 5;
    } else if(_xp > 19) {
        new_level = 4;
    } else if(_xp > 10) {
        new_level = 3;
    } else if(_xp > 5) {
        new_level = 2;
    } else {
        new_level = 1;
    }

    if(new_level > _level) {
        int difference = new_level - _level;
        for(int i = 0; i < difference; i++) {
            _attack++;
            _defense++;
            _level++;
            _hp_max++;
            _hp = _hp_max;
            _value = _attack + _defense + _hp_max;
        }
    }

    save(sd);
}

void Ghost::print_all(void)
{
    printf("\n Print out for Ghost: %s\n", get_name().c_str());
    printf("--------------------");
    printf("\n");
    printf("Type: %s\n", get_type_string().c_str());
    printf("Attack: %d\n", get_attack());
    printf("Defense: %d\n", get_defense());
    printf("Level: %d\n", get_level());
    printf("XP: %d\n", get_xp());
    printf("Value: %d\n", get_value());
    printf("HP Max: %d\n", get_hp_max());
    printf("HP: %d\n", get_hp());
    printf("UID: %d\n", get_uid());
}

Type Ghost::get_type_enum(void)
{
    return _type;
}

std::string Ghost::get_type_string(void)
{
    return type_to_string(_type);
}

std::string Ghost::get_name(void)
{
    return _name;
}

int Ghost::get_attack(void)
{
    return _attack;
}

int Ghost::get_defense(void)
{
    return _defense;
}

int Ghost::get_level(void)
{
    return _level;
}

int Ghost::get_xp(void)
{
    return _xp;
}

int Ghost::get_value(void)
{
    return _value;
}

int Ghost::get_hp_max(void)
{
    return _hp_max;
}

int Ghost::get_hp(void)
{
    return _hp;
}

int Ghost::get_uid(void)
{
    return _uid;
}

int Ghost::gen_uid(SDFileSystem &sd)
{
    std::string path = "/sd/ghosts";
    printf("Listing directory: %s\n", path.c_str());
    DIR *d;
    struct dirent *p;

    stringvec files;

    d = opendir(path.c_str());
    if (d != NULL) {
        while ((p = readdir(d)) != NULL) {
            files.push_back(p->d_name);
        }
    } else {
        printf("Could not open directory!\n");
    }
    closedir(d);

    stringvec correct_files;

    for(int i = 0; i < files.size(); i++) {
        if(hasEnding(files[i], ".ghost")) {
            correct_files.push_back(files[i]);
        }
    }

    std::vector<int> used_ids;

    for(int i = 0; i < correct_files.size(); i++) {
        std::string temp = correct_files[i].substr(0, correct_files[i].length() - 6);
        int x;
        sscanf(temp.c_str(), "%d", &x);
        used_ids.push_back(x);
    }
    int max = -1;
    for(int i = 0; i < used_ids.size(); i++) {
        if(used_ids[i] > max) {
            max = used_ids[i];
        }
    }

    max++;
    return max;

}

bool Ghost::hasEnding (std::string const &fullString, std::string const &ending)
{
    if (fullString.length() >= ending.length()) {
        return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
    } else {
        return false;
    }
}

std::string Ghost::type_to_string(Type type)
{
    if(type == BASIC) {
        return "BASIC";
    } else if (type == ECTO) {
        return "ECTOPLASM";
    } else if (type == POLTER) {
        return "POLTERGIEST";
    } else if (type == ORB) {
        return "ORB";
    } else if (type == FUNNEL) {
        return "FUNNEL";
    } else {
        return "NULL";
    }
}

Type Ghost::string_to_type(std::string type)
{
    if(type == "BASIC") {
        return BASIC;
    } else if (type == "ECTOPLASM") {
        return ECTO;
    } else if (type == "POLTERGIEST") {
        return POLTER;
    } else if (type == "ORB") {
        return ORB;
    } else if (type == "FUNNEL") {
        return FUNNEL;
    } else {
        return BASIC;
    }
}


void Ghost::delete_file(const char filename[], SDFileSystem &sd)
{
    printf("Deleting file '%s'...\n", filename);
    FILE *fp = fopen(filename, "r");  // try and open file
    if (fp != NULL) {  // if it does open...
        fclose(fp);    // close it
        remove(filename);  // and then delete
        printf("Done!\n");
    } else {
        printf("could not find file '%s', could not delete \n", filename);
    }
    // if we can't open it, it doesn't exist and so we can't delete it
}