Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 08-24-2005, 10:56 PM   #16 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,545
Valmont is on a distinguished road
By the way, do the main game loop first. I want to see how you do that again.
This time no bool* myVar. Ditch the "*".

The first thing you need to ask yourself:
'Who/what is responsible for terminating the program on client's request'
In your original code you had the answer wrong. Find a different one. Remember, every function or every block of code should be valued by its behaviour. I cannot stress that enough. You always want to think about behaviour and responsibilities. That is the "soul" of object oriented programming in real practice. Start now, become good soon.
__________________
Valmont is offline   Reply With Quote
Old 08-27-2005, 10:20 PM   #17 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
Heres the game loop.
Code:
void first_part(std::string * scrambledWord, std::string * word)
{
  std::cout << "Welcome to Word-Scramble." << std::endl;
  std::cout << "Your Word is: " << *scrambledWord << std::endl;

  middle_part(word);
}

//-----------------------------------------------------------------------------

void middle_part(std::string * word)
{
  bool tryAgain = true;
  std::string guess;

  //Start Loop
  while (tryAgain)
  {
    std::cout << "What is the word? (type \"give up\" to get the answer): ";
    std::cin >> guess;
    std::cout << std::endl;

    tryAgain = process(guess, *word);
  }
  end_part();
}

//-----------------------------------------------------------------------------

bool process(std::string guess, std::string word)
{
  bool tryAgain = true;
  //Give up?
  if (guess == "give")
  {
    //Yup, Give up
    std::cout << "The Word is: " << word << std::endl;
    tryAgain = false;
  }
  else
  {
    //Is it right?
    if (guess == word)
    {
      //Yup, It's right
      std::cout << "Correct! You Win!" << std::endl;
      tryAgain = false;
    }
    else
    {
      //Nope not right
      std::cout << "No, that\'s not the word. Try Again" << std::endl;
    }
  }
  return tryAgain;
}

//-----------------------------------------------------------------------------

void end_part()
{
  bool playAgain;

  std::cout << "Thanks, for playing." << std::endl;
//Let the functions finish
}
first_part() is called by main() after the word has been scrambled.
I think this works better. How would I start the program over at the user request? (that would be found in the end_part() function).

Missed your second reply so i've been woring on the scramble function too.
Code:
std::string scramble_word(std::string sWord)
{
  int wordLength=0;
  std::string scrambledWord;
  int letter;
  int count=0;
  int lettersLeft;
  std::string sLetter;

  wordLength = sWord.length();
  lettersLeft = wordLength;

  std::cout << "Scrambling Word";

  while (count <= (wordLength-1))
  {

    //choose a letter from sWord
    letter = (choose_rand(lettersLeft) - 1);
    std::cout << ".";

   //Asign it to scrambledWord[count]
    sLetter = sWord[letter];
    scrambledWord.append(sLetter);

   //Remove chosen letter from sWord
    int i = (letter);
    while (i<(lettersLeft-1))
    {
      sWord[i] = sWord[i+1];
      i++;
    }

    lettersLeft--;
    count++;
  }
  return scrambledWord;
}
it works resonably well but would work better if i had a random number generator that could come up with a different number several times per second. any suggestions there?

I'll take a crack at your puzzle code.
thanks
Scott
smckittr is offline   Reply With Quote
Old 08-28-2005, 04:44 AM   #18 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,545
Valmont is on a distinguished road
Don't do this "part" method. Use a simple global game loop. Also observe the usage of std::random_shuffle. Makes your life quite easy. After you've seen the code things are easy for you to do implement the rest:

Code:
#include <fstream>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
#include <algorithm>

unsigned choose_word(unsigned);
unsigned calculate_lines(std::ifstream&);
std::string fetch_word(std::ifstream&, unsigned);

