I wrote a simple bubble game... but it look long and complicated... so any idea to short it down? i heard about class.. but i dunno how to use it.. so is my program can use class? or any idea to short it down?

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

void introduce (char pos[][10]);
void random_board (char pos[][10]);
void show_board (char pos[][10]);
int change (char x);
void setAsZero (char a[][10]);
void SetSame (char pos[][10],char same[][10],char checked[][10],int x, int y);
void explode (char pos[][10],char same[][10]);
int checkSpace (char pos[][10]);
void arrangement (char pos[][10],int largest_space);
int gameover(char pos[][10],int x, int y);
int check_score (char same[][10]);
int check_skip (char pos[][10],int x,int y);

main()
{
      char pos[10][10],x_char;
      int x,y,largest_space;
      int end=1,score=0,Total_score=0,skip=0;
      char same[10][10],checked[10][10];

      random_board(pos);      
      introduce(pos);
      setAsZero (checked);
      setAsZero (same);

      while(true)
      {
      if(end==0)                                          //end the game
      break;
      show_board(pos);                                    //show board
      cout<<"Your score is "<<Total_score<<endl;
      cout<<"Enter the position: ";
      cin>>x_char>>y;                                   
      x=change(x_char);                                   //change char to int
      skip=check_skip (pos,x,y);                          //skip step if pos is ' '
      if(skip==0)                                         //below are the steps of whole game
      {
          SetSame (pos,same,checked,x,y);                     //Set same and checked   
          explode (pos,same);                                 //explode
          largest_space=checkSpace(pos);                      //check largest space at y axis
          arrangement (pos,largest_space);                    //arrange
          score=check_score (same);                           //check score of 1 round
          setAsZero (checked);                                //reset checked
          setAsZero (same);                                   //reset same
          Total_score=Total_score+score;
          end= gameover (pos,x,y);                            //c end game d o nt
      }
      skip=0;
      system("cls");
      }
      cout<<"Game Over!!!\nYour Score is "<<Total_score<<endl;

      system("pause");
      return EXIT_SUCCESS;

      }

void introduce (char pos[][10])
{
     cout<<"  **************************\n";
     cout<<"  * WELCOME TO BUBBLE BOOM *\n";
     cout<<"  **************************\n";
     cout<<"\n\n";
     show_board(pos);
     cout<<"\n\n";
     cout<<"Rule:\n1)explode the same symbol which gather around.\n2)At first u hv 1 point.\n3)if u explode 2 bubbles has 2 points,3 bubbles 4 point, 4 bubbles 8 points and so on.\n4)At least explode 2 bubbles.\n";
     system("pause");
     system("cls");
}

void random_board (char pos[][10])
{
     srand((unsigned)time(0)); 
     for(int i=0;i<10;i++)
     for(int j=0;j<10;j++)
             pos[i][j]=rand()%4+35;
}

void show_board (char pos[][10])
{
     for(int i=0;i<10;i++)
     {
     cout<<i<<"    ";
     for(int j=0;j<10;j++)
     cout<<pos[j][i]<<" ";
     cout<<endl;
     }
     cout<<"\n     a b c d e f g h i j \n";
}

int change (char x)
{
    for(int i=0;i<10;i++)
    if (x==97+i)
       return i;
}

void setAsZero (char a[][10])
{
     for(int i=0;i<10;i++)
     for(int j=0;j<10;j++)
     a[i][j]=' ';
}

//------------------------------------------------------------------------------
void SetSame (char pos[][10],char same[][10],char checked[][10],int x, int y)
{
     char temp;

     if(checked[x][y]!='c')
         temp=pos[x][y];

     if(pos[x-1][y]==temp && x!=0 && checked[x-1][y]!='c' && temp!=' ')    //check left is same or nt? and left checked or nt?
     {
         same[x][y]='s';
         checked[x][y]='c';
         SetSame (pos,same,checked,x-1,y);
     }    
     if(pos[x+1][y]==temp && x!=9 && checked[x+1][y]!='c' && temp!=' ')
     {
         same[x][y]='s';
         checked[x][y]='c';
         SetSame (pos,same,checked,x+1,y);
     }             
     if(pos[x][y-1]==temp && y!=0 && checked[x][y-1]!='c' && temp!=' ')
     {
         same[x][y]='s';
         checked[x][y]='c';
         SetSame (pos,same,checked,x,y-1);
     }             
     if(pos[x][y+1]==temp && y!=9 && checked[x][y+1]!='c' && temp!=' ')
     {
         same[x][y]='s';
         checked[x][y]='c';
         SetSame (pos,same,checked,x,y+1);
     }
     if((pos[x][y+1]==temp && y!=9) || (pos[x][y-1]==temp && y!=0) || (pos[x+1][y]==temp && x!=9) || (pos[x-1][y]==temp && x!=0))
     {
         same[x][y]='s';
         checked[x][y]='c';
     }
}

void explode (char pos[][10],char same[][10])
{
     for(int i=0;i<10;i++)
     for(int j=0;j<10;j++)
     {
         if (same[i][j]=='s')
            pos[i][j]=' ';
     }
}

int gameover (char pos[][10],int x, int y)
{
     int end=0;
     for(int i=0;i<10;i++)
     for(int j=0;j<10;j++)
     {
             char temp=pos[i][j];
             if(pos[i-1][j]==temp && i!=0 && temp!=' ')
             {
             end=1;
             break;
             }
             if(pos[i+1][j]==temp && i!=9 && temp!=' ')
             {
             end=1;   
             break;
             }
             if(pos[i][j-1]==temp && j!=0 && temp!=' ')
             {
             end=1;
             break;
             }
             if(pos[i][j+1]==temp && j!=9 && temp!=' ')
             {
             end=1;
             break;
             }
     }
     return end;
}

int checkSpace (char pos[][10])
{
    int largest_space=0,space=0;
    for(int i=9;i>=0;i--)
    {
         for(int j=9;j>=0;j--)
         {
             if(pos[i][j]==' ')
             space++;
         }
         if(largest_space<space)
         largest_space=space;
         space=0;
     }
     return largest_space;
}

void arrangement (char pos[][10],int largest_space)
{
     for(int k=0;k<largest_space;k++)
     for(int i=9;i>=0;i--)
     for(int j=9;j>0;j--)
         if(pos[i][j]==' ')
         {
             pos[i][j]=pos[i][j-1];
             pos[i][j-1]=' ';
         }
}

int check_score (char same[][10])
{
    int score=1;
    for(int i=0;i<10;i++)
    for(int j=0;j<10;j++)
    if(same[i][j]=='s')
    score=score*2;
    if(score!=1)
    return score;
    else
    return 0;
}

int check_skip (char pos[][10],int x,int y)
{
     if(pos[x][y]==' ')
     return 1;
     else
     return 0;
}

Recommended Answers

All 5 Replies

Actually, you've done quite admirably. My score: 1768.

A couple notes though:

  1. main returns int: int main()
  2. Don't use system("pause") and system("cls"). Here are some good replacements:
    void pause()
    {
      cout << "Press ENTER to continue..." << flush;
      cin.clear();  // (assume the user is playing interactively)
      cin.sync();   //
      cin.ignore( numeric_limits<streamsize>::max(), '\n' );
    }
    
    void clearscreen()
    {
      for (int i = 0; i < 100; i++) cout << '\n';
      cout << flush;
    }
  3. Your "a b c d" is off by one space. But I assume this is because you did not use [code] tags to paste your code...
  4. Use complete sentences and avoid 1337/cellphone speak when writing instructions. Also, you did not give instructions on how to enter the position. The other problem is that if the user enters the wrong answer the program crashes.

    You should add a little error checking to validate the user's input, and complain if he enters something wrong. This is a fairly involved subject, so the simplest thing would be simply to wrap everything in a try..catch block and complain if the user enters the wrong thing:

    cout<<"Enter the position: ";
        try {
          if (!(cin>>x_char)) throw 1;
          if (!(cin>>y))      throw 1;
          x=change(x_char); //change char to int
          if (x < 0) throw 1;
          skip=check_skip (pos,x,y); //skip step if pos is ' '
          }
        catch (int) {
          cout << "You must type a letter (A..J) followed by a number (0..9) and then press ENTER.\n";
          pause();
          skip = 1;
          }
  5. To convert the character to a number, use the character directly instead of assuming something about the ASCII set. For example, what if the user enters 'A'?
    int change( char x )
    {
      // Converts x from one of A..J to 0..9, or -1 on error.
    
      // x can be upper or lower case
      x = toupper( x );
    
      // x must be one of 'A'..'J'
      return (x >= 'A' and x <= 'J') ? (x -'A') : -1;
    }

    The other thing is to make sure that your functions actually return a value. The previous change() had only a conditional return statement (in an if inside a for). If x were, say '+', then the return value would be undefined (that is, random). By having an explicit return no matter what happens, the return value is never undefined.

  6. You should document your code better. I haven't actually analyzed it that deeply, so I don't know if there are any logic errors in there or not.

    The reason it looks so complicated is lack of commentary. As for long... well, this is actually a pretty short program... :-)

  7. For boolean values like end and skip, you should make them booleans (I gave 'end' a better name): bool gameover = false; Now you can use it handily: while (!gameover)

