Hi everyone!

I am a class XII student. I have been asked to make a project using c++. I have decided to make a word game. The game's objective is:

* show a random jumbled word stored in a file
* ask the user to enter any valid words that comprise only of the letters available in that word
* no repetitions allowed
* score should be incremented by 10 times the length of the string

The file I used are: data.txt, words.txt, score.txt.
data.txt: for inputting the words
words.txt: list of 58,000 words
score.txt: to save the scores
This is my source code:

// *************************** C++ project *********************
#include<fstream.h>
#include<string.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#include<dos.h>
#include<stdio.h>

struct string
{
  char a[20];
};

struct points
{
  char name[6];
  int num;
};

void start();
void help();
void high(int =0);
void menu();

void main()
{
  clrscr();
  menu();
  getch();
}

void start()
{
  // variables: n-> arbitrary variable, k-> running variable
  int score=0, times=0, n=0, k=0;
  char jum[20], temp[20];
  string read[10];
  // generate random word from data.txt
  randomize();
  n = random(100);

  ifstream file("data.txt");
  for(int i=0; i<n; ++i)
  {
    file>>jum;
  }

  do
  {
    clrscr();
    int check1=0, check2=1, check3=0;
    cout<<"\n\n\t LeTs pLaY ThE gAmE... :D ";
    cout<<"\n\t Score: "<<score<<"\t\t Chances Left: "<<10-times;
    cout<<"\n\n\t Your Word is: "<<jum;
    cout<<"\n\t Enter text: ";
    cin>>read[k].a;
    cout<<"\n initiating check(s)... ";

  // check(1) if all the letters are available in the word

    for(int q=0; q<strlen(read[k].a); ++q)
    {
      check1=0;
      for(int p=0; p<strlen(jum); ++p)
      {
	if( read[k].a[q] == jum[p])
	{ check1=1; }
      }
      if(check1 == 0)
      {
	cout<<"\n\n\t all char(s) in text aren't available!!! ";
	break;
      }
    }

    cout<<"\n Check1 completed... ";
    cout<<"\n Check1= "<<check1;

  // check(2) if it has been entered already

    for(int r=0; r<=k; ++r)
    {
      if(strcmp(read[k].a, read[r].a)==0)
      {
	check2=0;
	break;
      }
    }

    cout<<"\n Check2 completed... ";
    cout<<"\n Check2= "<<check2;

  // check(3) if the word exists

    ifstream word("word.txt");

    while(word)
    {
      word>>temp;
      if(strcmp(temp, read[k].a)==0)
      {
	check3=1;
	break;
      }
    }

    cout<<"\n Check3 completed... ";
    cout<<"\n Check3= "<<check3;

  // increment score if all check(s) are valid( i.e. ==1 )
    cout<<"\n Check1 + Check2 + Check3 = "<<check1 + check2 + check3;
    if(check1 + check2 + check3 == 3)
    {
      score = score + 10*strlen(read[k].a);
    }

    ++k;
    ++times;
    word.seekg(0);
    word.close();

  }// end of do loop
  while(times<10);

  cout<<"\n\n\t cOnGrAtS!!! yOu hAvE sEcUrEd "<<score<<" pOiNtS... ";
  file.close();
  high(score);
}

