/*
* Game: Mine Sweeper
* DHDL Van Lang
* Class: K12T01
* Total size: 12.0 KB
*/
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void menu();//Choose level
void frame(int color);// Playing frame
int exist(int **bomb, int row, int x, int y);//not 2 bombs in 1 cell
void makeBomb(int **&board, int range, int BombQuantity);//Generate bombs
void fillBoard(int **&board, int row, int col);//Fill other cells
void showBoard(int **board);//Show all cells
void showCell(int **board, int row, int col);//Show selected cell
void hideBoard(); //Hide al cells
int openBoard(int **board,int i, int j);
void openMass(int **board,int i, int j);//Open all non-bomb cell
int play(int **&board, char c,int &i,int &j,int &cursorLeft, int &cursorTop);
void death(int **board);//Win or lose
void lockBomb(int **&board,int i,int j);//Set a flag on the bomb
int top=7,left=5,bot,right,lose=0,flag;
int BombNumber, Quantity;//when Quantity goes to 0, you win
void main()
{
int **board,i,j;
char c=0;
menu();
beginning:
clrscr();
lose=0;
Quantity=BombNumber;
//creat dynamic matrix
board
= (int**)calloc((bot
-top
)/2, sizeof(int*)); for(i=0; i<bot-top; i++)
board
[i
]= (int*)calloc((right
-left
), sizeof(int));
//Set value for **board
for(i=0; i<(bot-top)/2; i++)
for(j=0; j<(right-left)/2; j++)
board[i][j]=-10; // -10 : no bomb && closed
frame(WHITE);//Draw WHITE frame
makeBomb(board,(right-left)/2,BombNumber);
/*
(right-left)/2
For example: |_|_|_|
right-left=6, but there are 3 cells
*/
fillBoard(board,(bot-top)/2,(right-left)/2);
hideBoard();
int cursorLeft=left+1, cursorTop=top+1;//Cursor
i=0;
j=0;
gotoxy(cursorLeft,cursorTop);
textbackground(GREEN);
showCell(board,cursorTop-top-1,cursorLeft-left-1);
do
{
flushall();
c=getch();
if(play(board,c,i,j,cursorLeft,cursorTop)==0) goto beginning;
}
while(c!=0xd);//play until button ENTER is pressed
//free the matrix
for(j=0; j<(right-left)/2; j++)
}
void menu()
{
char c;
clrscr();
textcolor(WHITE);
gotoxy(21,8);
cprintf("MINE SWEEPER");
gotoxy(20,10);
cprintf("1. Beginner (Moi tap choi)");
gotoxy(20,12);
cprintf("2. Experienced (Da biet choi)");
gotoxy(20,14);
cprintf("3. Professional (Cao thu)");
gotoxy(20,16);
cprintf("0. Quit ");
gotoxy(20,18);
cprintf("Chon cap do: ");
do
{
c=getch();
}
while(c<'0' || c>'3');
switch(c)
{
case '1': bot=top+16; right=left+16; BombNumber=5; break;
case '2': bot=top+22; right=left+22; BombNumber=20; break;
case '3': bot=top+30; right=left+30; BombNumber=10; break;
case '0': return;
}
}
int play(int **&board, char c,int &i,int &j,int &cursorLeft, int &cursorTop)
{
switch(c)
{
case 0x48://button UP
if(cursorTop>top+1)
{
gotoxy(cursorLeft,cursorTop);
textbackground(BLACK);
showCell(board,i,j);
/* Because the cursor is GREEN
before it leaves a cell, we must
set textbackgound(BLACK)
*/
cursorTop-=2;//set new position of the cursor
i--;
}
break;
case 0x50://button DOWN
if(cursorTop<bot-1)
{
gotoxy(cursorLeft,cursorTop);
textbackground(BLACK);
showCell(board,i,j);
cursorTop+=2;
i++;
}
break;
case 0x4d://button RIGHT
if(cursorLeft<right-1)
{
gotoxy(cursorLeft,cursorTop);
textbackground(BLACK);
showCell(board,i,j);
cursorLeft+=2;
j++;
}
break;
case 0x4b://button LEFT
if(cursorLeft>left+1)
{
gotoxy(cursorLeft,cursorTop);
textbackground(BLACK);
showCell(board,i,j);
cursorLeft-=2;
j--;
}
break;
case 0x3b:/* button F1*/
return 0;
case 0x3e:/*button F4*/
if(openBoard(board,i,j))
{
lose=1;
death(board);
}
break;
case 0x3f:/*button F5*/
lockBomb(board,i,j);break;
case 0x42:/*button F8*/
lose=1; death(board); break;
}
//move the cursor
gotoxy(cursorLeft,cursorTop);
textbackground(GREEN);
showCell(board,i,j);
textbackground(BLACK);
gotoxy(1,1);
return 1;
}
void frame(int color)
{
register int i,j;
//Trade mark
textcolor(color);
gotoxy(5,top-5);
cprintf("Created by Chau Nguyen Thanh Vu~ T06-3546 K12T01");
flag=BombNumber;//Available flags
textcolor(LIGHTCYAN);
gotoxy(left+5,top-3);
cprintf("Flags: %d",flag);
//Draw grid
for(i=0; i<bot-top; i++)
for(j=0; j<right-left-1; j++)
{
gotoxy(left+1+j,top+1+i);
textcolor(LIGHTGRAY);
if(i%2!=0 && j%2!=0)cprintf("%c",197); //draw Å
else if(i%2!=0) cprintf("%c",196);//draw Ä
else if(j%2!=0) cprintf("%c",179);//draw ³
}
textcolor(WHITE);
// Ve ÉÍÍÍÍÍÍÍÍÍ»
gotoxy(left,top);
cprintf("%c",201); // Top left corner É
for(i=left+1; i<right; i++)
{
gotoxy(i,top);
cprintf("%c",205); //Top horizonal line Í
}
cprintf("%c",187); // Top right corner »
//Ve ÈÍÍÍÍÍÍÍÍÍͼ
gotoxy(left,bot); //(10,40)
cprintf("%c",200); // Bottom left corner È
for(i=left+1; i<right; i++)
cprintf("%c",205); // Bottom horizonal line Í
cprintf("%c",188); //Bottom right corner ¼
for(i=top+1; i<bot; i++)
{
gotoxy(left,i);
cprintf("%c",186); // Left vertical line º
}
for(i=top+1; i<bot; i++)
{
gotoxy(right,i);
cprintf("%c",186); // Right vertical line º
}
//Number row
for(i=0,j=1; i<bot-top; i+=2,j++)
{
gotoxy(left-2,top+1+i);
cprintf("%2.d",j);
}
//Alphabet column
for(i=0,j=65; i<right-left; i+=2,j++)
{
gotoxy(left+i,top-1);
cprintf("%2.c",j);
}
//Instructions
textcolor(WHITE);
gotoxy(right+2,top+1); cprintf("F1: New Game (Choi lai)");
gotoxy(right+2,top+3); cprintf("F4: Open cell (Mo o^)");
gotoxy(right+2,top+5); cprintf("F5: Lock bomb (Kho'a bom)");
gotoxy(right+2,top+7); cprintf("F8: Resign (chiu thua)");
gotoxy(right+2,top+10); cprintf("Use ARROW keys to move");
gotoxy(right+2,top+12); cprintf("Press ENTER to QUIT");
}
int exist(int **bomb, int row, int x, int y)
{//check whether 2 bombs in 1 cell
for(int i=0; i<row; i++)
if(bomb[i][0]==x && bomb[i][1]==y) return 1;
return 0;
}
void makeBomb(int **&board, int range, int BombQuantity)
{
int i,j,x,y;
randomize();
//Dynamic matrix
int **bomb;
bomb
=(int**)calloc(BombQuantity
,sizeof(int*)); for(i=0; i<BombQuantity; i++)
bomb
[i
]= (int*)calloc(2,sizeof(int));
for(i=0; i<BombQuantity;i++)
{
do
{
//range from 0 -> (right-left)/2
x= random(range);
y= random(range);
}
while(exist(bomb,BombQuantity,x,y)==1);//2 bomb not 1 place
bomb[i][0]=x;
bomb[i][1]=y;
board[x][y]=-9;// -9 : 1 bomb && closed
}
//Free the matrix
for(j=0; j<2; j++)
}
void fillBoard(int **&board, int row, int col)
{
int count,i,j;
for(i=0; i<row; i++)
for(j=0; j<col; j++)
if(board[i][j]!=-9)
{
count=0;
if(board[i-1][j]==-9) count++;
if(board[i+1][j]==-9) count++;
if(board[i][j-1]==-9) count++;
if(board[i][j+1]==-9) count++;
if(board[i-1][j-1]==-9) count++;
if(board[i-1][j+1]==-9) count++;
if(board[i+1][j-1]==-9) count++;
if(board[i+1][j+1]==-9) count++;
if(count==0) board[i][j]=-10; //-10: no bom && closed
else board[i][j]=-count;// count<0 means: closed
}
}
void showBoard(int **board)
{
for(int hang=0,i=0; i<(bot-top)/2;hang+=2,i++)
for(int cot=0,j=0; j<(right-left)/2;cot+=2,j++)
{
gotoxy(left+1+cot,top+1+hang);
showCell(board,i,j);
}
}
void showCell(int **board, int row, int col)
{
textcolor(LIGHTMAGENTA);
if( (board[row][col]>=10 && lose==0)//lock selected cell
||(board[row][col]==11) )//locked bomb
cprintf("%c",6);
else if(board[row][col]>=10 && board[row][col]!=11 && lose==1)
{ //locked, not bomb
textcolor(LIGHTRED);
cprintf("X");
}
else
{
textcolor(CYAN);
switch(board[row][col])
{
case -9: cprintf("?"); break; //-9: closed bomb
case -10: cprintf("?"); break; //-10: closed nothing
case 0: cprintf(" "); break; // 0: opened nothing
case 9: // 9: opened bomb
textcolor(LIGHTRED);
cprintf("*");
break;
default:
if(board[row][col]>0)
{ // >0 : opened number
textcolor(LIGHTBLUE);
cprintf("%d",board[row][col]);
break;
}
else//if(board[row][col]<0): closed
{
textcolor(CYAN);
cprintf("?");
break;
}
}
}
}
void hideBoard()
{
for(int i=top+1; i<bot; i+=2)
for(int j=left+1; j<right; j+=2)
{
gotoxy(j,i);
textcolor(CYAN);
cprintf("?");
}
}
int openBoard(int **board,int i, int j)
{
int flag=0;
if(board[i][j]==-9) return 1;//Open bomb, die!!
else if(board[i][j]==-10)
{
openMass(board,i,j);//open all non-bomb cell
flag=1;
}
else if(board[i][j]<0) board[i][j]=-board[i][j];
if(flag==1) showBoard(board);
return 0;
}
void openMass(int **board,int i, int j)
{
if(board[i][j]==-10)// -10: non-bomb && closed
board[i][j]=0;// 0: non-bomb && opened
if(board[i-1][j]==-10) openMass(board,i-1,j);
if(board[i+1][j]==-10) openMass(board,i+1,j);
if(board[i][j-1]==-10) openMass(board,i,j-1);
if(board[i][j+1]==-10) openMass(board,i,j+1);
if(board[i-1][j]<0)/*If a numbered cell is next to
a non-bomb cell, open that numbered cell */
board[i-1][j]=-board[i-1][j];
if(board[i+1][j]<0)
board[i+1][j]=-board[i+1][j];
if(board[i][j-1]<0)
board[i][j-1]=-board[i][j-1];
if(board[i][j+1]<0)
board[i][j+1]=-board[i][j+1];
return;
}
void death(int **board)
{
int hang,cot,i,j;
for(i=0; i<(bot-top)/2;i++)
for(j=0; j<(right-left)/2; j++)
{
if(board[i][j]==-10) board[i][j]=0;//opend all non-bomb cells
if(board[i][j]<0) board[i][j]=-board[i][j];
//opened all numbered cells
//becase <0 : closed
// >0 : opened
}
showBoard(board);
if(lose==1)// LOSE mode
{
gotoxy(left+16,top-3);
textcolor(YELLOW);
cprintf("BAN DA THUA ! NHAN F1 DE CHOI LAI.");
}
else// WIN mode
{
gotoxy(left+16,top-3);
textcolor(YELLOW);
cprintf("CHUC MUNG! BAN DA CHIEN THANG!");
}
gotoxy(right+2, top+15);
textcolor(LIGHTRED);
cprintf("X");
textcolor(WHITE);
cprintf(": not a bomb (khong phai bom)");
gotoxy(right+2, top+17);
textcolor(LIGHTRED);
cprintf("*");
textcolor(WHITE);
cprintf(": a bomb (day la bom)");
gotoxy(right+2, top+19);
textcolor(LIGHTMAGENTA);
cprintf("%c",6);
textcolor(WHITE);
cprintf(": locked bomb (bom bi kho'a)");
}
void lockBomb(int **&board,int i,int j)//locked or unlock selected cell
{
if(board[i][j]<0 && flag>0)//only lock <0 cell (closed cell)
{
if(board[i][j]==-9) Quantity--; //if a bomb is locked
/*Quantity of bomb is not shown
it is the remaining bombs to defuse
when it goes to 0, you win.*/
/* (1)*/ board[i][j]+=20;/*for example: board[i][j]=-1 -> board[i][j]=19
19>0 : so it won't be opened by showCell()
because showCell() only opens <0 cell*/
flag--;
textcolor(WHITE);
gotoxy(left+12,top-3);
cprintf("%2.1d",flag);
if(Quantity==0)
{
lose=0;// you win
death(board);//show all cells in WIN mode
}
}
else if(board[i][j]>=10 && lose==0)
{
/* (2)*/ board[i][j]-=20;
/* In (1), board[i][j]=-1 -> board[i][j]=19;
In (2), board[i][j]=19 -> board[i][j]=-1;
=> when the flag is removed,
board[i][j] returns to the previous value
*/
if(board[i][j]==-9) Quantity++;//if a bomb is unlocked
flag++;
textcolor(WHITE);
gotoxy(left+12,top-3);
cprintf("%2.1d",flag);
}
}