I hope this helps and Good job! :)

thx..
i learn so much new command...:)
i will try to fix the infinite loop n the error..

thx..
i learn so much new command...:)
i will try to fix the infinite loop n the error..

but how i use class?
i read some book n they say class is better...

"Better" is a subjective word. If you mean in terms of "easier to use complicated code with fewer errors and improved error handling" then OOP is better.

Objects encapsulate information. That is to say, they don't just define related information, but they provide ways to manipulate that information.

One point of note: classes actually make life just a little bit more complicated for the people writing the class. The reward is that classes make life a breeze for people using the class. The tradeoff, however, is slim, since you'd generally have to write all the stuff that gets put in the class anyway, and when in a class it is much more coherent and easy to read.

The Before Way
For example, a non-object oriented thing is an array:

int xs[] = { 2, 3, 5, 7, 11, 13, 17, 19 };

If you want to print this array you have to know something "magical" about it: its length. The magical thing is that, given the array, there is no way to determine its length.

(Now, before those of you in-the-know respond with length = sizeof( xs ) / sizeof( x[0] ) I'll remind you that that only works because the compiler knows how long xs is. That only works in specific cases... when you are executing the program you cannot depend on the compiler's help.)

Suppose, for example, we have a little function to print that array:

void print_ints( int xs[] ) {
  for (unsigned i = 0; i < ???; i++)
    printf( "%d ", xs[i] );
  }

The problem becomes apparent. Where do we stop printing? We have to tell our function that information:

void print_ints( int xs[], unsigned length ) {
  for (unsigned i = 0; i < length; i++)
    printf( "%d ", xs[i] );
  }

Now, to top it off, what if I want to print my array to both the standard output and a file named "primes.txt"?
I'll have to add a new parameter:

#include <cstdio>

void print_ints( int xs[], unsigned length, FILE *outf ) {
  for (unsigned i = 0; i < length; i++)
    fprintf( outf, "%d ", xs[i] );
  }

Great. Now I can do what I want:

int main() {
  int xs[] = { 2, 3, 5, 7, 11, 13, 17, 19 };

  print_ints( stdout, xs, sizeof( xs ) / sizeof( xs[0] ) );

  FILE *f = fopen( "primes.txt", "w" );
  print_ints( stdout, xs, 8 );
  fclose( f );

  return 0;
  }

Those of you paying attention will have noticed that in one case I used the "sizeof" trick and in the other I just used "8". The reality is that either way the last argument to the function is compiled as the constant value 8. The reason to use the "sizeof" trick is that it lets the compiler worry about the actual length of the array. If I were to add a number to the array (23 is the next prime) the first print_ints() would properly compile with the constant value 9 as the last argument, whereas the second print_ints() would still compile, but it would not print the correct number of integers...

The OOP Way
Enter object oriented programming. Let's try to implement our OOP ideals and collect all the information together the right way.

The first thing we want is an array that knows its own size (rather than having to rely on the compiler or managing to use the right number everywhere it is needed in the code). Fortunately, the STL (Standard Template Library) gives us something that does that for us: a vector.

#include <vector>

int main() {
  // Initialize our array of primes
  const int _xs[] = { 2, 3, 5, 7, 11, 13, 17, 19 };
  std::vector<int> xs( _xs, _xs +(sizeof( _xs ) / sizeof( _xs[0] )) );

  // Tell the user how many primes we have
  cout << "The vector has " << xs.size() << " elements." << endl;

  // Add a new prime
  xs.push_back( 23 );

  // The size of the array has changed!
  cout << "Now it has " << xs.size() << " elements." << endl;

  return 0;
  }

The vector was initialized with a constant array just for ease of use... The thing to note is that the vector knows its own length. If you compile and run that program the output will be

The vector has 8 elements.
Now it has 9 elements.

Amazing!

Um... I'm out of time. More info later if you want...

commented: Good writeup +1

hmmm... finally i know my lvl d...
i think i better read more rather than i ask..
bcoz u juz explain the info tat i totally nvr c b4 haha

anyway thx...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.