2015-12-07 4 views
0

Dans mon jeu, je garde une trace des niveaux déverrouillés avec un vecteur std::vector<bool> lvlUnlocked_;.Utiliser une boucle avec std :: strcmp pour charger beaucoup de paramètres

La fonction simple pour enregistrer le progrès est la suivante:

void save() { 
    std::stringstream ss; 
    std::string stringToSave = ""; 
    std::ofstream ofile("./progress.txt"); 

    if (ofile.good()) { 
    ofile.clear(); 
    for (std::size_t i = 0; i < levelUnlocked_.size(); ++i) { 
     ss << "lvl" << i << "=" << (lvlUnlocked_.at(i) ? "1" : "0") << std::endl; 
    } 
    stringToSave = ss.str(); 
    ofile << stringToSave; 
    ofile.close(); 
    } 
} 

Cela fonctionne et est agréable car je peux utiliser une boucle pour vider l'info.

maintenant à la partie où je suis coincé, la partie inférieure de ma fonction de charge (voir le commentaire dans le code ci-dessous):

void load() { 
    std::ifstream ifile("./progress.txt"); 

    if (ifile.good()) { 
    int begin; 
    int end; 
    std::string line; 
    std::string stringKey = ""; 
    std::string stringValue = ""; 
    unsigned int result; 

    while (std::getline(ifile, line)) { 
     stringKey = ""; 
     stringValue = ""; 
     for (unsigned int i = 0; i < line.length(); i++) { 
     if (line.at(i) == '=') { 
      begin = i + 1; 
      end = line.length(); 
      break; 
     } 
     } 
     for (int i = 0; i < begin - 1; i++) { 
     stringKey += line.at(i); 
     } 
     for (int i = begin; i < end; i++) { 
     stringValue += line.at(i); 
     } 

     result = static_cast<unsigned int>(std::stoi(stringValue)); 

     // usually I now compare the value and act accordingly, like so: 
     if (std::strcmp(stringKey.c_str(), "lvl0") == 0) { 
     lvlUnlocked_.at(0) = true; 
     } else if (std::strcmp(stringKey.c_str(), "lvl1") == 0) { 
     lvlUnlocked_.at(1) = true; 
     } else if (std::strcmp(stringKey.c_str(), "lvl2") == 0) { 
     lvlUnlocked_.at(2) = true; 
     } 
     // etc.... 

    } 
    } 
} 

Cela fonctionne très bien, mais ...

le problème est que j'ai plus de 100 niveaux et je veux qu'il soit dynamique basé sur la taille de mon vecteur lvlUnlocked_ au lieu d'avoir à taper tout comme dans le code ci-dessus.

Existe-t-il un moyen d'utiliser une boucle comme dans ma fonction de sauvegarde pour vérifier tous les niveaux?

+2

Pourquoi utiliser des chaînes du tout? C'est lent et douloureux, ne pouvez-vous pas implémenter une paire clé-valeur? – Neijwiert

+0

si (std :: strncmp (stringKey.c_str(), "lvl", 3) == 0) lvlUnlocked_.at (atoi (stringKey.substr (3) .c_str())) = true; – Rabbid76

+0

@ Gernot1976 Cela ressemble à quelque chose que je pourrais utiliser! Mais il ne trouve rien ... Je vais devoir voir quel est le problème avec ce code. –

Répondre

0

Si vous analysez votre clé pour extraire une valeur entière appropriée, vous pouvez simplement indexer le bit-vecteur qui:

while (std::getline(ifile, line)) { 
     const size_t eq = line.find('='); 
     if (eq == std::string::npos) 
      // no equals sign 
      continue; 

     auto stringKey = line.substr(0, eq); 
     auto stringValue = line.substr(eq+1); 

     if (stringKey.substr(0,3) != "lvl") 
      // doesn't begin with lvl 
      continue; 

     // strip off "lvl" 
     stringKey = stringKey.substr(3); 

     size_t end; 
     std::vector<bool>::size_type index = std::stoi(stringKey, &end); 
     if (end == 0 || end != stringKey.length()) 
      // not a valid level number 
      continue; 

     if (index >= lvlUnlocked_.size()) 
      // out of range 
      continue; 

     // Set it :-) 
     lvlUnlocked_[index] = stringValue=="1"; 
    } 

(je l'ai aussi mis à jour votre analyse syntaxique pour les chaînes « clé = valeur » à plus C++ idiomatique.)