int main()
{
  using std::endl;
  using std::cout;
  using std::cin;
  
  std::string sWord;
  std::string sGuess = "quit";
  unsigned nLines(0);
 
  std::ifstream dictionary("dictionary.txt");

  if (!dictionary)
  {
    std::cout << "ERROR: There was error opening the file dictionary.txt." << std::endl; 
    std::cout<< "Please read readme.txt for possible solutions." << std::endl;
    std::cout<< "Terminating program...";
    exit(1);
  }
  
  while(1)
  {
    cout << "1 = Play Game" << endl;
    cout << "2 = Quit App" << endl;
    char appRun;
    cin >> appRun;
    if(appRun == '2')
    {
      break;
    }
    if(appRun == '1')
    {
      //Let's first determine how many words there are.
      nLines = calculate_lines(dictionary);
      //We know how many words there are, so let's choose a random word line.
      unsigned RandomLine;
      RandomLine = choose_word(nLines);
      //We know which line to pick. So let's retreive the word on that line.
      sWord = fetch_word(dictionary, RandomLine);
      std::random_shuffle(sWord.begin(), sWord.end());
    }
    else
    {
      cout << endl << "ERROR: you didn't enter \"1\" or \"2\" " << endl;
      cout << "Please try again." << endl << endl;
    }    
  }

  return 0;
}

//---------------------------------------------------

//So how many lines (=words) has this file?
unsigned calculate_lines(std::ifstream& dict)
{
  unsigned lns(0);
  std::string sBuffer;
  while( std::getline(dict, sBuffer) )
  {
    ++lns;
  }
  
  //Did something went wrong during the read of this stream?
  if(!dict.eof())
  {
    //Yep, something went wront. Ring the alarms!
    std::cout<<"ERROR: something go wrong during file reading.";
    dict.close();
    std::cout<<"exiting app...";
  }  

  //Do not forget to reset the state of the dictionary file object since it is
  //in a error state due to EOF.
  dict.clear();
  //And let the file pointer point to the beginning as it was before all this.
  dict.seekg(0, std::ios::beg);
  return lns;
}

//---------------------------------------------------

unsigned choose_word(unsigned maxnum)
{
  unsigned randnum;
  std::srand(std::time(0));
  randnum= std::rand() % maxnum + 1;  
  return randnum;
}

//----------------------------------------------------

std::string fetch_word(std::ifstream& dict, unsigned line)
{
  std::string buffer;
  while( std::getline(dict, buffer) && line != 1)
  {
    --line;
  }
  
  //Do not forget to reset the state of the dictionary file object since it is
  //in a error state due to EOF.
  dict.clear();
  //And let the file pointer point to the beginning as it was before all this.
  dict.seekg(0, std::ios::beg);
  
  return buffer;
}
Soo... what do you think?
__________________
Valmont is offline   Reply With Quote
Old 08-28-2005, 05:06 AM   #19 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
You could first parse the file into an array or vector of strings, then do all the looking up on that. Should reduce the complexity a bit, and maybe improve performance a little.
Locutus is offline   Reply With Quote
Old 08-28-2005, 05:25 AM   #20 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,545
Valmont is on a distinguished road
Yes the first thing that popped in my mind as well. But if you look around on this forum you'll see peeps having difficulties with stream handling. Once their fight against basic C++ is over they can shift their attention.
If I stored the words in a container they would not have learned how to count lines and wouldn't have seen that one needs to parse all lines to count the total lines in file. It's the only portable way.
__________________
Valmont is offline   Reply With Quote
Old 08-29-2005, 04:33 PM   #21 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
Valmont,
I got the rest of the game loop in. Heres the whole program
Code:
#include <fstream>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
#include <algorith>

unsigned choose_word(unsigned);
unsigned calculate_lines(std::ifstream&);
std::string fetch_word(std::ifstream&, unsigned);
bool process(std::string, std::string);

int main()
{
  using std::endl;
  using std::cout;
  using std::cin;

  std::string sWord;
  std::string sGuess = "quit";
  unsigned nLines(0);

  std::ifstream dictionary("dictionary.txt");

  if (!dictionary)
  {
    std::cout << "ERROR: There was error opening the file dictionary.txt." << std::endl;
    std::cout<< "Please read readme.txt for possible solutions." << std::endl;
    std::cout<< "Terminating program...";
    std::exit(1);
  }

  while(1)
  {
    cout << "1 = Play Game" << endl;
    cout << "2 = Quit App" << endl;
    char appRun;
    cin >> appRun;
    if(appRun == '2')
    {
      break;
    }
    if(appRun == '1')
    {
      //Let's first determine how many words there are.
      nLines = calculate_lines(dictionary);
      //We know how many words there are, so let's choose a random word line.
      unsigned RandomLine;
      RandomLine = choose_word(nLines);
      //We know which line to pick. So let's retreive the word on that line.
      sWord = fetch_word(dictionary, RandomLine);

      //Make a copy and shuffle
      std::string word = sWord;
      std::random_shuffle(sWord.begin(), sWord.end());

      //Start Game
      std::cout << "Welcome to Word-Scramble." << std::endl;
      std::cout << "Your Word is: " << sWord << std::endl;

      bool tryAgain = true;
      std::string guess;

      //Start Loop
      while (tryAgain)
      {
        std::cout << "What is the word? (type \"3\" to get the answer): ";
        std::cin >> guess;
        std::cout << std::endl;

        tryAgain = process(guess, word);
      }

      std::cout << "Thanks, for playing." << std::endl;

    }
    else
    {
      cout << endl << "ERROR: you didn't enter \"1\" or \"2\" " << endl;
      cout << "Please try again." << endl << endl;
    }
  }

  return 0;
}

