My homework assignment requires me to use booleans

2019-09-22 04:36发布

问题:

For my homework assignment I'm supposed to make a create-your-own-adventure story. There are certain words in the text that are in all caps to represent boolean values that I need to display at the end if the player got them, like a status effect or something. I'm having trouble figuring out how to pass the booleans to the functions so that it makes it to the end of the program where I can display it. My program has functions within functions.

I've tried making the function that sets the boolean to true a boolean itself, then returning the boolean but that just ends the program it seems. I've also tried passing it through the first function call to see if it reaches the second but it doesn't seem like it wants to.

void A1();
bool A100(bool INTIM);
void A167();
void A232();
void A290();
void A13();
void A212();
void A173();
void A159();
void A161();

int main() {
bool INTIM;

A1();
cout << INTIM << endl;
return 0;
}
void A1()
{
  int choice;
  cout << "Well, Mr Artanon, ...\n 1. ’It’s you who’ll get a rare cut 
across that corpulent neck of yours if you don’t speed things along, you 
feckless blob of festering lard.’\n 2. ’Surely in such an industrious 
kitchen, there must be a starter or two ready to send along and sate His 
Abhorentness’s appetite?’\n (enter a menu option): ";
  cin >> choice;

  while (choice != 1 && choice != 2)
  {
    cout << "Enter in a valid choice (1 or 2)";
    cin >> choice;
  }

  if (choice == 1)
  {
    A100();
  }

  if (choice == 2)
  {
    A167();
  }
}

bool A100(bool INTIM)
{
  int choice;
  INTIM = true;
  cout << " Repugnis turns a paler...\n 1. Onwards, Mr Artanon.\n (enter 
in a menu option): ";
  cin >> choice;

  while (choice != 1)
  {
    cout << "Enter in a valid option (1)";
  }
  return INTIM;
  A232();
  }

What I'm wanting to happen is, the bool INTIM to be passed along so i can display it back in main with the cout statement. I know it will just be a 1 or 0 at the end but I'm just trying to get it to show up at least in the end when I display it. Again there are functions within functions in this program and that might be my problem but I wouldn't think so. There is also functions that come after this, this is not the end of the program and if I need to post the whole thing I will

回答1:

Calling A100 as written, you need to pass in INTIM and accept the return value

INTIM = A100(INTIM);

But... The initiqal state of INTIM is never used, so you could

INTIM = A100();

and change A100 to look more like

bool A100()
{
  int choice;
  cout << " Repugnis turns a paler...\n 1. Onwards, Mr Artanon.\n (enter in a menu option): ";
  cin >> choice;

  while (choice != 1)
  {
    cout << "Enter in a valid option (1)";
    cin >> choice; // added here because otherwise choice never changes
                   // and this loop will go on for a long, long time.
  }
  A232(); // moved ahead of return. Code after a return is not run
  return true;
}

But since A232 is called and may set additional flags you cannot return, you have a design flaw: What if A232 also modifies a boolean? You can only return one thing from a function. You could pass A232's boolean in by reference, but what it A232 then calls B484 and it also has a boolean?

You don't want to have to pass around every possible boolean, that would be a confusing mess, so consider making a data structure that stores all of your booleans to pass around.

And that leads to an even better idea: encapsulating the booleans and the functions in the same data structure so that you don't have to pass anything around; it's all in the same place.



回答2:

Do I need to pass them [the boolean results] to the functions?

Often, but not always, it is my preference to pass them by reference, and yes, it can get to be a big chain thru many functions. sigh.

But your question is "Do you need to pass them ...".

The answer is No.

Because

a) you have tagged this post as C++, and

b) the key feature of C++ is the user-defined-class.


  1. Consider declaring every 'adventurous function' of your story within a class scope.

  2. Each 'adventurous function', as an attribute of the class, is implemented with one 'hidden' parameter, the 'this' pointer to the class instance.

  3. So .. if you place all your 'result' booleans as data attributes of the class, invoking any 'adventurous function' will also 'pass' all the class instance data attributes (all your bools!) as part of the invocation. No data is actually moving, just a pointer, the 'this' pointer.


It might look something like this:

#include <iostream>
using std::cout, std::cerr, std::flush, std::endl;
// using std::cin;

#include <iomanip>
using std::setw, std::setfill;

#include <sstream>
using std::stringstream;

#include <string>
using std::string;


namespace AS  // Adventure Story
{
   class CreateYourOwnAdventureStory_t
   {
   private:
      // diagnostic purposes
      stringstream ssUI;
      // command line arguments concatenated into one string
      // contents:  strings convertable to ints to mimic cin

      bool INTIM;
      // other results go here

   public:
      int operator()(int argc, char* argv[]) {return exec(argc, argv);}

   private:

      int exec(int argc, char* argv[])
         {
            int retVal = 0;

            // capture all command line arguments into a string
            for (int i=1; i<argc; ++i)
               ssUI << argv[i] << "  ";

            cout << "\n  ssUI: " << ssUI.str() << "\n\n\n";

            A1();
            cout << "\n  INTIM : " << INTIM << endl;

            // ?more here?

            return retVal;
         }


      void A1()
         {
            int choice = 0;
            cout << "Well, Mr Artanon, ...\n "
               "\n 1. ’It’s you who’ll get a rare cut across that corpulent neck of yours "
               "if you don’t speed things along, you feckless blob of festering lard. "
               "\n 2. ’Surely in such an industrious kitchen, there must be a starter or two "
               "ready to send along and sate His Abhorentness’s appetite?’"
               "\n (enter a menu option): ";

            ssUI >> choice; // cin >> choice;

            if (choice == 1) { A100(); }

            if (choice == 2) { A167(); }
         }


      void A100()
         {
            int choice = 0;
            INTIM = true;
            ssUI >> choice; // cin >> choice;

            cout << "\n\n  A100()  choice:" << choice 
                 << "  INTIM: " << INTIM << endl;
         }

      void A167()
         {
            int choice = 0;
            INTIM = false;
            ssUI >> choice; // cin >> choice;

            cout << "\n\n  A167()  choice:" << choice 
                 << "  INTIM: " << INTIM << endl;
         }

      // other action-functions go here

   }; // class CreateYourOwnAdventureStory_t
   typedef CreateYourOwnAdventureStory_t  CreateYOAS_t;

} // namespace AS

int main(int argc, char* argv[]){return AS::CreateYOAS_t()(argc,argv);}

Notes:

This example grabs the command line parameters and appends them to a string stream. The result is use-able in a fashion much like your cin statements.

Did you notice you (probably) will not need forward declarations for your functions? The compiler has to scan a lot of the class declaration to decide various issues, and thus can figure out that A100 (and A167) are actually with-in the scope of AS::CreateYOAS_t::. The functions can still be moved into a cpp file, so you can still take advantage of separate compilation. (and maybe save some effort compiling smaller files, and only the changed files.)

Did you notice that the functions accessing INTIM simply use the bool, without needing any 'this->' to de-reference?

Main invokes a simple Functor. Nothing else. Main invokes operator(). Simple, minimal. The ctor and dtor are currently default. If you need to use the ctor to initialize results or other intermediate info, I would simply add it near the operator() implementation.

PS: You mentioned using bools to return results. You might as, an alternative, consider using a stringstream ... a single stream with text ... use like a log for capturing the ongoing game, or for a single simple overall report to the user.

Good luck.