C++扫雷源代码

C++扫雷源代码,第1张

这是字符界面的扫雷:

#include <iostream>

#include <cstdlib>

#include <ctime>

#include <windowsh>

#include <conioh>

// defines

#define KEY_UP 0xE048

#define KEY_DOWN 0xE050

#define KEY_LEFT 0xE04B

#define KEY_RIGHT 0xE04D

#define KEY_ESC 0x001B

#define KEY_1 '1'

#define KEY_2 '2'

#define KEY_3 '3'

#define GAME_MAX_WIDTH 100

#define GAME_MAX_HEIGHT 100

// Strings Resource

#define STR_GAMETITLE "ArrowKey:MoveCursor Key1:Open \

Key2:Mark Key3:OpenNeighbors"

#define STR_GAMEWIN "Congratulations! You Win! Thank you for playing!\n"

#define STR_GAMEOVER "Game Over, thank you for playing!\n"

#define STR_GAMEEND "Presented by yzfy Press ESC to exit\n"

//-------------------------------------------------------------

// Base class

class CConsoleWnd

{

public:

static int TextOut(const char);

static int GotoXY(int, int);

static int CharOut(int, int, const int);

static int TextOut(int, int, const char);

static int GetKey();

public:

};

//{{// class CConsoleWnd

//

// int CConsoleWnd::GetKey()

// Wait for standard input and return the KeyCode

//

int CConsoleWnd::GetKey()

{

int nkey=getch(),nk=0;

if(nkey>=128||nkey==0)nk=getch();

return nk>0nkey256+nk:nkey;

}

//

// int CConsoleWnd::GotoXY(int x, int y)

// Move cursor to (x,y)

// Only Console Application

//

int CConsoleWnd::GotoXY(int x, int y)

{

COORD cd;

cdX = x;cdY = y;

return SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),cd);

}

//

// int CConsoleWnd::TextOut(const char pstr)

// Output a string at current position

//

int CConsoleWnd::TextOut(const char pstr)

{

for(;pstr;++pstr)putchar(pstr);

return 0;

}

//

// int CConsoleWnd::CharOut(int x, int y, const int pstr)

// Output a char at (x,y)

//

int CConsoleWnd::CharOut(int x, int y, const int pstr)

{

GotoXY(x, y);

return putchar(pstr);

}

//

// int CConsoleWnd::TextOut(const char pstr)

// Output a string at (x,y)

//

int CConsoleWnd::TextOut(int x, int y, const char pstr)

{

GotoXY(x, y);

return TextOut(pstr);

}

//}}

//-------------------------------------------------------------

//Application class

class CSLGame:public CConsoleWnd

{

private:

private:

int curX,curY;

int poolWidth,poolHeight;

int bm_gamepool[GAME_MAX_HEIGHT+2][GAME_MAX_WIDTH+2];

public:

CSLGame():curX(0),curY(0){poolWidth=poolHeight=0;}

int InitPool(int, int, int);

int MoveCursor(){return CConsoleWnd::GotoXY(curX, curY);}

int DrawPool(int);

int WaitMessage();

int GetShowNum(int, int);

int TryOpen(int, int);

private:

int DFSShowNum(int, int);

private:

const static int GMARK_BOOM;

const static int GMARK_EMPTY;

const static int GMARK_MARK;

};

const int CSLGame::GMARK_BOOM = 0x10;

const int CSLGame::GMARK_EMPTY= 0x100;

const int CSLGame::GMARK_MARK = 0x200;

//{{// class CSLGame:public CConsoleWnd

//

// int CSLGame::InitPool(int Width, int Height, int nBoom)

// Initialize the game pool

// If WidthHeight <= nBoom, or nBoom<=0,

// or Width and Height exceed limit , then return 1

// otherwise return 0

//

int CSLGame::InitPool(int Width, int Height, int nBoom)

