• Welcome to Valhalla Legends Archive.
 

Creating a Word Guessing Game

Started by warz, June 05, 2003, 09:41 AM

Previous topic - Next topic

warz

Here's a little something i made out of boredom in computer science. Might be of some use...


// Final Exam Problem 2
// Ryan Cole

#include <iostream.h>
#include <stdlib.h>
#include <string.h>
#include "oostring.cpp"

void GetSecret(oostring &Secret);
void DoLetterGuess(char Letter, oostring &Secret, oostring &Guess, int &Tries);

int main()
{
   oostring Secret;            // initialize variables
   oostring Guess = "";
   oostring Attempt = "";
   const char GuessSignal = '$';
   int Tries = 0;
   char Letter;
   char tempdash[] = "";

   GetSecret(Secret);            // call getsecret()
   for(int x = 0; x <= Secret.length() - 1; x++)
   {
      strcat(tempdash, "-");      // create the dashed helper
   }
   Guess = tempdash;

   do{
      cout << "Word is " << Guess << '.' << endl;      
      cout << "Your letter (type $ to guess the word): ";
      cin >> Letter;
      if(Letter == '$')      // check for guess
      {
         cout << "Your guess: ";
         cin >> Guess;
      } else {
         DoLetterGuess(Letter, Secret, Guess, Tries);   // do letter try
      }
   } while( Guess != Secret );
   cout << "CORRECT! You took " << Tries << " tries.\n";   // correct

   return 0;
}

void DoLetterGuess(char Letter, oostring &Secret, oostring &Guess, int &Tries)
{
   int CorrectCount = 0;
   for(int x = 0; x < Secret.length(); x++)      // loop through guessed word
   {
      if( Secret[x] == Letter)
      {
         CorrectCount++;
         Guess[x] = Letter;
      }
   }
   if( CorrectCount == 0)
      cout << "Sorry, there are no " << Letter << "'s" << endl;
   Tries++;
}

void GetSecret(oostring &Secret)
{
   cout << "Enter word to be guessed: ";
   cin >> Secret;
   system("CLS");            // clear screen
}

Yoni

You aren't supposed to #include a cpp, nor use the deprecated iostream.h, or stdlib.h/string.h in C++ code... And what's an oostring? Use std::string.

Sounds like your computer science class is as outdated as pretty much damn near almost all computer science classes in existence. :(

Grok

Don't use iostream.h?  What then? Educate!

warz

My bad, I'll post oostring.h when I go back to school tomorrow. I included a cpp file because it reduced a few errors that I didn't know how to fix, and that somehow fixed them. Aren't 'supposed' to use them? Since when were there rules on what I could use and not use?  :P

Eibro

Instead of <iostream.h> use <iostream>. It's contents are contained in namespace std. iostream.h and similar standard headers with .h appended are only included in modern compilers for backwards compatability.
Eibro of Yeti Lovers.

Camel

#5
Quote from: Yoni on June 05, 2003, 10:32 AM
You aren't supposed to #include a cpp, nor use the deprecated iostream.h, or stdlib.h/string.h in C++ code... And what's an oostring? Use std::string.

Sounds like your computer science class is as outdated as pretty much damn near almost all computer science classes in existence. :(

i had an argument with my com sci teacher (and won btw) about that; apstring includes cpp files (and it gets away because it is distributed as source, not a library)

[edit] btw, aplib sucks. real men use pointers and arrays. :)

Yoni

What argument did you have? Did you claim it was correct or incorrect to #include source files?

(And I am not familiar with aplib.)

K

#7
the apstring class doesn't include a source file.  the apstack, apqueue, apvector (...etc) do and (sort of) get away with it because they're templated classes. By #include-ing "apfile.cpp"  at the bottom of the header, it allows them to implement the class in seperate source file. Anyway, no argument here about the suckiness of aformention ap classes. They're good for what they're meant to do, which is be used in an introductory class.  No one in their right mind would use them in another setting.

Camel

Quote from: Yoni on June 05, 2003, 05:34 PM
What argument did you have? Did you claim it was correct or incorrect to #include source files?

(And I am not familiar with aplib.)

i was arguing that it's wrong to #include a cpp file in every sense. you're not supposed to give anybody access to your actual functions. if you were, there wouldnt be header files at all. same reason global vars shouldn't be used.
he was defending aplib not because they're correct in #including cpp files (because they're not), but that the class is for n00blets that will never use c++ again after the class ends. i argued back that there's no point of having a header file if it's going to include the cpp file.
header files (.h) are supposed to be the only thing third-party code can see. they can't modify the function or do any of that crap, they can only call it.
source files (.c/.cpp) are where the actual functions are intended to be written.
when combined with secure classes (by secure, i mean using protected variables), seperating header files from source files is the most effective way to fix bugs and close security holes.

pcode:

<computer.h>
class computer
{
public:
    computer(int ramsize, int cpuspeed, cpu_t cputype);
    virtual ~computer();
    int turn_on();
    int turn_off();

    int log_in(char *login, char *pass);
    int log_out();
    int run_program(char *apppath);

    int who_is_logged_in(OUT char *lpszUser);

protected:
    char **system_memory; //pointer to memory array
    int cpu_speed; //cpu speed in Hz
    cpu_t cpu_type; //cpu type enum
    char *userloggedin;

    int write_memory(int address, void *lpData, int length); //allow only functions within the class to write to memory
    void * read_memory(int address, int length); //allow only functions within the class to read memory
    int close_all_programs();
private:
    void explode(); //don't allow anybody to blow up the computer

};

<computer.cpp>
#include "computer.h"

computer::computer(int ramsize, int cpuspeed, cpu_t cputype)
{
    cpu_speed = cpuspeed;
    cpu_type = cputype;
    ...
}

computer::~computer()
{
    turn_off();
    ...
}

int computer::turn_on()
{
    system_memory = (char**)malloc(ramsize);
    ...
}
int turn_off()
{
    close_all_programs();
    log_out();
    free(system_memory);
    ...
}

int computer::log_in(char *login, char *pass)
{
    //verify if password is correct
    ...
    userloggedin = login;
    ...
}
int computer::run_program(char *apppath)
{ ... }

int computer::who_is_logged_in(OUT char *lpszUser)
{
    lpszUser = malloc(strlen(userloggedin)+1); //leave space for null
    memcpy(lpszUser, userloggedin, strlen(userloggedin));
    lpszUser[strlen(userloggedin)] = 0; //null-terminate
    ...
}


implementation:

<main.cpp>

int main(int argc, char **argv)
{
   class computer CamelsComputer;
   CamelsComputer = new class computer(768<<16, 1730<<16, AMD_Athalon_2100+);

   /* none of the following will work */
   CamelsComputer.userloggedin = "root"; //root the box
   CamelsComputer.write_memory(0, NULL, 512<<16); //erase all memory
   CamelsComputer.close_all_programs();
   CamelsComputer.explode();

   /* the correct way */
   CamelsComputer.turn_on();
   CamelsComputer.log_in("Camel", "*******");
   CamelsComputer.run_program("/home/camel/path/to/uberleetprogram");
   CamelsComputer.run_program("ping -t www.valhallalegends.com");
   CamelsComputer.log_in("root", "******");
   CamelsComputer.run_program("/root/explode");
   CamelsComputer.turn_off();

   delete CamelsComputer;
}


now, anybody can use class computer, but nobody can skrew with it or modify the memory or any of that crap.

Quote from: K on June 05, 2003, 05:39 PM
the apstring class doesn't include a source file.  the apstack, apqueue, apvector (...etc) do and (sort of) get away with it because they're templated classes. By #include-ing "apfile.cpp"  at the bottom of the header, it allows them to implement the class in seperate source file. Anyway, no argument here about the suckiness of aformention ap classes. They're good for what they're meant to do, which is be used in an introductory class.  No one in their right mind would use them in another setting.

the origional aplib doesnt #include cpp files, but the 2002 version does
c'mon, i'm not blind and retarded

K

#9
Quote
the origional aplib doesnt #include cpp files, but the 2002 version does
c'mon, i'm not blind and retarded

Read carefully, I'm not arguing that it doesn't.  What I said was that the reason that the author chose to #include them was because of a conflict in good coding practices:
1. to implement templated classes correctly, the implementation must precede it's use.  This is why templated classes are implemented in header files.
2. header files are for declaration, source files are for implementation. This produces cleaner, nicer projects.

Because the ap classes are used as a teaching tool, the author decided that to encourage both of these practices, they would #include the source file at the end of the header file.  In this case it is a weird way to accomplish the goal, but there is nothing inherently wrong about it.

http://www.collegeboard.com/ap/students/compsci/classes.html
QuoteMany students often ask whether apstring.h is missing "#include apstring.cpp" just before the #endif at the end of the file. Apstring is not a templated class and therefore is a bit different than the other apclasses (apvector, apmatrix, apstack and apqueue). Although adding "#include apstring.cpp" at the end of apstring.h may work, the preferred method is to include it in the project rather than in the header file. This is the preferred method because linker problems can arise when you start using programs that have multiple separately compiled classes that each use the apstring class.

Camel

Quote from: K on June 06, 2003, 07:27 PM
Quote
the origional aplib doesnt #include cpp files, but the 2002 version does
c'mon, i'm not blind and retarded

Read carefully, I'm not arguing that it doesn't.  What I said was that the reason that the author chose to #include them was because of a conflict in good coding practices:
1. to implement templated classes correctly, the implementation must precede it's use.  This is why templated classes are implemented in header files.
2. header files are for declaration, source files are for implementation. This produces cleaner, nicer projects.