//---------------------------------------------------

//So how many lines (=words) has this file?
unsigned calculate_lines(std::ifstream& dict)
{
  unsigned lns(0);
  std::string sBuffer;
  while( std::getline(dict, sBuffer) )
  {
    ++lns;
  }

  //Did something went wrong during the read of this stream?
  if(!dict.eof())
  {
    //Yep, something went wront. Ring the alarms!
    std::cout<<"ERROR: something go wrong during file reading.";
    dict.close();
    std::cout<<"exiting app...";
  }

  //Do not forget to reset the state of the dictionary file object since it is
  //in a error state due to EOF.
  dict.clear();
  //And let the file pointer point to the beginning as it was before all this.
  dict.seekg(0, std::ios::beg);
  return lns;
}

//---------------------------------------------------

unsigned choose_word(unsigned maxnum)
{
  unsigned randnum;
  std::srand(std::time(0));
  randnum= std::rand() % maxnum + 1;
  return randnum;
}

//----------------------------------------------------

std::string fetch_word(std::ifstream& dict, unsigned line)
{
  std::string buffer;
  while( std::getline(dict, buffer) && line != 1)
  {
    --line;
  }

  //Do not forget to reset the state of the dictionary file object since it is
  //in a error state due to EOF.
  dict.clear();
  //And let the file pointer point to the beginning as it was before all this.
  dict.seekg(0, std::ios::beg);

  return buffer;
}

//-----------------------------------------------------------------------------

bool process(std::string guess, std::string word)
{
  bool tryAgain = true;
  //Give up?
  if (guess == "3")
  {
    //Yup, Give up
    std::cout << "The Word is: " << word << std::endl;
    tryAgain = false;
  }
  else
  {
    //Is it right?
    if (guess == word)
    {
      //Yup, It's right
      std::cout << "Correct! You Win!" << std::endl;
      tryAgain = false;
    }
    else
    {
      //Nope not right
      std::cout << "No, that\'s not the word. Try Again" << std::endl;
    }
  }
  return tryAgain;
}
#include <algorithm> didn't work so i looked in my include files and the file was named algorth so I changed it.

Also the random_shuffle() function doesn't compile for me. I get this error:
"_algo.c": E2268 Call to undefined function 'rand' in function _STL::int __random_number<int>(int) at line 432

Thanks
Scott
smckittr is offline   Reply With Quote
Old 08-30-2005, 06:48 AM   #22 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,545
Valmont is on a distinguished road
Well done so far.

Here is a nice tip: check out redhead's reply in the thread below.
http://codenewbie.com/forum/showthre...8610#post18610
Download Dev-Cpp or Code::Blocks for ISO compliance and good IDE and visual debugger. You won't have STL problems anymore. Debugging works easy as well. I think you will like it. I use both myself at work!

So let's move on with your code.
Your function bool process().
The word "process" could be meaning anything. It's not very informative. Pretend I am a total stranger. And I look for the first time at your code. What could "process" possibly mean to me as a stranger. Could be anything...

Behaviour & Responsibilities

We talked about that earlier. Once you figured out how to do things basically, you may want to think about which part of the program should be doing whatever needs to be done. Your "process()" function does a lot:
- It checks user input for correct guess.
- It offers a supporting role for the gaming engine (it may let you guess again or it may let you give up).
- It even knows what plans the engine has for you.

That's one kick-ass function you got there. It has a lot of responsibilities. We don't want that .

So I skinned that function down and renamed a few stuff here and there. Remember, to chose the right names for the things so strangers know what you mean. You communicate through code. Never forget that!

Your task