{

poolWidth = Width; poolHeight = Height;

if(nBoom<=0 || nBoom>=WidthHeight

|| Width <=0 || Width >GAME_MAX_WIDTH

|| Height<=0 || Height>GAME_MAX_HEIGHT

){

return 1;

}

// zero memory

for(int y=0; y<=Height+1; ++y)

{

for(int x=0; x<=Width+1; ++x)

{

bm_gamepool[y][x]=0;

}

}

// init seed

srand(time(NULL));

// init Booms

while(nBoom)

{

int x = rand()%Width + 1, y = rand()%Height + 1;

if(bm_gamepool[y][x]==0)

{

bm_gamepool[y][x] = GMARK_BOOM;

--nBoom;

}

}

// init cursor position

curX = curY = 1;

MoveCursor();

return 0;

}

//

// int CSLGame::DrawPool(int bDrawBoom = 0)

// Draw game pool to Console window

//

int CSLGame::DrawPool(int bDrawBoom = 0)

{

for(int y=1;y<=poolHeight;++y)

{

CConsoleWnd::GotoXY(1, y);

for(int x=1;x<=poolWidth;++x)

{

if(bm_gamepool[y][x]==0)

{

putchar('');

}

else if(bm_gamepool[y][x]==GMARK_EMPTY)

{

putchar(' ');

}

else if(bm_gamepool[y][x]>0 && bm_gamepool[y][x]<=8)

{

putchar('0'+bm_gamepool[y][x]);

}

else if(bDrawBoom==0 && (bm_gamepool[y][x] & GMARK_MARK))

{

putchar('#');

}

else if(bm_gamepool[y][x] & GMARK_BOOM)

{

if(bDrawBoom)

putchar('');

else

putchar('');

}

}

}

return 0;

}

//

// int CSLGame::GetShowNum(int x, int y)

// return ShowNum at (x, y)

//

int CSLGame::GetShowNum(int x, int y)

{

int nCount = 0;

for(int Y=-1;Y<=1;++Y)

for(int X=-1;X<=1;++X)

{

if(bm_gamepool[y+Y][x+X] & GMARK_BOOM)++nCount;

}

return nCount;

}

//

// int CSLGame::TryOpen(int x, int y)

// Try open (x, y) and show the number

// If there is a boom, then return EOF

//

int CSLGame::TryOpen(int x, int y)

{

int nRT = 0;

if(bm_gamepool[y][x] & GMARK_BOOM)

{

nRT = EOF;

}

else

{

int nCount = GetShowNum(x,y);

if(nCount==0)

{

DFSShowNum(x, y);

}

else bm_gamepool[y][x] = nCount;

}

return nRT;

}

//

// int CSLGame::DFSShowNum(int x, int y)

// Private function, no comment

//

int CSLGame::DFSShowNum(int x, int y)

{

if((0<x && x<=poolWidth) &&

(0<y && y<=poolHeight) &&

(bm_gamepool[y][x]==0))

{

int nCount = GetShowNum(x, y);

if(nCount==0)

{

bm_gamepool[y][x] = GMARK_EMPTY;

for(int Y=-1;Y<=1;++Y)

for(int X=-1;X<=1;++X)

{

DFSShowNum(x+X,y+Y);

}

}

else bm_gamepool[y][x] = nCount;

}

return 0;

}

//

// int CSLGame::WaitMessage()

// Game loop, wait and process an input message

// return: 0: not end; 1: Win; otherwise: Lose

//

int CSLGame::WaitMessage()

