Hey folks!
Been a while. I blame school starting up again and MIT's OpenCourseWare for being awesome... the latter anyway.
I'm going to try and keep this short this time; except for the question section at the end.
So, last time I asked for input I learned a lot. By a lot I mean truckloads. I was wondering if you would be so kind as to give me critique again? It's the same program as last time with all the recommended changes implemented as far as I know. If you're interested in a side by side comparison: My attempt at FileHandling up for your inspection
The only thing I wasn't able to do was incorporate iterators. Mainly because I need to create a custom iterator and figure out how to make a single iterator work on two vectors simultaneously. Can't really explain that last one better, my attempt at it is in the code commented out.
Now compiling with CodeBlocks (-wall -pedantic). After doing some research, I'm now comfortable in using CodeBlocks over the recommended compiler, mainly because the version of GCC it uses hasn't implemented any C++ 11 features. It scares me how much it sounds like I know what I'm talking about in this paragraph...
One last important thing (forgive me for bolding, but I really would like input on this):
Last time all the feedback was on how I implemented my solution and not so much the solution itself. Don't get me wrong, as I've said, that feedback has taught me a lot. I would however really appreciate some feedback on the solution; would you use/recommend something else? Perhaps something along the lines of databases? Something else? Or is my solution what you would recommend?
Either way, how would you advise obfuscating the contents of the file (Don't want players reading ahead)? Somehow encryption seems ill-suited to me.
On to code!
contentblock.h:
Code:
#ifndef CONTENTBLOCK_H
#define CONTENTBLOCK_H
#include <vector>
#include <string>
#include <iostream>
class contentBlock {
public:
// Set Functions
void setBlockID(int blockid);
void setText(std::string text);
void setChoiceAmount(int choices);
void addChoiceText(std::string choicetext);
// Get Functions
int getChoiceAmount();
int getNextBlock(int ChoiceIdentifier);
int getBlockID();
contentBlock(int id, std::string &text, int choices, std::vector<int> &choiceids, std::vector<std::string> &choicetexts);
friend std::ostream& operator<<(std::ostream &os, const contentBlock &block);
private:
int Choices, BlockID;
std::string Text;
std::vector<std::string> ChoiceText;
std::vector<int> m_nextblockids;
};
#endif
contentblock.cpp:
Code:
#include "contentblock.h"
void contentBlock::setBlockID(int id) {
BlockID = id;
}
void contentBlock::setText(std::string text) {
Text = text;
}
void contentBlock::setChoiceAmount(int choices) {
Choices = choices;
}
void contentBlock::addChoiceText(std::string choicetext) {
ChoiceText.push_back(choicetext);
}
int contentBlock::getChoiceAmount() {
return Choices;
}
int contentBlock::getNextBlock(int ChoiceIdentifier) {
return m_nextblockids[ChoiceIdentifier];
}
int contentBlock::getBlockID() {
return BlockID;
}
std::ostream& operator<<(std::ostream &os, const contentBlock &block) {
os << "==========" << block.BlockID << "==========" << std::endl;
os << block.Text << std::endl;
os << "************************" << std::endl;
os << "**Please Select:[1.." << block.Choices << "]**" << std::endl;
os << "************************" << std::endl;
for (int i = 0; i < block.Choices; i++)
os << i+1 << ") (" << block.m_nextblockids[i] << "):" << block.ChoiceText[i] << std::endl;
os << "=========/" << block.BlockID << "==========" << std::endl;
os << "Option (999 exits): ";
return os;
}
contentBlock::contentBlock(int id, std::string &text, int choices, std::vector<int> &choiceids, std::vector<std::string> &choicetexts)
: Choices(choices), BlockID(id), Text(text), ChoiceText(choicetexts), m_nextblockids(choiceids) {}
main.cpp:
Code:
#include <fstream>
#include <sstream>
#include "contentblock.h"
std::vector<contentBlock> readContent(std::string file);
void treeLoop();
int StringToNumber (std::string &text);
int getUserInput();
int main () {
treeLoop();
return 0;
}
std::vector<contentBlock> readContent(std::string file) {
//variable setup
int blockid, choices;
std::string Temp, text;
std::vector<contentBlock> Block;
//stream setup
std::ifstream contentStream(file.c_str());
//if to check file access.
if (contentStream.fail())
std::cout << "File access failed.\n";
//while to read contents of file
int i = 0;
while (contentStream.good()) {
std::vector<std::string> choicetext;
std::vector<int> nextid;
// Retrieve and set BlockID
getline(contentStream, Temp, '#');
blockid = StringToNumber(Temp);
// Retrieve and set Text
getline(contentStream, Temp, '#');
text = Temp;
// Retrieve and set ChoiceAmount
getline(contentStream, Temp, '#');
choices = StringToNumber(Temp);
// Retrieve and set NextIDs and ChoiceTexts
for (int j = 0; j < choices; j++) {
getline(contentStream, Temp, '#');
nextid.push_back(StringToNumber(Temp));
getline(contentStream, Temp, '#');
//DEBUG: std::cout << "Block " << i +1 << ": " << Temp << std::endl;
choicetext.push_back(Temp);
}
contentBlock temp(blockid, text, choices, nextid, choicetext);
Block.push_back(temp);
i++;
}// end while
return Block;
} // end readContent function
void treeLoop() {
// variable setup
std::vector<contentBlock> primaryVector;
int ChoiceSelector, PrimaryVectorSize, CurrentBlock, Temp;
std::vector<int> TempVector;
std::vector<int>::iterator IntVectorIterator;
primaryVector = readContent("Story.txt");
PrimaryVectorSize = primaryVector.size() - 1;
// Create vector of BlockIDs
for (int i = 0; i < PrimaryVectorSize; i++)
TempVector.push_back(primaryVector[i].getBlockID());
// Need to write custom iterator for this
/*for(IntVectorIterator = primaryVector.begin();
IntVectorIterator != primaryVector.end();
IntVectorIterator++) {
TempVector.push_back(*IntVectorIterator.getBlockID());
}*/
// For debugging purposes.
/*std::cout << "Array contents:\n";
for (int i = 0; i < PrimaryVectorSize; i++)
std::cout << i << ":" << TempVector[i] << std::endl;*/
// Initial setup. Will change this when I add save/load functionality.
CurrentBlock = 0;
std::cout << primaryVector[0];
ChoiceSelector = getUserInput();
// Runs until the user enters '999' as input.
while (ChoiceSelector != 999) {
// while to check and correct input.
while (ChoiceSelector < 1 || ChoiceSelector > primaryVector[CurrentBlock].getChoiceAmount()) {
std::cout << "You have entered an invalid choice. Please select one from the list. [1.."
<< primaryVector[CurrentBlock].getChoiceAmount() << "]: " ;
ChoiceSelector = getUserInput();
}// end inner while
Temp = primaryVector[CurrentBlock].getNextBlock(ChoiceSelector - 1);
// runs comparison to determine what the NextBlock is going to be.
for (int i = 0; i < PrimaryVectorSize; i++) {
if (TempVector[i] == Temp) {
//DEBUG: std::cout << "Temp: " << Temp << " vs TempVector[" << i << "]: " << TempVector[i] << std::endl;
std::cout << primaryVector[i];
CurrentBlock = i;
break;
} // end if
}// end for
/*for(IntVectorIterator = TempVector.begin();
IntVectorIterator != TempVector.end();
IntVectorIterator++) {
if (*TempVector == Temp) {
std::cout << primaryVector[i]; // This is going to be a problem
CurrentBlock = i;
break;
} // end if
}// end for */
ChoiceSelector = getUserInput();
}// end outer while
}// end treeLoop function
int StringToNumber (std::string &text) {
std::stringstream ss(text);
int result;
return ss >> result ? result : 0;
}
int getUserInput() {
std::string userinput;
std::cin >> userinput;
while (StringToNumber(userinput) == 0) {
std::cout << "Incorrect input. Please enter a valid choice: ";
std::cin >> userinput;
}
return StringToNumber(userinput);
}
To accomodate the change of the IDs from strings to int, I'm uploading a new .txt should you want to see the code in motion. You don't need to change the extension this time. Find attached.
Now for a murderous tl;dr section. Enter at own risk...
Questions
(In no particular order)
I got a little lazy with my questions last time; I apologize to anyone who managed to read through that.
1) I created a new thread because I was unsure of the rules on Necro'ing here. I read the forum rules. I read that bumping isn't allowed, but to a lot of people bumping and necro'ing isnt the same thing. Could someone give me the rundown on this?
2) Totally unrelated: Having done some rudementary research on the subject, should I ever go into something involving 3D (Games, visualization, CAD, etc) I will be using OpenGL (Mainly because I'm a sucker for the underdog). I was wondering... all these 3D modelling programs (3DS Max, Maya, etc), the files they output - how do you write code that work with them? Do you have to use libraries? Who maintains those, the companies themselves or 3rd parties? Or is it a case by case thing?
3) Related to #2: In my reseach, I mostly got the impression that OpenGL is playing catch-up with DirectX's feature set. Should a person have/want to write an OpenGL game engine from the ground up wanting a specific feature from DirectX that OpenGL lacks, can it be coded into the engine itself? My uneducated guess would be that if you could that, there would be a drop in the execution speed of that feature. I base that on my idea that it would have to work through more layers of software than it would if it was "lower down" in OpenGL itself. Please feel free to correct me on this. Now a really out there question: Say you wanted to write a game engine, but didn't want to use OpenGL or DirectX and do everything from the ground up (Which I know is kind of insane)... is that even doable? Would graphics card drivers still work or would you need to write new ones? How big a task is this? Could you possibly do this in say... 3 years?
4) In the previous thread, I asked for book recommendations and phantomotap kindly supplied a list. I found a very cheap second-hand copy of Effective C++, 3rd Edition, but it's a first print. Should I rather buy the PDF online (Which is slightly more expensive)? In fact, in general, should I worry if I can't get the latest Editions or prints? Online stores make it so hard to find out which print (versus editions) of a book they are actually selling...
5) After the refactoring of my program, the .exe size doubled. Should this worry me? If you have the time, would you mind speculating as to why this is the case, either way?
6) Getting back to GCC not having the C++ 11 features (At least, not all of them). Please don't think me entitled in asking this, in fact I'm asking to get informed and avoid that. C++ 11 was ratified in 2011 and we are rapidly nearing the end of 2012. My assumption is that these things are mostly maintained/updated by volunteers (and would thus take longer). What is a reasonable timeframe of when we can expect full C++ 11 support? I REALLY want to sink my teeth into that new thread stuff C++ 11 brings (Even though my understanding of anything beyond the most rudimentary is severly lacking). I like punching above my weightclass
I feel like I'm forgetting something... perhaps I can edit it in should I remember in time...