Because the ap classes are used as a teaching tool, the author decided that to encourage both of these practices, they would #include the source file at the end of the header file.  In this case it is a weird way to accomplish the goal, but there is nothing inherently wrong about it.

http://www.collegeboard.com/ap/students/compsci/classes.html
QuoteMany students often ask whether apstring.h is missing "#include apstring.cpp" just before the #endif at the end of the file. Apstring is not a templated class and therefore is a bit different than the other apclasses (apvector, apmatrix, apstack and apqueue). Although adding "#include apstring.cpp" at the end of apstring.h may work, the preferred method is to include it in the project rather than in the header file. This is the preferred method because linker problems can arise when you start using programs that have multiple separately compiled classes that each use the apstring class.

another reason i dont like aplib: templates are ultra-eww.
how i would do it:


<apsux.h>
/* templates */
class apsux
{ ... };

typedef class apsux APSUX;

<apsux.cpp>
#include "apsux.h"

apsux::somefunction()
{ ... }

...

<main.cpp>
#include "apsux.h"

void main(int argc, char **argv)
{
    APSUX myApSux;
    ...
}


it isn't the accepted method, but it's the best because:
1) it will never present linker errors because one can skip the declarations if included more than once
2) it doesnt expose the code directly to the user, allowing the apsux lib to be compiled individually as a dll or other library/resource


the *best* way would simply be to not use classes at all. as i said, templates are eww. however, if they used templates in order to teach templates, then that's excusable.

K

#11
I guess you're right, writing VectorForInts VectorForFloats VectorForMyStruct VectorForStrings and VectorForBytes classes, and then writing a new vector class everytime you need to store a different class is much easier than writing a generic templated vector class.  

You can't do what you've posted above with a templated class. The compiler has to know the implementation of the template before it can be used.

///////// apsux.h ////
#pragma once

template <class t>
class apsux
{
public:
   apsux();
   t somefunction( const t &myvar);
};

///////// apsux.cpp ////
#include "apsux.h"

template <class t>
t apsux<t>::somefunction(const t &myvar)
{
   return myvar;
}


template <class t>
apsux<t>::apsux()
{
   
}

///////// main.cpp ////

#include <iostream>
#include "apsux.h"

using std::cout;
using std::endl;

int main(int argc, char **argv)
{
   apsux<int> myApSux;
   cout << myApSux.somefunction(53) << endl;
}



error LNK2019: unresolved external symbol "public: __thiscall apsux<int>::apsux<int>(void)" (??0?$apsux@H@@QAE@XZ) referenced in function _main
error LNK2019: unresolved external symbol "public: int __thiscall apsux<int>::somefunction(void)" (?somefunction@?$apsux@H@@QAEHXZ) referenced in function _main

Camel

#12
woops, i forgot to mention the magic part
#define something in the cpp before you #include apsux.h
then, in apsux.h:

#if something
#define classdefthingy template <class t>
#else
#define classdefthingy
#end if

classdefthingy
class apsux
{ ... };

...


[edit] btw, i've never tested it because i dont use templates. templates are designed for lazy programmers: people who only want to change something in one place, not five. why bother when one could spend a tenth of the time just writing five classes? templates aren't bad in theory, but neither is communism.

K

#13
Quote from: Camel on June 07, 2003, 04:25 PM
[edit] btw, i've never tested it because i dont use templates. templates are designed for lazy programmers: people who only want to change something in one place, not five. why bother when one could spend a tenth of the time just writing five classes? templates aren't bad in theory, but neither is communism.
I'm speechless.

When realize you have hard to find bugs or want to add features in your ten classes that are 99.9% the same, enjoy fixing each class in turn.  Oh, and don't use Find - Replace.  Find - Replace is for lazy programmers! Don't use an IDE like Anjunta or Visual Studio, those are for wusses.  In fact, structured programming languages are for lazy programmers.

It doesn't make you "lazy" to use a tool to simplify repetative tasks. It makes you "smart."

Camel

Quote from: K on June 07, 2003, 04:38 PM
Quote from: Camel on June 07, 2003, 04:25 PM
[edit] btw, i've never tested it because i dont use templates. templates are designed for lazy programmers: people who only want to change something in one place, not five. why bother when one could spend a tenth of the time just writing five classes? templates aren't bad in theory, but neither is communism.
I'm speechless.

When realize you have hard to find bugs or want to add features in your ten classes that are 99.9% the same, enjoy fixing each class in turn.  Oh, and don't use Find - Replace.  Find - Replace is for lazy programmers! Don't use an IDE like Anjunta or Visual Studio, those are for wusses.  In fact, structured programming languages are for lazy programmers.

It doesn't make you "lazy" to use a tool to simplify repetative tasks. It makes you "smart."

i said five! the flame was directed at aplib
and btw, you should use inheriance if your classes are 99.9% the same