{

int nKey = CConsoleWnd::GetKey();

int nRT = 0, nArrow = 0;

switch (nKey)

{

case KEY_UP:

{

if(curY>1)--curY;

nArrow=1;

}break;

case KEY_DOWN:

{

if(curY<poolHeight)++curY;

nArrow=1;

}break;

case KEY_LEFT:

{

if(curX>1)--curX;

nArrow=1;

}break;

case KEY_RIGHT:

{

if(curX<poolWidth)++curX;

nArrow=1;

}break;

case KEY_1:

{

nRT = TryOpen(curX, curY);

}break;

case KEY_2:

{

if((bm_gamepool[curY][curX]

& ~(GMARK_MARK|GMARK_BOOM))==0)

{

bm_gamepool[curY][curX] ^= GMARK_MARK;

}

}break;

case KEY_3:

{

if(bm_gamepool[curY][curX] & 0xF)

{

int nb = bm_gamepool[curY][curX] & 0xF;

for(int y=-1;y<=1;++y)

for(int x=-1;x<=1;++x)

{

if(bm_gamepool[curY+y][curX+x] & GMARK_MARK)

--nb;

}

if(nb==0)

{

for(int y=-1;y<=1;++y)

for(int x=-1;x<=1;++x)

{

if((bm_gamepool[curY+y][curX+x]

& (0xF|GMARK_MARK)) == 0)

{

nRT |= TryOpen(curX+x, curY+y);

}

}

}

}

}break;

case KEY_ESC:

{

nRT = EOF;

}break;

}

if(nKey == KEY_1 || nKey == KEY_3)

{

int y=1;

for(;y<=poolHeight;++y)

{

int x=1;

for(;x<=poolWidth; ++x)

{

if(bm_gamepool[y][x]==0)break;

}

if(x<=poolWidth) break;

}

if(! (y<=poolHeight))

{

nRT = 1;

}

}

if(nArrow==0)

{

DrawPool();

}

MoveCursor();

return nRT;

}

//}}

//-------------------------------------------------------------

//{{

//

// main function

//

int main(void)

{

int x=50, y=20, b=100,n; // define width & height & n_booms

CSLGame slGame;

// Init Game

{

CConsoleWnd::GotoXY(0,0);

CConsoleWnd::TextOut(STR_GAMETITLE);

slGameInitPool(x,y,b);

slGameDrawPool();

slGameMoveCursor();

}

while((n=slGameWaitMessage())==0) // Game Message Loop

;

// End of the Game

{

slGameDrawPool(1);

CConsoleWnd::TextOut("\n");

if(n==1)

{

CConsoleWnd::TextOut(STR_GAMEWIN);

}

else

{

CConsoleWnd::TextOut(STR_GAMEOVER);

}

CConsoleWnd::TextOut(STR_GAMEEND);

}

while(CConsoleWnd::GetKey()!=KEY_ESC)

;

return 0;

}

//}}

用TC自己玩一下吧

/534 源程序/

#include <graphicsh>

#include <stdlibh>

#include <dosh>

#define LEFTPRESS 0xff01

#define LEFTCLICK 0xff10

#define LEFTDRAG 0xff19

#define MOUSEMOVE 0xff08

struct

{

int num;/格子当前处于什么状态,1有雷,0已经显示过数字或者空白格子/

int roundnum;/统计格子周围有多少雷/

int flag;/右键按下显示红旗的标志,0没有红旗标志,1有红旗标志/

}Mine[10][10];

int gameAGAIN=0;/是否重来的变量/

int gamePLAY=0;/是否是第一次玩游戏的标志/

int mineNUM;/统计处理过的格子数/

char randmineNUM[3];/显示数字的字符串/

int Keystate;

int MouseExist;

int MouseButton;

int MouseX;

int MouseY;

void Init(void);/图形驱动/

void MouseOn(void);/鼠标光标显示/

void MouseOff(void);/鼠标光标隐藏/

void MouseSetXY(int,int);/设置当前位置/

int LeftPress(void);/左键按下/

int RightPress(void);/鼠标右键按下/

void MouseGetXY(void);/得到当前位置/

void Control(void);/游戏开始,重新,关闭/

void GameBegain(void);/游戏开始画面/

void DrawSmile(void);/画笑脸/

void DrawRedflag(int,int);/显示红旗/

void DrawEmpty(int,int,int,int);/两种空格子的显示/

void GameOver(void);/游戏结束/

void GameWin(void);/显示胜利/

int MineStatistics(int,int);/统计每个格子周围的雷数/

int ShowWhite(int,int);/显示无雷区的空白部分/

void GamePlay(void);/游戏过程/

void Close(void);/图形关闭/

void main(void)

{

Init();

Control();

Close();

}

void Init(void)/图形开始/

{

int gd=DETECT,gm;

initgraph(&gd,&gm,"c:\\tc");

}

void Close(void)/图形关闭/

{

closegraph();

}

void MouseOn(void)/鼠标光标显示/

{

_AX=0x01;

geninterrupt(0x33);

}

void MouseOff(void)/鼠标光标隐藏/

{

_AX=0x02;

geninterrupt(0x33);

}

void MouseSetXY(int x,int y)/设置当前位置/

{

_CX=x;

_DX=y;

_AX=0x04;

geninterrupt(0x33);

}

int LeftPress(void)/鼠标左键按下/

{

_AX=0x03;

geninterrupt(0x33);

return(_BX&1);

}

int RightPress(void)/鼠标右键按下/

{

_AX=0x03;

geninterrupt(0x33);

return(_BX&2);

}

void MouseGetXY(void)/得到当前位置/

{

_AX=0x03;

geninterrupt(0x33);

MouseX=_CX;

MouseY=_DX;

}

void Control(void)/游戏开始,重新,关闭/

{

int gameFLAG=1;/游戏失败后判断是否重新开始的标志/

while(1)

{

if(gameFLAG)/游戏失败后没判断出重新开始或者退出游戏的话就继续判断/

{

GameBegain(); /游戏初始画面/

GamePlay();/具体游戏/

if(gameAGAIN==1)/游戏中重新开始/

{

gameAGAIN=0;

continue;

}

}

MouseOn();

gameFLAG=0;

if(LeftPress())/判断是否重新开始/

{

MouseGetXY();

if(MouseX>280&&MouseX<300&&MouseY>65&&MouseY<85)

{

gameFLAG=1;

continue;

}

}

if(kbhit())/判断是否按键退出/

break;

}

MouseOff();

}

void DrawSmile(void)/画笑脸/

{

setfillstyle(SOLID_FILL,YELLOW);

fillellipse(290,75,10,10);

setcolor(YELLOW);

setfillstyle(SOLID_FILL,BLACK);/眼睛/

fillellipse(285,75,2,2);

fillellipse(295,75,2,2);

setcolor(BLACK);/嘴巴/

bar(287,80,293,81);

}

void DrawRedflag(int i,int j)/显示红旗/

{

setcolor(7);

setfillstyle(SOLID_FILL,RED);

bar(198+j20,95+i20,198+j20+5,95+i20+5);

setcolor(BLACK);

line(198+j20,95+i20,198+j20,95+i20+10);

}

void DrawEmpty(int i,int j,int mode,int color)/两种空格子的显示/

{

setcolor(color);

setfillstyle(SOLID_FILL,color);

if(mode==0)/没有单击过的大格子/

bar(200+j20-8,100+i20-8,200+j20+8,100+i20+8);

else

if(mode==1)/单击过后显示空白的小格子/

bar(200+j20-7,100+i20-7,200+j20+7,100+i20+7);

}

void GameBegain(void)/游戏开始画面/

{

int i,j;

cleardevice();

if(gamePLAY!=1)

{

MouseSetXY(290,70); /鼠标一开始的位置,并作为它的初始坐标/

MouseX=290;

MouseY=70;

}

gamePLAY=1;/下次按重新开始的话鼠标不重新初始化/

mineNUM=0;

setfillstyle(SOLID_FILL,7);

bar(190,60,390,290);

for(i=0;i<10;i++)/画格子/

for(j=0;j<10;j++)

DrawEmpty(i,j,0,8);

setcolor(7);

DrawSmile();/画脸/

randomize();

for(i=0;i<10;i++)/100个格子随机赋值有没有地雷/

for(j=0;j<10;j++)

{

Mine[i][j]num=random(8);/如果随机数的结果是1表示这个格子有地雷/

if(Mine[i][j]num==1)

mineNUM++;/现有雷数加1/

else

Mine[i][j]num=2;

Mine[i][j]flag=0;/表示没红旗标志/

}

sprintf(randmineNUM,"%d",mineNUM); /显示这次总共有多少雷数/

setcolor(1);

settextstyle(0,0,2);

outtextxy(210,70,randmineNUM);

mineNUM=100-mineNUM;/变量取空白格数量/

MouseOn();

}

void GameOver(void)/游戏结束画面/

{

int i,j;

setcolor(0);

for(i=0;i<10;i++)

for(j=0;j<10;j++)

if(Mine[i][j]num==1)/显示所有的地雷/

{

DrawEmpty(i,j,0,RED);

setfillstyle(SOLID_FILL,BLACK);

fillellipse(200+j20,100+i20,7,7);

}

}

void GameWin(void)/显示胜利/

{

setcolor(11);

settextstyle(0,0,2);

outtextxy(230,30,"YOU WIN!");

}

int MineStatistics(int i,int j)/统计每个格子周围的雷数/

{

int nNUM=0;

if(i==0&&j==0)/左上角格子的统计/

{

if(Mine[0][1]num==1)

nNUM++;

if(Mine[1][0]num==1)

nNUM++;

if(Mine[1][1]num==1)

nNUM++;

}

else

if(i==0&&j==9)/右上角格子的统计/

{

if(Mine[0][8]num==1)

nNUM++;

if(Mine[1][9]num==1)

nNUM++;

if(Mine[1][8]num==1)

nNUM++;

}

else

if(i==9&&j==0)/左下角格子的统计/

{

if(Mine[8][0]num==1)

nNUM++;

if(Mine[9][1]num==1)

nNUM++;

if(Mine[8][1]num==1)

nNUM++;

}

else

if(i==9&&j==9)/右下角格子的统计/

{

if(Mine[9][8]num==1)

nNUM++;

if(Mine[8][9]num==1)

nNUM++;

if(Mine[8][8]num==1)

nNUM++;

}

else if(j==0)/左边第一列格子的统计/

{

if(Mine[i][j+1]num==1)

nNUM++;

if(Mine[i+1][j]num==1)

nNUM++;

if(Mine[i-1][j]num==1)

nNUM++;

if(Mine[i-1][j+1]num==1)

nNUM++;

if(Mine[i+1][j+1]num==1)

nNUM++;

}

else if(j==9)/右边第一列格子的统计/

{

if(Mine[i][j-1]num==1)

nNUM++;

if(Mine[i+1][j]num==1)

nNUM++;

if(Mine[i-1][j]num==1)

nNUM++;

if(Mine[i-1][j-1]num==1)

nNUM++;

if(Mine[i+1][j-1]num==1)

nNUM++;

}

else if(i==0)/第一行格子的统计/

{

if(Mine[i+1][j]num==1)

nNUM++;

if(Mine[i][j-1]num==1)

nNUM++;

if(Mine[i][j+1]num==1)

nNUM++;

if(Mine[i+1][j-1]num==1)

nNUM++;

if(Mine[i+1][j+1]num==1)

nNUM++;

}

else if(i==9)/最后一行格子的统计/

{

if(Mine[i-1][j]num==1)

nNUM++;

if(Mine[i][j-1]num==1)

nNUM++;

if(Mine[i][j+1]num==1)

nNUM++;

if(Mine[i-1][j-1]num==1)

nNUM++;

if(Mine[i-1][j+1]num==1)

nNUM++;

}

else/普通格子的统计/

{

if(Mine[i-1][j]num==1)

nNUM++;

if(Mine[i-1][j+1]num==1)

nNUM++;

if(Mine[i][j+1]num==1)

nNUM++;

if(Mine[i+1][j+1]num==1)

nNUM++;

if(Mine[i+1][j]num==1)

nNUM++;

if(Mine[i+1][j-1]num==1)

nNUM++;

if(Mine[i][j-1]num==1)

nNUM++;

if(Mine[i-1][j-1]num==1)

nNUM++;

}

return(nNUM);/把格子周围一共有多少雷数的统计结果返回/

}

int ShowWhite(int i,int j)/显示无雷区的空白部分/

{

if(Mine[i][j]flag==1||Mine[i][j]num==0)/如果有红旗或该格处理过就不对该格进行任何判断/

return;

mineNUM--;/显示过数字或者空格的格子就表示多处理了一个格子,当所有格子都处理过了表示胜利/

if(Mine[i][j]roundnum==0&&Mine[i][j]num!=1)/显示空格/

{

DrawEmpty(i,j,1,7);

Mine[i][j]num=0;

}

else

if(Mine[i][j]roundnum!=0)/输出雷数/

{

DrawEmpty(i,j,0,8);

sprintf(randmineNUM,"%d",Mine[i][j]roundnum);

setcolor(RED);

outtextxy(195+j20,95+i20,randmineNUM);

Mine[i][j]num=0;/已经输出雷数的格子用0表示已经用过这个格子/

return ;

}

/8个方向递归显示所有的空白格子/

if(i!=0&&Mine[i-1][j]num!=1)

ShowWhite(i-1,j);

if(i!=0&&j!=9&&Mine[i-1][j+1]num!=1)

ShowWhite(i-1,j+1);

if(j!=9&&Mine[i][j+1]num!=1)

ShowWhite(i,j+1);

if(j!=9&&i!=9&&Mine[i+1][j+1]num!=1)

ShowWhite(i+1,j+1);

if(i!=9&&Mine[i+1][j]num!=1)

ShowWhite(i+1,j);

if(i!=9&&j!=0&&Mine[i+1][j-1]num!=1)

ShowWhite(i+1,j-1);

if(j!=0&&Mine[i][j-1]num!=1)

ShowWhite(i,j-1);

if(i!=0&&j!=0&&Mine[i-1][j-1]num!=1)

ShowWhite(i-1,j-1);

}

void GamePlay(void)/游戏过程/

{

int i,j,Num;/Num用来接收统计函数返回一个格子周围有多少地雷/

for(i=0;i<10;i++)

for(j=0;j<10;j++)

Mine[i][j]roundnum=MineStatistics(i,j);/统计每个格子周围有多少地雷/

while(!kbhit())

{

if(LeftPress())/鼠标左键盘按下/

{

MouseGetXY();

if(MouseX>280&&MouseX<300&&MouseY>65&&MouseY<85)/重新来/

{

MouseOff();

gameAGAIN=1;

break;

}

if(MouseX>190&&MouseX<390&&MouseY>90&&MouseY<290)/当前鼠标位置在格子范围内/

{

j=(MouseX-190)/20;/x坐标/

i=(MouseY-90)/20;/y坐标/

if(Mine[i][j]flag==1)/如果格子有红旗则左键无效/

continue;

if(Mine[i][j]num!=0)/如果格子没有处理过/

{

if(Mine[i][j]num==1)/鼠标按下的格子是地雷/

{

MouseOff();

GameOver();/游戏失败/

break;

}

else/鼠标按下的格子不是地雷/

{

MouseOff();

Num=MineStatistics(i,j);

if(Num==0)/周围没地雷就用递归算法来显示空白格子/

ShowWhite(i,j);

else/按下格子周围有地雷/

{

sprintf(randmineNUM,"%d",Num);/输出当前格子周围的雷数/

setcolor(RED);

outtextxy(195+j20,95+i20,randmineNUM);

mineNUM--;

}

MouseOn();

Mine[i][j]num=0;/点过的格子周围雷数的数字变为0表示这个格子已经用过/

if(mineNUM<1)/胜利了/

{

GameWin();

break;

}

}

}

}

}

if(RightPress())/鼠标右键键盘按下/

{

MouseGetXY();

if(MouseX>190&&MouseX<390&&MouseY>90&&MouseY<290)/当前鼠标位置在格子范围内/

{

j=(MouseX-190)/20;/x坐标/

i=(MouseY-90)/20;/y坐标/

MouseOff();

if(Mine[i][j]flag==0&&Mine[i][j]num!=0)/本来没红旗现在显示红旗/

{

DrawRedflag(i,j);

Mine[i][j]flag=1;

}

else

if(Mine[i][j]flag==1)/有红旗标志再按右键就红旗消失/

{

DrawEmpty(i,j,0,8);

Mine[i][j]flag=0;

}

}

MouseOn();

sleep(1);

}

}

}

以上就是关于C++扫雷源代码全部的内容,包括:C++扫雷源代码、扫雷游戏的C代码给个网址或代码也行、等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/10635615.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-10
下一篇 2023-05-10

发表评论

登录后才能评论

评论列表(0条)

保存