# mine sweeper help..

• 01-04-2009
transgalactic2
mine sweeper help..
i have all the parts.

i have a function wich for a given coordinate puts in it how many
mines around it,or if this coordinate is a mine than it puts X on it

but there is a problem.
i need to do some question mark board
for example
? ?
? ?

and i place the mine in one of the cells
and then i need to put a coordinate x,y
1,2
and it should print
? 1
? ?

2,2
and it should print
? 1
? 1

2,1
and it should print
* 1
1 1

i done a similar thing it reveals the squares
but it doesnt show the last
* 1
1 1

i marked the start of this option by "option 5 code" comment

??

Code:

```#include <stdio.h> #define N 9 int checkEndOfGame(char board[N][N],int size); int same_digit(char ch_cords[40],int k); int is_valid(const char input[40],int leng); void mainPlayGame(char board[N][N]); int playGame(char board[N][N],int size); void printBoard(char board[N][N],int size); int removeMine(char board[N][N],int size,int x,int y); void mainMenu(); int unCover(char board[N][N],int size,int x,int y); int main() {     char board[N][N];     mainPlayGame(board);     printf("bye, please press enter to exit!\n");     getchar();     return 0; } void mainPlayGame(char board[N][N]) {         int x_cord,y_cord,kent,end=0,wins=0,loses=0;         char qboard[N][N];     char input[40];     char input2[40];     int flag=0,flag2=0,flag3=0;     int opt,leng,size=-1;     int index,kndex,temp;     char ch_cords[40];     int tr;     int cords[8][2];     int tndex,result;     int i,k,j,ch,l,x_rem,y_rem;     int  leng2;                 for(index=0;index<N;index++)             {                 for(kndex=0;kndex<N;kndex++)                 {                     board[index][kndex]=' ';                 }             }             for(index=0;index<N;index++)             {                 for(kndex=0;kndex<N;kndex++)                 {                     qboard[index][kndex]='?';                 }             }     do     {///         mainMenu();         scanf("%d",&opt);         l=getchar();         if (opt==1)         {             printf("enter board size [1..9] (no input control is needed):\n");             scanf("%d",&size);         }         if (opt==2)         {             flag2=0;             if (size==-1)             {                 printf("you must choose board size first!\n");             }         else         {             printf("enter x,y of the new mines (x1,y1)(x2,y2)...(xn,yn)\n");             for (i = 0; i < 39 && (ch = getchar()) != '\n' && ch != EOF; ++i)             {                 input2[i] = ch;             }             input2[i] = '\0';             k=0;           for(index=0;index<=i;index++)           {               if(input2[index]!=' ')               {                   input[k]=input2[index];                   k++;               }           }           leng=k;//same digit input check           if (is_valid(input,leng))           {                           for(index=0;index<leng;index++)               {                 if (((input[index])>='0')&&((input[index])<='9')&&((input[index+1])>='0')&&((input[index+1])<='9'))                   {                           flag2=1;                   }                           }               k=0;           if (flag2!=1){           for(index=0;index<leng;index++)           {               if((input[index]!='(')&&(input[index]!=',')&&(input[index]!=')'))               {                   ch_cords[k]=input[index];                   k++;               }           }                   k--;           tndex=0;           for(index=0;index<=leng;index++)           {               if((input[index]==')'))               {                   tndex++;               }           }             j=0;             for(index=0;index<tndex;index++)             {                 for(kndex=0;kndex<2;kndex++)                 {                     tr=ch_cords[j]-'0';                     cords[index][kndex]=tr;                     j++;                 }             }             result=same_digit(ch_cords,tndex); //i call the function here                         if (result==0)                         {               for(index=0;index<tndex;index++)               {                                                 x_cord=cords[index][0];                                                 y_cord=cords[index][1];                 if((x_cord>size)||(y_cord>size)||(y_cord<0)||(x_cord<0))                 {                 //out of bound                 printf("(%d,%d) is out of range\n",x_cord,y_cord);                 }                 else                 {  //excepted                   board[y_cord-1][x_cord-1]='*';                   printf("(%d,%d) mine inserted\n",x_cord,y_cord);                 }               }                         }           }           else           {             printf("wrong input\n");           }       }       else       {           printf("wrong input\n");       }       }     }//end if opt 2///     if (opt==3)     {         if (size==-1)             {                 printf("you must choose board size first!\n");             }         else         {             printf("enter x,y of the  mine to remove (no input control is needed):\n");             for (i = 0; i < 39 && (ch = getchar()) != '\n' && ch != EOF; ++i)             {                 input2[i] = ch;             }             input2[i] = '\0';                   ch_cords[0]=input2[0];                   ch_cords[2]=input2[2];                   x_rem=ch_cords[0]-'0';                   y_rem=ch_cords[2]-'0';                   if (board[y_rem-1][x_rem-1]!='*')                   {                       printf("wrong input or no mine\n");                   }                   else                   {                       printf("mine removed\n");                   }         }     }     if (opt==4)     {         if (size==-1)             {                 printf("you must choose board size first!\n");             }         else         {       printBoard(board,size);         }     }     if (opt==5)//option5 code     {           if (size==-1)             {                 printf("you must choose board size first!\n");             }         else         {         do         {             printf("enter a square x,y to uncover : (no input control is needed):\n");             for (i = 0; i < 39 && (ch = getchar()) != '\n' && ch != EOF; ++i)             {                 input2[i] = ch;             }             input2[i] = '\0';             x_rem=input2[0]-'0';             y_rem=input2[2]-'0';             kent=unCover(board,size,x_rem,y_rem);             if (kent==0)                     {               end=1;               loses++;               printBoard(board,size);             }         else                 {               for (index=0;index<size;index++)                           {                   for (kndex=0;kndex<size;kndex++)                                   {                     if  ((board[index][kndex]!=' ')&&(board[index][kndex]!='*'))                                         {                           qboard[index][kndex]=board[index][kndex];                       }                     }                   }         }         printBoard(qboard,size);           flag=checkEndOfGame(qboard,size);           printf("flag=%d\n",flag);           if (flag==1){           end=1;               wins++;             printBoard(qboard,size);           }         }while(end!=1);         }     }     if (opt==0)     {     }     }while(opt!=0); } int same_digit(char ch_cords[40],int k) {     int index;     char ch;     ch=ch_cords[0];     for (index=0;index<=k;index++)     {       if (ch_cords[index]!=ch)           {                   return 0;           }     }     if(k>2)     {           return 1;     }     else     {     return 0;     } }//end same digit void mainMenu() {     printf("--------------------------\n");     printf("welcome to the game\n");     printf("1. choose board size\n");     printf("2. place mines\n");     printf("3. remove mines\n");     printf("4. show mines\n");     printf("5. start the game\n");     printf("0. exit\n");     printf("please enter your choice (input control is needed): \n"); } void printBoard(char board[N][N],int size) {     int index,kndex;     for(index=0;index<size;index++)     {                 printf("+");       for(kndex=0;kndex<size;kndex++)       {           printf("-+");       }       printf("\n");           printf("|");       for(kndex=0;kndex<size;kndex++)       {           printf("%c|",board[index][kndex]);       }       printf("\n");  }         printf("+");   for(kndex=0;kndex<size;kndex++)   {         printf("-+");   }   printf("\n"); } int removeMine(char board[N][N],int size,int x,int y) {     if (board[y-1][x-1]=='*')     {         board[y-1][x-1]=' ';         printf("mine removed");         return 1;     }     else     {         printf("wrong input or no mine");         return 0;     } } int unCover(char board[N][N],int size,int x,int y){  int count=0;   if (board[y-1][x-1]=='*'){   printf("you lost\n");   board[y-1][x-1]='X';   return 0;   }  else  {       if (((y-2)>=0) && ((x-2)>=0) && (board[y-2][x-2]=='*')){       count++;       }         if (((y-2)>=0) && ((x-1)>=0) && (board[y-2][x-1]=='*')){       count++;       }         if (((y-2)>=0) && ((x)<size) && (board[y-2][x]=='*')){       count++;       }       if (((y)<size) && ((x-2)>=0) && (board[y][x-2]=='*')){       count++;       }         if (((y)<size) && ((x-1)>=0) && (board[y][x-1]=='*')){       count++;       }         if (((y)<size) && ((x)<size) && (board[y][x]=='*')){       count++;       }       if (((y-1)>=0) && ((x-2)>=0) && (board[y-1][x-2]=='*')){       count++;       }       if (((y-1)>=0) && ((x)<size) && (board[y-1][x]=='*')){       count++;       }       board[y-1][x-1]='0' +count;   return 1;  } } int is_valid(const char input[40],int leng) {         int flag=3;         int i=1;     int index;     for(index=0;index<leng;index++)     {         if((input[index]!='(')&&(input[index]!=',')&&(input[index]!=')'))         {             if (((input[1])<'0')||((input[1])>'9'))             {                         return 0;                 }         }     }     if (input[0] != '(')     {         flag=(int)NULL;     }     if (((input[1])<'0')||((input[1])>'9'))     {             flag=(int)NULL;     }     i++;     while((input[i]<='9')&&(input[i]>='0'))     {         i++; //increasing the  address by1     } //it wiil get char '2'     if (input[i] == ',')     {  //'2' differs ','         if (((input[i+1])<'0')||((input[i+1])>'9'))         {                   flag=(int)NULL;             }         i++;         while((input[i]<='9')&&(input[i]>='0'))         {             input++; //increasing the  address by1         }         if (input[i]==')')         {             i++;         }         else           flag=(int)NULL;         }   else   {       flag=(int)NULL;   }   if (flag ==(int)NULL)   {       return 0;   }     while (input[i]!= '\0')     {         if (input[i] != '(')         {             flag=(int)NULL;         }             if (((input[i+1])<'0')||((input[i+1])>'9'))             {                   flag=(int)NULL;             }                 i++;         while((input[i]<='9')&&(input[i]>='0'))         {             i++; //increasing the  address by1         } //it wiil get char '2'         if (input[i] == ',')         {  //'2' differs ','             if (((input[i+1])<'0')||((input[i+1])>'9'))             {                         flag=(int)NULL;                 }             i++;             while((input[i]<='9')&&(input[i]>='0'))             {                 i++; //increasing the  address by1             }             if (input[i]==')')             {                 i++;             }             else             flag=(int)NULL;             }   else   {       flag=(int)NULL;   }   if (flag ==(int)NULL)         {             return 0;         }     }     return 1; } int checkEndOfGame(char board[N][N],int size) {   int index,kndex;   for (index=0;index<size;index++)   {       for (kndex=0;kndex<size;kndex++)           {           if  (board[index][kndex]=='?')                   {       return 0;           }       }  }  return 1; }```
• 01-04-2009
tabstop
So what does it show instead?
• 01-04-2009
transgalactic2
it doesnt stop
it shows

