Hirsipuu

Enec 25.02.08 20:30

Hirsipuupeli. :) Pitäisi ainakin g++:lla kääntyä Linuxin puolella ja Borlandilla(tms) Windowsissa.

 Tekstiversio  Arvo: 1 (1 ääntä)  Äänestä: +  -
/* Koodi on kaukana optimaalisesta, sitä
 * voisi helposti lyhentää vaikka kuinka, ja hommia joita
 * hoidetaan omalla funktiolla saisi helposti tehtyä ilmankin,
 * mutta menkööt nyt tällasena. :)
 *
 * Lähinnä stringien ihmeellisyyksiä kävin tässä läpi.
 *
 * Ensimmäinen "isompi" C++ -projektini. C oli tosin tuttua ennestään.
 * Kommentteja kaipailisin, jos jotain on tehty väärin.
 */



/* Simple hangman game.
 *
 * (c) Joeli Hokkanen, 2008
 *     <cene @ fix.fi>
 */


#include <iostream>
#include <string>
#include <ctime>
using namespace std;

bool bValidchar(string sChar);                  // Function for checking if the entered character is valid.
bool bCorrectword(string guess, string answer); // Function to check if a guess is valid.
string sGetWord(void);                          // Getting a random word from list.
int iGetRand(int min, int max);                 // Getting a random number from certain range.
int iGamefunc(void);                            // The actual function where the game is run in.
void vHang(int iTry);                           // Function for the hangman ASCII handling.
void vPrintHang(void);                          // Printing the hangman.
int fakemain(void);                             // "Real" main that can be called recursively.
string sToLow(string sConv);                    // Function for converting strings to lowercase.

char cAscii[7][10];

int main(void) {
 
  time_t seconds;
  time(&seconds);
  srand((unsigned int)seconds);                 // For random number generation.

  return fakemain();
}

int fakemain(void) {
  for (int col = 0; col < 10; col++)
    for (int row = 0; row < 8; row++)
      cAscii[row][col] = ' ';
 
  string resp;
  cout << endl << endl <<
  "**********************************************" << endl <<
  "* Welcome to the simple hangman game.        *" << endl <<
  "*                                            *" << endl <<
  "* To start a new game, press enter           *" << endl <<
  "* To quit, type 'q' or 'quit'                *" << endl <<
  "**********************************************" << endl;
  cout << "> ";
  getline(cin, resp);
 
  if (resp == "q")
    return 0;
 
  else if (resp.empty() == true) {
    if (iGamefunc() != 0)
      return 1;
  }
  else
    fakemain();

  return 0;
}

bool bCorrectword(string guess, string answer) {
  if ((guess.compare(answer)) == 0)
    return true;
  else
    return false;
}

string sGetWord(void) {
 
  /*************
   * Wordlist  *
   *************/


  string words[] = { \
  "apocalypse", "alphabet", \
  "bible", "blood", "brain", \
  "chip", "cipher", "cosine",  \
  "dentist", "dextromethorphan", "downfall" \
  "everlasting", "enthusiast", \
  "fuzzy", "feeling", "foreground", \
  "guilt", "golf", "graduation", \
  "hypotenuse", "height", "home", \
  "important", "ice", "independent", "indestructible", "identical", \
  "jewel", "jail", "janitor", "justice", \
  "keg", "kidney", "kennel", \
  "love", "level", "loop", "luxury", \
  "mother", "mustard", "modify", "major", "may", \
  "number", "needle", "nation", "near", \
  "official", "open", "only", "other", \
  "playoff", "player", "people", "place", \
  "quick", "queer", "queen", "quiz", \
  "robe", "robbery", "roll", "reek", "radio", \
  "sulk", "see", "smoke", "swallow", \
  "thought", "team", "thesis", "television", \
  "ultraviolet", "ugly", "uppercase", "upload", \
  "velocity", "volume", "vision", "verbose", \
  "weight", "well", "wizard", "wear", \
  "xylitol", \
  "yell", "yield", \
  "zebra", "zoophilia" };
 

  int rnd = iGetRand(0,(sizeof(words)/sizeof(*words) -1)); // Getting a random number between 0 and the amount of the words
  return (words[rnd]);
}