void high(int score)
{
  clrscr();
  points sco1,sco2;
  fstream ifile("score.txt", ios::in);
  ofstream ofile("temp.txt", ios::out);
  char name[20];
  int k=0;
  if(score!=0)
  {
    cout<<"\n\n\t\t CONGRATS... YOU MADE IT TO THE HIGH SCORES... ";
    cout<<"\n\n\t\t Enter Your Name: ";
    cin>>sco2.name;
    sco2.num=score;
    while(ofile)
    {
      ifile.read((char *)&sco1, sizeof(sco1));
      if(sco1.num>score)
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
      if(sco1.num<sco2.num && k==0)
      {
	 ofile.write((char *)&sco2, sizeof(sco2));
	 k++;
      }
      if(sco1.num<sco2.num )
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
    }

   }
   ifile.close(); ofile.close();
   remove("score.txt");
   rename("temp.txt","score.txt");
   ifstream file("score.txt", ios::in);
   if(score==0)
   {
      cout<<"\n\n\t\t\t HIGH SCORES ";
      cout<<"\n\t\t\t ==== ======";
      cout<<"\n\n PLAYER";cout<<"\t\t\t SCORE";
      cout<<"\n ------"; cout<<"\t\t\t -----";
      while(file)
      {
	 file.read((char *)&sco1, sizeof(sco1));
	 cout<<sco1.name<<"\t\t\t "<<sco1.num;
      }
   }
   cout<<"\n\n\t Press a key to proceed to main menu... ";
   getch();
   menu();
}
void help()
{
  clrscr();
  cout<<"\n\n\t RULES OF PLAY ";
  cout<<"\n\t ============= ";
  cout<<"\n\n\t You will be given a 10 charachter word in its jumbled form. ";
  cout<<"\n\t You must enter words of four charachters or above using the letters in the word";
  cout<<"\n\t If you can guess the jumbled word correctly or manage to score more than 100 points, You win!!! ";
  cout<<"\n\n\n\t Press any key to proceed to main menu... ";
  getch();
  menu();
}
void menu()
{
  clrscr();
  cout<<"\n\t\t SCRABBLE GAME IN C++";
  cout<<"\n\t\t ======== ==== == ===";
  cout<<"\n\n\t\t 1. Start"<<endl;
  cout<<"\n\t\t 2. Help"<<endl;
  cout<<"\n\t\t 3. High Scores"<<endl;
  cout<<"\n\t\t 4. Exit"<<endl;
  cout<<"\n\t\t Enter Choice: ";
  int ch;
  cin>>ch;
  switch(ch)
  {
   case 1: start();
	   break;
   case 2: help();
	   break;
   case 3: high(0);
	   break;
   case 4: exit(0);
	   break;
   default: clrscr(); menu(); cout<<"\n\t\t Wrong Choice!!! ";
  }

}

The compiler shows no errors at all! But something is not right with my source code. I request you all to kindly go through it patiently and help me debug it. I experience the following problems:

1) When I Run start(); I don't get all the outputs, like check1, etc.
2) score is always zero
3) the high score displayed after start() is not the same as that viewed directly from menu()

Please help me out!!!

1)What do you mean by don't get it? You mean no print at all or value is not correct?

for(int q=0; q<strlen(read[k].a); ++q) {  // each char in read[k]
      check1=0;  // <-- should be outside the loop and set to 1
      for(int p=0; p<strlen(jum); ++p) {
        if( read[k].a[q] == jum[p])  { check1=1; }
//      Instead of checking equal, check if not equal and reset the check value
//      because not all chars are in the word and could break from the loop.
//      If break from the inner loop, should also break again from the outer loop.
      }
      if(check1 == 0) {  // <-- should also be displayed outside the loop
        cout<<"\n\n\t all char(s) in text aren't available!!! ";
        break;
      }
    }

2)Score is always 0 because it would be changed if the total of check is equal to 3, and it never will...
3)What do you mean? Could you give an example?

Edited 6 Years Ago by Taywin: n/a

The logic behind check(1) is :
It considers each entry in the kth string of the array read; and searches for it in 'jum'. If found, check1=1; else check1 remains zero. I output "all char(s) in text aren't available!!!" after ensuring that it doesn't match with entries in 'jum'.
If all entries are valid, then it exits the loop with check1=1, as the final element in read[k].a is available!
Thus, check1 should have the value 1.

But I don't get any output beyond "Enter text: "; not even "initiating check(s)... ". But the do loop seems to run completely as "times" is incremented by 1, appropriately.

I would like to know why it skips the lines after " cin>>read[k].a;"

I'm not sure about your sting struct. Try to change the name of your

struct string {
}

to something else that is not call 'string'.

No, changing the name of the string doesn't make a difference! Not even this line executes:

while(times<10);
  cout<<"\n\n\t cOnGrAtS!!! yOu hAvE sEcUrEd "<<score<<" pOiNtS... ";// <-- this one
  file.close();

When you said about not getting in your struct, I am not sure about how it would take. In your struct, you use an array of char. When cin get the input from user, I am not sure whether it really put the string in your char array correctly. I mean I am not sure if it actually puts the end of string in your char array. How about create a string right before you assign the cin to your struct array? And then assign it to your array, and then try to print it out again? That may clear up the problem when you do the cin>>read[k].a.

Sorry, that didn't work either! Could you give me a snippet on how you exactly want me to try it? Note that it must also run the do-while loop correctly. I even tried to receive the string in an temporary char array and then copy that to read[k].a; not even that worked! Is there any other alternative to my code?

Hmm... I need a computer with C++ compiler... Let me try to download a compiler so I can test your code... I have none in my computer right now.

What compiler are you using? Do you use any namespace?

EDIT: Found out one thing, your loop does not wait to display the message if the enter word is not completely correct. Put in a function to make the system wait right above while (time<10).

Edited 6 Years Ago by Taywin: n/a

I use turbo c++ 3.0 as prescribed by my school. But it ain't so good. No, I don't have to use namespace!

Thanks for that, but check3 all results in zero. Why? Whenever I search for the word in the file word.txt, it never finds it! Kindly look into high() also; as the output is not the same always; i.e. when I access it through menu() and through start(), the results don't match!!!

Do you mean you have content inside score.txt? I tried it with an empty file, it displayed garbage (random value).

I tried your code using Dev C++ which is much newer version compared to Borland. I don't know why your school is still using an out-dated C++ compiler... :(

Edited 6 Years Ago by Taywin: n/a

Hey, I managed to rectify the error in high(); but still couldn't solve the error in start(); I don't know why check3 always results in zero! here is the change I have made in high();
previously:

if(score!=0)
  {
    cout<<"\n\n\t\t CONGRATS... YOU MADE IT TO THE HIGH SCORES... ";
    cout<<"\n\n\t\t Enter Your Name: ";
    cin>>sco2.name;
    sco2.num=score;
    while(ofile)
    {
      ifile.read((char *)&sco1, sizeof(sco1));
      if(sco1.num>score)
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
      if(sco1.num<sco2.num && k==0)
      {
	 ofile.write((char *)&sco2, sizeof(sco2));
	 k++;
      }
      if(sco1.num<sco2.num )
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
    }
   }// if ends...
  // outside if
    ifile.close(); ofile.close();
    remove("score.txt");
    rename("temp.txt","score.txt");
    ifstream ifile("score.txt", ios::in);

Now...

if(score!=0)
  {
    cout<<"\n\n\t\t CONGRATS... YOU MADE IT TO THE HIGH SCORES... ";
    cout<<"\n\n\t\t Enter Your Name: ";
    cin>>sco2.name;
    sco2.num=score;
    while(ofile)
    {
      ifile.read((char *)&sco1, sizeof(sco1));
      if(sco1.num>score)
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
      if(sco1.num<sco2.num && k==0)
      {
	 ofile.write((char *)&sco2, sizeof(sco2));
	 k++;
      }
      if(sco1.num<sco2.num )
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
    }
   // inside if...
    ifile.close(); ofile.close();
    remove("score.txt");
    rename("temp.txt","score.txt");
    ifstream ifile("score.txt", ios::in);
   }// outside if...

please help me solve the error in start();

I think that strcmp use the c string. If you want to be sure, you could implement your own string comparison as another function. That way, you would know what it should be returned.

At a first glance here are a few suggestions: check1 is not running. Your code is faulty because once check1==0 it should come out of the for loops because there is no need for further iterations which it is not. check2 is unable to check the first word for previous entries and is check2==0 for the first entry. It should be check2==1. For that :

if(k==0)
		check2=1;
	if (k>0)
	{
    for(int r=0;r<k; ++r)
    {
      if(strcmp(read[k].a, read[r].a)==0)
      {
	check2=0;
	break;
	  }
	  else
	  {
		  check2=1;
		  
		  }
	}
    }

    cout<<"\n Check2 completed... ";
    cout<<"\n Check2= "<<check2;

Also in your code the last for iteration will check the word against itself and hence will always return 0; So change it to for(int r=0;r<k; ++r).
check3 is perfectly ok and I don’t know why it is not working for you. Check your .txt files.
You said your high() is working now. So you should get the output now.
BTW what is in scrore.txt?
cheers

@mtbs1826

Yes, I have made those corrections. But check3 always results in zero! As suggested by Taywin, I tried to create my own string comparison function, but the results are still the same! Kindly look into it!

