• 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

VPS Starter Arubacloud
0 głosów
214 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,780 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,780 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 82 wizyt
pytanie zadane 6 marca 2017 w Inne języki przez Pulsar Nowicjusz (120 p.)
0 głosów
5 odpowiedzi 635 wizyt
pytanie zadane 28 kwietnia 2016 w C i C++ przez Munvik Dyskutant (9,350 p.)
0 głosów
1 odpowiedź 491 wizyt
pytanie zadane 7 maja 2015 w C i C++ przez molaki Obywatel (1,700 p.)

92,452 zapytań

141,262 odpowiedzi

319,079 komentarzy

61,854 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

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 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!

...