Grab the complete working code from below (at the very end of this post) and wrap this part in some sort of a function. This will be THE game engine. THE controller. THE boss.
Code:
      //Start Game
      std::cout << "Welcome to Word-Scramble." << std::endl;
      std::cout << "Your Word to guess is: " << sShuffledWord << std::endl;

      std::string sClientGuess;
      //Begin user guessing sequence.
      while (1)
      {
        std::cout << "What is the word? (type \"?\" to get the answer): ";
        std::cin >> sClientGuess;
        if(sClientGuess == "?")
        {
          //Client gives up guessing.
          std::cout << "The correct word is: " << sWord << std::endl;
          break;
        }
        std::cout << std::endl;

        if( check_guess(sClientGuess, sWord) )
        {
          //User guessed the word so quit guessing sequence.
          break;
        }
      }
When you succeeded you want to check out what else you could do to keep "main()" simple and readable for strangers like me. You want to hide the all the complex things so stranger can concentrate on your global idea first.

Here is the complete code: have fun! (and don't forget to download that stuff)
Code:
#include <fstream>
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <string>
#include <algorithm>

unsigned choose_word(unsigned);
unsigned calculate_lines(std::ifstream&);
std::string fetch_word(std::ifstream&, unsigned);
bool check_guess(const std::string, const std::string);

int main()
{
  using std::endl;
  using std::cout;
  using std::cin;

  std::string sWord;
  std::string sGuess = "quit";
  unsigned nLines(0);

  std::ifstream dictionary("dictionary.txt");

  if (!dictionary)
  {
    std::cout << "ERROR: There was error opening the file dictionary.txt." << std::endl;
    std::cout<< "Please read readme.txt for possible solutions." << std::endl;
    std::cout<< "Terminating program...";
    std::exit(1);
  }

  while(1)
  {
    cout << "1 = Play Game" << endl;
    cout << "2 = Quit App" << endl;
    char appRun;
    cin >> appRun;
    if(appRun == '2')
    {
      break;
    }
    if(appRun == '1')
    {
      //Let's first determine how many words there are.
      nLines = calculate_lines(dictionary);
      //We know how many words there are, so let's choose a random word line.
      unsigned RandomLine;
      RandomLine = choose_word(nLines);
      //We know which line to pick. So let's retreive the word on that line.
      sWord = fetch_word(dictionary, RandomLine);

      //Make a copy and shuffle
      std::string sShuffledWord = sWord;
      std::random_shuffle(sShuffledWord.begin(), sShuffledWord.end());

      //Start Game
      std::cout << "Welcome to Word-Scramble." << std::endl;
      std::cout << "Your Word to guess is: " << sShuffledWord << std::endl;

      std::string sClientGuess;
      //Begin user guessing sequence.
      while (1)
      {
        std::cout << "What is the word? (type \"?\" to get the answer): ";
        std::cin >> sClientGuess;
        if(sClientGuess == "?")
        {
          //Client gives up guessing.
          std::cout << "The correct word is: " << sWord << std::endl;
          break;
        }
        std::cout << std::endl;

        if( check_guess(sClientGuess, sWord) )
        {
          //User guessed the word so quit guessing sequence.
          break;
        }
      }
    }
    else //Incorrect main menu usage.
    {
      cout << endl << "ERROR: you didn't enter \"1\" or \"2\" " << endl;
      cout << "Please try again." << endl << endl;
    }
  }
  
  std::cout << "Thanks, for playing." << std::endl;
  return 0;
}

//---------------------------------------------------

//So how many lines (=words) has this file?
unsigned calculate_lines(std::ifstream& dict)
{
  unsigned lns(0);
  std::string sBuffer;
  while( std::getline(dict, sBuffer) )
  {
    ++lns;
  }

  //Did something went wrong during the read of this stream?
  if(!dict.eof())
  {
    //Yep, something went wront. Ring the alarms!
    std::cout<<"ERROR: something go wrong during file reading.";
    dict.close();
    std::cout<<"exiting app...";
  }

  //Do not forget to reset the state of the dictionary file object since it is
  //in a error state due to EOF.
  dict.clear();
  //And let the file pointer point to the beginning as it was before all this.
  dict.seekg(0, std::ios::beg);
  return lns;
}

//---------------------------------------------------

unsigned choose_word(unsigned maxnum)
{
  unsigned randnum;
  std::srand(std::time(0));
  randnum= std::rand() % maxnum + 1;
  return randnum;
}

//----------------------------------------------------

std::string fetch_word(std::ifstream& dict, unsigned line)
{
  std::string buffer;
  while( std::getline(dict, buffer) && line != 1)
  {
    --line;
  }

  //Do not forget to reset the state of the dictionary file object since it is
  //in a error state due to EOF.
  dict.clear();
  //And let the file pointer point to the beginning as it was before all this.
  dict.seekg(0, std::ios::beg);

  return buffer;
}

//-----------------------------------------------------------------------------

bool check_guess(const std::string guess, const std::string word)
{
  //Did the user guess right?
  if (guess == word)
  {
    //User Guessed right
    std::cout << "Correct! You guessed the word!" << std::endl;
    return true;
  }
  else
  {
    //User guessed wrong.
    std::cout << "No, that\'s not the word." << std::endl;
    return false;
  }
}
__________________
Valmont is offline   Reply With Quote
Old 08-30-2005, 05:28 PM   #23 (permalink)
smckittr
Scott
 
Join Date: Aug 2005
Posts: 29
smckittr is on a distinguished road
Valmont,
Thank you very much for all your help. I really appreciate it. I'll keep all your advice in mind for my next program.
i downloaded devc++ and ran the program and i see it flash on the screen for a split second and then go away. Any suggestions?

Thanks again
Scott
smckittr is offline   Reply With Quote
Old 08-30-2005, 07:26 PM   #24 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,545
Valmont is on a distinguished road
#include <iostream>

{
std::cin.get();
}

You could try Code::Blocks as well. It's very nice! And no flashing console's either...
__________________
Valmont is offline   Reply With Quote
Old 08-31-2005, 11:01 AM   #25 (permalink)
fp_unit
mike
 
Join Date: Jan 2005
Location: Ottawa, ON
Posts: 79
fp_unit is on a distinguished road
I didnt follow this thread, I just wanted to say theres probably no point in passing bool's by reference OR by pointer. Really. Do a sizeof(bool) and a sizeof(bool*) and I guarantee they're the same size. If you want the values to stick after the function changes them, use pass by reference since you're using C++.

void change(bool& foo);
fp_unit is offline   Reply With Quote
Old 09-01-2005, 01:41 AM   #26 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
Quote:
Originally Posted by fp_unit
Really. Do a sizeof(bool) and a sizeof(bool*) and I guarantee they're the same size.
That depends on your compiler. As far as I know, all that is guaranteed about the size of a bool is:

1 =< sizeof(bool) =< sizeof(long)

Even then, that doesn't mean all compilers stick to that

Also, the size of a pointer isn't always 32-bit, that too depends on the platform.
It's quite possible that the size of a bool is smaller than the size of a pointer. Your point of course still stands. In fact, at least for performance reasons there's little reason to pass anything like bool, long, int, char, etc by pointer. It's probably even slower, since you need to dereference the pointer.

Related to that subject, if you don't modify strings, you generally want to pass them as

const std::string &
Locutus is offline   Reply With Quote
Old 09-01-2005, 05:25 AM   #27 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,545
Valmont is on a distinguished road
The number "1" I can deduce since so no adress can be smaller then sizeof(char). So
sizeof(bool) >= sizeof(char). Which is basically sizeof(bool) >= 1. But from where in the ISO standard can I deduce that sizeof(bool) <= sizeof(long)?
I realize that many systems implement sizeof(bool) = sizeof(word) to evade a performance hit. But that has nothing to do with the ISO standard.
__________________
Valmont is offline   Reply With Quote
Old 09-01-2005, 06:08 AM   #28 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
Well, I haven't got a copy of the standard as such, but that's what Stroustrup writes wrt the sizes of "fundamental types" in "The C++ Programming Language", which supposedly describes the standard.
Locutus is offline   Reply With Quote
Old 09-01-2005, 06:54 AM   #29 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,545
Valmont is on a distinguished road
Oh yes, I just read it. Thanks.
__________________
Valmont is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
c compiling simple question if13121 Standard C, C++ 1 11-12-2004 05:34 AM
simple question 'bout compiling c program if13121 Platform/API C++ 0 11-09-2004 10:36 PM
c simple question problem with switch case if13121 Standard C, C++ 1 10-24-2004 09:43 PM
simple c question if13121 Standard C, C++ 3 10-18-2004 10:20 PM


All times are GMT -8. The time now is 04:29 PM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting