• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Wczytywanie mapy i elementów z pliku

Object Storage Arubacloud
0 głosów
232 wizyt
pytanie zadane 6 listopada 2020 w C i C++ przez Xarcane Początkujący (440 p.)
zamknięte 6 listopada 2020 przez Xarcane

Zastanawiam się nad wczytywaniem jednostek z pliku do programu,obecna konstrukcja mi się nie podoba,myślę że da się to zrobić lepiej a ja to za bardzo zagmatwałem, i takie wczytywanie powoduje duże ryzyko wystąpienia błędów, możecie coś poradzić'? Oto mój kod:

Plik txt.

Load=[Creature][PositionX][PositionY]
[Slime][100][100]
[Slime][200][200]
[Slime][300][300]

Plik File Manager

enum LoadState { ATTRIBUTES, CONTENTS };

int state;

void FileManager::LoadContent(const char* filename, std::vector<std::vector<std::string>>& attributes,
    std::vector<std::vector<std::string>>& contents)
{
    attributes.clear();
    contents.clear();

    std::ifstream openfile(filename);
    if (openfile.is_open())
    {
        while (!openfile.eof())
        {
            std::string line;

            std::getline(openfile, line);

            line.erase(std::remove(line.begin(), line.end(), ' '), line.end());

            if (line.find("Load=") != std::string::npos)
            {
                state = ATTRIBUTES;
                line.erase(0, line.find('=') + 1);
                tempAttributes.clear();
            }
            else
            {
                state = CONTENTS;
                tempContents.clear();
            }

            line.erase(std::remove(line.begin(), line.end(), '['), line.end());

            std::stringstream str(line);
            while (str)
            {
                std::getline(str, line, ']');
                if (line != "")
                {
                    if (state == ATTRIBUTES)
                        tempAttributes.push_back(line);
                    else
                        tempContents.push_back(line);
                }
            }

            if (state == CONTENTS && tempContents.size() > 0)
            {
                attributes.push_back(tempAttributes);
                contents.push_back(tempContents);
            }
        }
    }
    else
    {
    }
}

Fragment kodu gdzie wczytuje dane do programu:

characterType.insert(std::make_pair("Slime", Character::Slime));
file.LoadContent("level0.txt", attributes, contents);

    for (int i = 0; i < attributes.size(); i++)
    {
        for (int j = 0; j < attributes[i].size(); j++)
        {
            std::string att = attributes[i][j];
            std::string con = contents[i][j];

            if (att == "Creature")
            {
                std::map<std::string, Character::Type>::iterator it = characterType.begin();
                while (it != characterType.end())
                {
                    if (it->first == contents[i][j])
                    {   
                        std::unique_ptr<Character> enemy(new Character(it->second, mTextures));
                        mSceneLayers[Upper]->attachChild(std::move(enemy));
                    }
                    it++;
                }
            }
        }
    }
}

W tym fragmencie nie przypisuje pozycji jednostce. Mógłbym zrobić tak że: If att == PositionX then etity[entity.size()-1].position.x = contents[i][j]. Ale co jak powstaną potem inne elementy entity,nie tylko potwory ale tez kafelki. To wszystko dałoby się "JAKOŚ" zrobić ale to strasznie potem jest namieszane. Nie wiem czy obrałem zły sposób wczytywania tego wszystkiego czy coś, ale prosiłbym o jakiś wzorzec,pomysł. Plik txt będzie wyglądał tak:

Load=[Creature][PositionX][PositionY]
[Slime][100][100]
[Slime][200][200]
[Slime][300][300]

Load=[Tile][PositionX][PositionY][Move]
[Dirt][100][100][0]
[Stone][100][100][1]

Staram się to jakoś rozwiązać ale ciągle mnie to niesatysfakcjonujące,ktoś może mi dać jakiś pomysł,artykuł, cokolwiek? 

komentarz zamknięcia: Rozwiązane

1 odpowiedź

+1 głos
odpowiedź 6 listopada 2020 przez tangarr Mędrzec (154,860 p.)
wybrane 6 listopada 2020 przez Xarcane
 
Najlepsza

Niezależnie od wybranego formatu danych w pliku zawsze może się pojawić błąd. Powinieneś dodać sprawdzanie formatu/struktury wczytywanych danych. W razie jakiegokolwiek problemu (za mało pól w linii, za dużo pól w linii, błąd w parsowaniu wartości, niepoprawne użycie nawiasów, niezamknięcie nawiasu, itp) powinieneś przerywać wczytywanie i zwracać błąd (możesz użyć wyjątków do tego).

Jeżeli chcesz zrobić elastyczny format danych to możesz się zainteresować jakimiś popularnymi formatami danych (np XML, JSON). Możesz sam napisać do nich parser (trudniejsze) lub użyć gotowej biblioteki.

Przykładowy plik JSON zawierający twoją mapę:

{
    "Creatures": [
         {"Type":"Slime", "x":100, "y":100},
         {"Type":"Slime", "x":100, "y":200},
         {"Type":"Slime", "x":100, "y":300}
     ],
     "Tiles":[
         {"Type":"Dirt", "x":100, "y":100, "Move":0}
     ]
}
komentarz 6 listopada 2020 przez Xarcane Początkujący (440 p.)
A jaką biblioteke do parsowania polecasz?
komentarz 6 listopada 2020 przez tangarr Mędrzec (154,860 p.)
Zazwyczaj używam parsera z biblioteki Qt. Jednak dodawanie takiego kombajnu do swojego programu tylko ze względu na jedną funkcjonalność wydaje się strzelaniem z armaty do wróbli.

RapidJSON wydaje się ciekawą alternatywą https://rapidjson.org/index.html

Podobne pytania

0 głosów
0 odpowiedzi 85 wizyt
pytanie zadane 6 marca 2017 w Inne języki przez Pulsar Nowicjusz (120 p.)
0 głosów
5 odpowiedzi 682 wizyt
pytanie zadane 28 kwietnia 2016 w C i C++ przez Munvik Dyskutant (9,350 p.)
0 głosów
1 odpowiedź 501 wizyt
pytanie zadane 7 maja 2015 w C i C++ przez molaki Obywatel (1,700 p.)

92,657 zapytań

141,551 odpowiedzi

319,991 komentarzy

62,026 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...