Advertisement

C++ Workshop - Project 1

Started by August 16, 2006 05:41 PM
193 comments, last by me_minus 15 years, 3 months ago
Random names are beyond the scope of this project. I would suggest you just let the user type it in, then go and get the rest of the system working. You can come back to this feature later when you don't have a deadline, and also when you know a little more of the language.

Anyway, one way to do it is to randomly pick from a list of syllables. This is how all the 'fantasy name generators' I've seen on the net work. For example, randomly picking two syllables from the list 'isu, bua, het, nam, tij, tri, wen' could produce names like 'isuwen' or 'tribua' or 'hetnam'.
Well random names aren't part of the project, but here is the system I would use.

For a simple first-name and last-name system, just create two string array's and just manually fill them with names.

Then just randomly generate two numbers that are in the range of the above array's (so two arrays most likely since you could potentially uneven the two arrays)

Then just get the two strings by using the above numbers in the array, and add the two strings together. Then voila, a "random name generator".

Also, thanks for helping me out with the combat system! Makes a _lot_ more sense now that you put it in layman's terms :) I will be implementing the combat system tonight hopefully.

*Edit* Erm, actually I'm unable to do this anymore... You see, WinXP has been degrading for the past month (explorer.exe crashes randomly and a bunch of other crap) and now for some reason, backspace, space, enter, control, and a bunch of other essential keys are unable _only_ in visual studio... WTF?

So yea, this sucks... Looks like I'll be going over to Vista as my primary OS sooner than I thought (now that he just hit RC1 and hopefully should be usable as a day-to-day OS)
Advertisement
Considering that

- menus display their options
- menus get input
- menus test their input
- each menu takes its own different actions upon different input

Well, I tried designing a menu base class which has all these actions, then, all menus (including main menu) will polymorphically derive from the base class, with virtual functions like showMenu() and testChoice() etc.

Going in this direction, what would be the correct approach to handle branching to submenus and returning to "outer" menus?

The approach I tried was to create the submenu from within the outer menu, and with A twist I thought would be neat; To make the constructor for the BASE calss menu call the showMenu() and testChoice() etc functions, like this all derived menu objects will right away act themselves out respectively- or will they. Well, is it possible to call virtual functions from within the base class constructor?
Rephrase: is it possible to use the base class constructor to call virtual functions of derived types?

example
class Menu{  public:     Menu() { while (itsExit) { showMenu();  testChoice(); } }     virtual ~Menu () {}     virtual showMenu() { cout << "this is the base menu you'l never see\n" ; }     virtual testChoice() { cout << "this is the base class test choice\n" ; }  protected:     char itsChoice;     bool itsExit;};class MainMenu : public Menu{     virtual showMenu() { cout << "this is the main menu\nEnter Choice\n"; cin >> itsChoice; }     // here is the punchline of my question,      virtual testChoice() { if (itsChoice == '1') Menu * pSubMenu = new SubMenu; else {itsExit = true;} }};class SubMenu : public Menu{     virtual showMenu() { cout << "this is the sub menu\nEnter Choice\n"; cin >> itsChoice; }     virtual testChoice() { if (itsChoice == '1') cout << "\nhello world\n" ; else {itsExit = true;} }};int main(){ Menu * pStartMenus = new MainMenu; return 0;}


hope im understood

Please comment about this whole approach

[Edited by - kingIZZZY on September 3, 2006 5:18:48 AM]
About the writing to the console:

I found ben ryves tutorial very helpful: http://benryves.com/tutorials/?t=winconsole&c=1

One thing I couldn't solve yet is to eliminate the cursor from blinking. I tried

CONSOLE_CURSOR_INFO ConsoleCursorInfo;
ConsoleCursorInfo.bVisible = false;
SetConsoleCursorInfo(hStdout, &ConsoleCursorInfo);

Another problem I have is that the console always prints ("Press Enter to continue...").

[Edited by - yabba_dabba on September 3, 2006 7:28:35 AM]
Quote:
Rephrase: is it possible to use the base class constructor to call virtual functions of derived types?


No. Your compiler should give you warning about this. The problem here is that that base constructor is called before any part of the derived class is constructed, so when you call that virtual function the dervided part is not yet constructed. Obviously, calling functions on an un-constructed object isn't a good idea.
If you call a virtual function in a constructor, it will call the virtual function in that class, regardless of any subclasses. It will not exhibit the normal virtual behaviour that you may expect. This is for a good reason, as Deyja stated the subclasses virtual functions may use bits of the subclass that haven't been constructed yet.

However, the real problem is that you are trying to "do work" in your contructor. That is not the purpose of a constructor, its a special function that should only exist if an object needs special set up. Your current menu objects do not use it for that purpose, indeed they don't seem to set reasonable defaults for "itsExit" and "itsChoice".

Programmers expect that code works in a certain way, people using your code would be wondering why the constructor blocks for so long, as it has a user-input loop in there.

Moving the relevant code to a special "doMenu()" or "run()" function would work better, as not only would the virtual functions work properly, but you could do things like preconstruct menu objects without running them yet.

I believe that would be a better choice for your program.
Advertisement
thanx, that really helps.

p.s. rip-off

Quote:
indeed they don't seem to set reasonable defaults for "itsExit" and "itsChoice".


the above example code of my question is laughably abbreviated, with inline implementation and funny input testing- my real constructor's initialization section assigns default values to the variables, and the testChoice() 'switch'es input, etc.
If you want to hide the cursor you can use:
void hideCursor(HANDLE wHnd) {    CONSOLE_CURSOR_INFO info;    info.dwSize = 100;    info.bVisible = false;    SetConsoleCursorInfo(wHnd, &info);}
RE to hide the cursor: didnt work by me. (there were no compile errors or warnings, just the cursor didnt hide at runtime)

question:

is it healthy to create an object on the free store, then pass the dereferenced pointer to this object into a function, which will take the dereferenced pointer as a reference?

example:

class Monster {.....}int main(){     Monster * pMyMonster = new Monster("tempName", 1, 2, 3, 4, 5, 6,);     doTheFunction(*pMyMoster);  // passing the OBJECT thats on the free store...     return 0;}void doTheFunction(Monster & theDereferencedPointerMonster) //... to a reference!! (references to free store objects isnt SUCH a good idea, no?){     theDereferencedPointerMonster.printItsName();// or is it//   theDereferencedPointerMonster->printItsName();}


[Edited by - kingIZZZY on September 3, 2006 5:24:21 PM]
That's absolutely fine. Just beware - if the pointer is null, the dereference itself will NOT crash the program; the first attempt to use the reference (the . operator) will instead. Dereferences are usually 'null operations' or 'nops' because they don't usually directly correlate to assembly - instead of generating code, they change surrounding code. This 'delayed crash' can be a serious source of debugging headaches.

This topic is closed to new replies.

Advertisement