?1
11

and nothing happens

??
• 01-04-2009
tabstop
Well, and why not? According to your "checkEndOfGame", the game isn't over yet. Why do you think the game should be over?
• 01-04-2009
transgalactic2
I am asked to end the game when i open every cell which is not a mine

i cant have
?1
11
the victory picture is
showing the mines
*1
11
• 01-04-2009
matsp
Can I just make a few suggestions that would improve your code:
Code:

```            for (i = 0; i < 39 && (ch = getchar()) != '\n' && ch != EOF; ++i)             {                 input2[i] = ch;             }```
is repeated twice: Make it a function. (To make it generic, pass a parameter for the size, so you can enter longer and shorter strings too).

Code:

```            flag2=0;             if (size==-1)             {                 printf("you must choose board size first!\n");             }         else         {             printf("enter x,y of the new mines (x1,y1)(x2,y2)...(xn,yn)\n");             for (i = 0; i < 39 && (ch = getchar()) != '\n' && ch != EOF; ++i)             {                 input2[i] = ch;             }             input2[i] = '\0';             k=0;           for(index=0;index<=i;index++)           {               if(input2[index]!=' ')               {                   input[k]=input2[index];                   k++;               }           }           leng=k;//same digit input check           if (is_valid(input,leng))           {                           for(index=0;index<leng;index++)               {                 if (((input[index])>='0')&&((input[index])<='9')&&((input[index+1])>='0')&&((input[index+1])<='9'))                   {                           flag2=1;                   }                           }               k=0;           if (flag2!=1){           for(index=0;index<leng;index++)           {               if((input[index]!='(')&&(input[index]!=',')&&(input[index]!=')'))               {                   ch_cords[k]=input[index];                   k++;               }           }                   k--;           tndex=0;           for(index=0;index<=leng;index++)           {               if((input[index]==')'))               {                   tndex++;               }           }             j=0;             for(index=0;index<tndex;index++)             {                 for(kndex=0;kndex<2;kndex++)                 {                     tr=ch_cords[j]-'0';                     cords[index][kndex]=tr;                     j++;                 }             }             result=same_digit(ch_cords,tndex); //i call the function here                         if (result==0)                         {               for(index=0;index<tndex;index++)               {                                                 x_cord=cords[index][0];                                                 y_cord=cords[index][1];                 if((x_cord>size)||(y_cord>size)||(y_cord<0)||(x_cord<0))                 {                 //out of bound                 printf("(%d,%d) is out of range\n",x_cord,y_cord);                 }                 else                 {  //excepted                   board[y_cord-1][x_cord-1]='*';                   printf("(%d,%d) mine inserted\n",x_cord,y_cord);                 }               }                         }           }           else           {             printf("wrong input\n");           }       }       else       {           printf("wrong input\n");       }       }```
This is all inside "if (opt == 2)..." - it's far too much code inside a single if-statement. Make it a separate function.

