Yeah I tried that, but what about on large scale, if im moving between 50 rooms, that wouldnt work, because it would be move north if input is 12 for every single room
Yeah I tried that, but what about on large scale, if im moving between 50 rooms, that wouldnt work, because it would be move north if input is 12 for every single room
This probably isnt the most effiencent but something like.
If the players location = this number (Room number)
then do this function
Something like that would work, would allow me to assign a different functuion each and every time the player runns into the room
Just like how you don't need a separate function to move north for each room, despite the fact that north is different in each room, you also don't need separate question functions. Instead you need a generic question function.
You could create a large array with questions and a corrisponding array with answers. Create a function that asks the player one of the questions at random. Hint try using the anwser data from other questions to generate wrong answers.
Ok thank you for your response, I quite tired so I am not following what you are saying so I will take a look tomorrow.
Aliaks, I hope you are rested up. I like to pop in occasionally to see how your project is coming along. If you are finding that adding a room to your world is getting difficult, don’t be discouraged. You’ve learned a lot.
I really wanted to talk about your quiz idea. I assume from your posts that you want to generate random questions. Maybe you want questions of different types, like riddles and arithmetic questions. If I understand correctly, I would separate the questions into different categories, and implement each category with a class because each category would probably have a different implementation. The idea is to keep your program flexible. A good design would allow a new question category to be added without changing existing code. Being able to add stuff without changing existing code is the big benefit of object oriented design. You do this by creating an interface. Your program uses only the interface and all your question classes implement the interface.
For example here is an interface for a question generator
Its functions are pure virtual meaning that this is an interface.Code:class QuestionGenerator { /* Defines the public interface to question generators */ public: virtual const std::string& poseQuestion(void) = 0; virtual bool isCorrectAnswer(const std::string& answer) const = 0; };
Anything that claims to inherit from this interface must implement the functions advertized by the interface.
Now you can have a number of question categories. For example, say you want an arithmetic question generator.
You can also have a RiddleQuestionGenerator that has a different implementation from the ArithmeticQuestionGenerator, but the same interface.Code:class ArithmeticQuestionGenerator: public QuestionGenerator { /* Creates arithmetic question */ public: virtual const std::string& poseQuestion(void) { // return a string for the current question } virtual bool isCorrectAnswer(const std::string& answer) const { // check answer and return result } };
How do we put all these question generators together? We can have a QuizMaster class that creates all the question generators and picks one at random to use.
Notice that the QuizMaster is also a QuestionGenerator. The poseQuestion and isCorrectAnswer methods simply forward calls to a randomly chosen QuestionGenerator.Code:class QuizMaster : public QuestionGenerator { /* Responsible for holding different types of question generators */ public: QuizMaster() { mGenerators.push_back(new RiddleGenerator()); mGenerators.push_back(new ArithmeticQuestionGenerator()); } virtual const std::string& poseQuestion(void) { } virtual bool isCorrectAnswer(const std::string& answer) const { } std::vector<QuestionGenerator*> mGenerators; };
Then all we need is to create a QuizMaster in main and use it.
Notice that main does not care about how QuizMaster works, or about what question generators are available.Code:int main() { QuizMaster quizMaster; while(true) { std::cout << quizMaster.poseQuestion().c_str() << std::endl; std::string answer; getline(std::cin, answer); if (quizMaster.isCorrectAnswer(answer)) std::cout << "Thats right" << std::endl; else std::cout << "Better luck next time !" << std::endl; } }
If you want to add a new QuestionGenerator, you don’t change any existing ones. You just create a new class and add its instance to the list in QuizMaster.
Please feel free to ask questions. If you want a working example, I can post it.
Hey Zlatko, thanks for the reply.
Yes I would like to randomly pick or generate some questions which I can slot into my moving around part.
Some of the questions would be math, spelling, remembering, nothing to complicated, once I can do 1 question, I can easily write the rest.
I think I understand the above, how does it pick a random question.?
Im guessingis like a vector and it picks the next in line? Is that correct?Code:mGenerators.push_back(new RiddleGenerator()); mGenerators.push_back(new ArithmeticQuestionGenerator());
I just don't see how this can fit into the moving around part, its kind of annoying me as this is basicly the only part I can't get my head around
If you already have one laying about a example would be great, so I can see how it works, but If you don't thats ok, I do not wish to take up to much of your time.
Zlatko: I must point out that you never delete what you new. Best to use some smart pointer, such as std::tr1::shared_ptr or simply std::auto_ptr.
Aliaks: The idea is that every one of these *Generator classes contains one question and one answer. Then QuizMaster creates a number of these questions and picks one at random when you call poseQuestion. The implementation of that is missing.
Of course, I see this as overkill. You simply need QuizMaster and some struct with a question and answer and you can implement a number of question in QuizMaster and the rest works the same.
Elysia, haven't you read the latest standard? C++ is now garbage collected! Ha, just kidding. You're right, QuizMaster should have a virtual destructor to clean things up.
Aliaks, I'm including the code I used to play around with my idea. Don't forget to make a virtual destructor in QuizMaster. Remember there are many ways of solving a problem so don't be afraid to experiment with different designs.
Code:#include <iostream> #include <vector> #include <string> #include <time.h> #include <stdio.h> #ifdef WIN32 #include <Windows.h> #define snprintf _snprintf #endif #define PROGRAMMING_ERROR std::cerr << "Programming error at " << __FILE__ << " line " << __LINE__ << std::endl; static int randBetween(int low, int high) { if (low == high) return low; if (low > high) { int tmp = low; low = high; high = tmp; } static bool firstTime = true; if (firstTime) { srand((unsigned int)time(NULL)); firstTime = false; } int num = rand(); int result = num % (high - low + 1) + low; return result; } class QuestionGenerator { /* Defines the public interface to question generators */ public: virtual const std::string& poseQuestion(void) = 0; virtual bool isCorrectAnswer(const std::string& answer) const = 0; }; class ArithmeticQuestionGenerator: public QuestionGenerator { /* Creates arithmetic question */ public: virtual const std::string& poseQuestion(void) { Operation operation = (Operation)randBetween(ADD, SUBT); int operand1 = randBetween(5, 10); int operand2 = randBetween(0, 5); char buf[128]; snprintf(buf, sizeof(buf), "What is %d %c %d ?", operand1, operationChar(operation), operand2); mCurrentQuestion = buf; switch(operation) { case ADD: mAnswer = operand1 + operand2; break; case SUBT: mAnswer = operand1 - operand2; break; default: PROGRAMMING_ERROR; } return mCurrentQuestion; } virtual bool isCorrectAnswer(const std::string& answer) const { return (atoi(answer.c_str()) == mAnswer); } private: enum Operation { ADD = 1, SUBT }; char operationChar(Operation op) { switch(op) { case ADD: return '+'; case SUBT: return '-'; default: PROGRAMMING_ERROR; break; } return ' '; } std::string mCurrentQuestion; double mAnswer; }; class RiddleGenerator: public QuestionGenerator { public: /* Trivial pursuit questions */ virtual const std::string& poseQuestion(void) { int q = randBetween(0, QuestionCount-1); mAnswer = mQnA[q].answer; return mQnA[q].question; } virtual bool isCorrectAnswer(const std::string& answer) const { return (atoi(answer.c_str()) == mAnswer); } private: struct QnA { std::string question; int answer; }; static const int QuestionCount = 2; static QnA mQnA[QuestionCount]; int mAnswer; }; RiddleGenerator::QnA RiddleGenerator::mQnA[RiddleGenerator::QuestionCount] = { { "What is your Quest?\n\t1)To seek the holy grail?\n\t2)Party Party Party", 1 }, { "What is the best beer in Aussi Land?\n\t1)Tooheys\n\t2)Reschs\n\t3)Hahn", 1 } }; class QuizMaster : public QuestionGenerator { /* Responsible for holding different types of question generators */ public: QuizMaster() { mCurrentQuestionGenerator= NULL; mGenerators.push_back(new RiddleGenerator()); mGenerators.push_back(new ArithmeticQuestionGenerator()); } virtual const std::string& poseQuestion(void) { int ix = randBetween(0, int(mGenerators.size()-1)); mCurrentQuestionGenerator = mGenerators[ix]; return mCurrentQuestionGenerator->poseQuestion(); } virtual bool isCorrectAnswer(const std::string& answer) const { if (mCurrentQuestionGenerator == NULL) return false; return mCurrentQuestionGenerator->isCorrectAnswer(answer); } std::vector<QuestionGenerator*> mGenerators; QuestionGenerator* mCurrentQuestionGenerator; }; int main() { QuizMaster quizMaster; while(true) { std::cout << quizMaster.poseQuestion().c_str() << std::endl; std::string answer; getline(std::cin, answer); if (quizMaster.isCorrectAnswer(answer)) std::cout << "Thats right" << std::endl; else std::cout << "Better luck next time !" << std::endl; } }
It's quite simple really. Assuming this is your current code to move north:
All you have to do is change it to:Code:player.location = player.location -> north;
I realize you don't already have a function called askQuestion(), but you should easily be able to do so. The code is already here in the thread, you just need to but it in a function, and make the function return true or false depending on how the player answers the question.Code:if (askQuestion () ) { player.location = player.location->north; }
How does this know the answer?Code:RiddleGenerator::QnA RiddleGenerator::mQnA[RiddleGenerator::QuestionCount] = { { "What is your Quest?\n\t1)To seek the holy grail?\n\t2)Party Party Party", 1 }, { "What is the best beer in Aussi Land?\n\t1)Tooheys\n\t2)Reschs\n\t3)Hahn", 1 } };
Sorry I have not done structs yet, I will look into them.