Cheers

In score.txt, I have saved "Nobody" and 0 using a similar structure! High seems to work pretty fine!

Hey Sorry Guys! Don't laugh at me! I made a terrible mistake by trying to open "word.txt" as the file was "words.txt".
But there is one more problem! The output screen gets stuck, after I enter a name into High().

void high(int score)
{
  clrscr();
  points sco1,sco2;
  fstream ifile("score.txt", ios::in);
  ofstream ofile("temp.txt", ios::out);
  char name[20];
  int k=0;// same as flag, just to check if it has already been entered into temp.txt
  if(score!=0)
  {
    cout<<"\n\n\t\t CONGRATS... YOU MADE IT TO THE HIGH SCORES... ";
    cout<<"\n\n\t\t Enter Your Name: ";
    cin>>sco2.name;
    sco2.num=score;
    while(ofile)
    {
      ifile.read((char *)&sco1, sizeof(sco1));
      if(sco1.num>score)
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
      if(sco1.num<sco2.num && k==0)// <-- it gets stuck here!
      {
	 ofile.write((char *)&sco2, sizeof(sco2));
	 k++;
      }
      if(sco1.num<sco2.num )
      {
	 ofile.write((char *)&sco1, sizeof(sco1));
      }
    }

   ifile.close(); ofile.close();
   remove("score.txt");
   rename("temp.txt","score.txt");
   ifstream ifile("score.txt", ios::in);
   }

   if(score==0)
   {
      cout<<"\n\n\t\t\t HIGH SCORES ";
      cout<<"\n\t\t\t ==== ======";
      cout<<"\n\n PLAYER";cout<<"\t\t\t SCORE";
      cout<<"\n ------"; cout<<"\t\t\t -----"<<endl;
      while(ifile)
      {
	 ifile.read((char *)&sco1, sizeof(sco1));
	 cout<<sco1.name<<"\t\t\t "<<sco1.num<<endl;
      }
   }
   cout<<"\n\n\t Press a key to proceed to main menu... ";
   getch();
   menu();
}

Substitute if in place of while in lines 15 & 45. why score==0 in line 39? Remove it and close the if loop in line 9 at the end of the function. There could be other problems like reading binary files etc.

Cheers

I need while in lines 15 & 45, because the file words.txt has over 58,000 words and each of them has to be read! Similarly score.txt also has some data. When I pass score as 0, I just want the compiler to output the contents of the file score.txt. Else I want it to add the new high score to the list!

You are reading words by ifstream word by a while loop which is correct. Files score.txt and temp.txt will always contain only 1 record each. So you can safely use if loop if code is otherwise correct.
int k=0 in high(int) will always be true. If the score is greater then 2nd and 3rd if condition in line 22 and 27 will both be true. Better to keep 2nd . High score is not displayed when high(int) is called from menu(). There could be problems in reading binary files too. After all corrections the while loops will work.
Also you should not use name string for a struct or class. It will be ambiguous with the library string class.

I am afraid, both score.txt and temp.txt have multiple records! Changing the name of the struct didn't make a difference. How do I rectify the problems while reading binary files?

You are correct, missed your point...a few suggestions:
Score.txt is empty at program start how you have written to it since it is binary?
While(outfile) must be while(ifile) since temp.txt is empty
Change line to ofstream ofile("temp.txt", ios::out | ios::app); it will add records at end of temp.txt instead of overwriting each write.
Furthermore when high() is called from menu() unnecessary calculations are done and possible error sources.
Try while(!ifile.eof()) instead of while(ifile). Check if new line be found at the end of file giving same record.
Should rewrite function as per menu().

Firstly, I have written the data (Nobody, 0) into the file score.txt using a separate program with a similar structure. I want the contents to change dynamically with respect to the new scores of the players. Hence the file score.txt isn't empty before the 1st time the program is executed!
Secondly, if I use ios::app, then writing the program accordingly will become more complicated, as all I need is only to insert the new record appropriately. I need to overwrite data!
Finally, !ifile.eof() and ifile are one and the same; as while(ifile) means the loop must run till the last record of the file is read!

This article has been dead for over six months. Start a new discussion instead.