int iGetRand(int min, int max) {

  return (rand() % (max - min + 1 ) + min);

}

bool bValidchar(string sChar) {
  char character = sChar[0];
  char cCorrect[26] = {'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
  for (int i = 0; i < 26; i++)
    if (cCorrect[i] == character)
      return true;

  return false;
}
 

int iGamefunc(void) {
  string sWord = sGetWord(); // Getting the word
  string sVisible;           // The string that is visible to user
  string sUsed;              // Holds the list of used characters

  for (unsigned int i = 0; i < sWord.length(); i++) // Inserting the correct amount of underscores to the visible string
    sVisible.append("_");

  string ans;                // Given answer
  int iEnd = 0;              // Trigger to see if game ended (hung or got correct word)
  int iCount;

  do {
    vPrintHang();   // First we'll draw the hangman (or parts of it :-)

    if (sUsed.length() > 10) { // Over 10 used characters, which means we're dead.
      cout << endl << "Game ended, you were hung. The correct word was \"" << sWord << "\", by the way." << endl;
      iEnd = 1;
    }
   
    if (iEnd == 0) {
      cout << endl << endl << endl << "Used characters: " << sUsed << endl <<
      sVisible << endl << endl <<
      "***************************************************" << endl <<
      "* Give a character or your guess.                 *" << endl <<
      "***************************************************" << endl;
      cin >> ans;

      ans = sToLow(ans);                  // Converting everything to lowercase

      if (ans.length() > 1) {
        if ((bCorrectword(ans, sWord)) == true) {
          iEnd = 1;
          cout << endl << "Correct answer " << ans << "!!!";
        }
        else {
          cout << endl << "Incorrect answer \"" << ans << "\".";
          continue;
        }
      }
      else {
        if ((bValidchar(ans)) == true) {  // Let's see if the given character is valid
          iCount = 0;
          for (unsigned int i = 0; i < sWord.length(); i++) {
            if (sWord.compare(i, 1 ,ans) == 0) {
              sVisible.replace(i, 1, ans);
              iCount++;
            }
          }
          if (iCount == 0) {
            if (sUsed.find(ans) == string::npos) {
              sUsed.append(ans);
              vHang(sUsed.length());
            }
            else
              continue;
          }
        }
        else
          cout << "Illegal character " << ans << "!!" << endl;
      }
    }
  }
  while (iEnd == 0);


  cin.ignore();         // Required for getline(); to work properly on fakemain();
  fakemain();
 
  return 0;
}

void vHang(int iTry) {  // Inserts new parts of the drawing to the cAscii array
  switch(iTry) {        // which is drawn with vPrintHang();
    case 1:
      cAscii[6][1] = '+';
      cAscii[7][1] = '|';
      cAscii[6][2] = '-';
      break;

    case 2:
      cAscii[6][5] = '+';
      cAscii[7][5] = '|';
      cAscii[6][4] = '-';
      break;

    case 3:
      cAscii[6][3] = '+';
      for (int ht = 5; ht > 1; ht--)
        cAscii[ht][3] = '|';
      break;

    case 4:
      cAscii[1][3] = '+';
      for (int upcol = 4; upcol < 8; upcol++)
        cAscii[1][upcol] = '-';
      cAscii[1][8] = '+';
      break;

    case 5:
      cAscii[2][4] = '/';
      cAscii[2][8] = '|';
      break;

    case 6:
      cAscii[3][8] = 'O';
      break;

    case 7:
      cAscii[4][8] = '|';
      break;

    case 8:
      cAscii[4][7] = '/';
      break;

    case 9:
      cAscii[4][9] = '\\';
      break;

    case 10:
      cAscii[5][7] = '/';
      break;

    case 11:
      cAscii[5][9] = '\\';
      break;
  }
}

void vPrintHang(void) {

  for (int row = 0; row < 8; row++) {
    for (int col = 0; col < 10; col++)
      cout << cAscii[row][col];
    cout << endl;
  }
}

string sToLow(string sConv) {

  for (unsigned int i = 0; i < sConv.length(); i++)
    sConv[i] = tolower(sConv[i]);

  return sConv;
}