Code:

```            if (size==-1)             {                 printf("you must choose board size first!\n");             }```
This is done on EVERY option except option 1. So why not break it out, and move it up with, something like "if (opt != 1 && size == -1) ... ". You should try to never have the same piece of code repeated several times. It's a maintenance nightmare (because when you come to change the "you must choose board size first" into a different message, you have to change it several times, or you find that -1 is a bad value to indicate "not yet set", etc).

Code:

```        printBoard(qboard,size);           flag=checkEndOfGame(qboard,size);           printf("flag=%d\n",flag);           if (flag==1){           end=1;               wins++;             printBoard(qboard,size);           }```
Does printBoard do something different after checkEndOfGame? [No, I can't be bothered to check - but if it does, it may make good sense to write a small comment as to why].

Code:

`            kent=unCover(board,size,x_rem,y_rem);`
Is "kent" of any meaning here, or is it just that you didn't know what else to use, so you used the last name of SuperMan?

Your code is too hard to follow, and I can't be bothered to fire up a debugger to try to figure out what is wrong with it.

If you tidy up the code as suggested, it will be easier to follow, and I may be able to figure out what is wrong. I hold little hope that you will do so, since last time I wrote a long post with suggestions to improve, you apparently didn't bother. I don't write these things because I want to post more posts - I write it because I think it will teach you how to write better code - and by writing better code you will:
1. Achieve more on your own.
2. Have problems that are easier to understand so others are more able to help you.

--
Mats
• 01-04-2009
tabstop
Quote:

Originally Posted by transgalactic2
I am asked to end the game when i open every cell which is not a mine

i cant have
?1
11
the victory picture is
showing the mines
*1
11

And did you expect that to happen by magic, for some reason? Write (another) function that checks if all and every un-stepped-on place is a mine, and if so, then you win.
• 01-04-2009
One easy way to do this is to just subtract the number of mines, from the number of squares, in total.

If the player's move number equals that number, then the player wins.

Something like:
Code:

```/* Relies on each move being checked first whether it's a mine or not. If it's a mine, then the game is over, and this function should NOT be called, as is. */ int IsWin  (int total_squares, int mine_number, int move_number)  {     if(total_squares = move_number + mine_number)       //player wins       return 1;   else       //game not over       return 0; }```
• 01-04-2009
iMalc
Quote:

Originally Posted by transgalactic2
I am asked to end the game when i open every cell which is not a mine

i cant have
?1
11
the victory picture is
showing the mines
*1
11

Yes but surely "opening a cell" means entering its coordinates. Until you've done that, I think it is correct to stay as a question mark.

What's the point of removeMine if you duplicated the code and dont call it?

How exactly is one supposed to lose this game? I mean if you select to "remove mine" for any cell and it wasn't a mine, IT TELLS YOU!!! (cheat)
Have you not played this game before?