- 游戏
- @ 2026-07-27 08:10:57
扫雷
刚学C++没多久,从我detect函数的逻辑(dfs)就能知道我那是还没学bfs,瞎写的,哪些句柄没释放也希望大家提醒一下:
//////////////////////////////////
//如果发现选中的位置与预期不符,//
//可以试试打开源文件编译后的EXE //
//程序,虽然它会随时适应控制台字//
//符长宽,但是最好不要缩放控制台//
//////////////////////////////////
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<conio.h>
#define __color(attr); SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),attr);
#define color(attr); __color(0x##attr);
#define __gotoxy(x,y); SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),{x,y});
#define gotoxy(x,y); __gotoxy((SHORT)(x),(SHORT)(y));
int rect[18][18];
bool mark[18][18];
bool vis[18][18];
int vis_quantity;
bool exploded;
int wordsize_width,wordsize_height;
void init_rect(){
srand((unsigned int)(time(NULL)));
for(int i=256;i>216;i--){
int tmp=rand()%i;
bool flag=0;
for(int j=1;j<=16&&!flag;j++){
for(int k=1;k<=16&&!flag;k++){
if(rect[j][k]>=1000)continue;
if(tmp--)continue;
rect[j-1][k-1]++;
rect[j-1][k]++;
rect[j-1][k+1]++;
rect[j][k-1]++;
rect[j][k]=1000;
rect[j][k+1]++;
rect[j+1][k-1]++;
rect[j+1][k]++;
rect[j+1][k+1]++;
flag=1;
}
}
}
for(int i=1;i<=16;i++){
for(int j=1;j<=16;j++){
if(rect[i][j]>=1000)rect[i][j]=1000;
}
}
for(int i=0;i<18;i++){
rect[i][0]=-1;
rect[0][i]=-1;
rect[i][17]=-1;
rect[17][i]=-1;
vis[i][0]=1;
vis[0][i]=1;
vis[i][17]=1;
vis[17][i]=1;
}
}
bool GetConsoleWordSize(int &width,int &height){
HANDLE hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
if(hConsole==INVALID_HANDLE_VALUE)return false;
CONSOLE_FONT_INFO cfi;
if(!GetCurrentConsoleFont(hConsole,0,&cfi))return false;
width=cfi.dwFontSize.X;
height=cfi.dwFontSize.Y;
return true;
}
bool GetSelectedWordPos(LPPOINT lpPoint,int nWidth,int nHeight){
HWND hConsoleWnd=GetConsoleWindow();
if(hConsoleWnd!=GetForegroundWindow())return false;
if(!GetCursorPos(lpPoint))return false;
if(!ScreenToClient(hConsoleWnd,lpPoint))return false;
lpPoint->x/=nWidth;lpPoint->y/=nHeight;
return true;
}
void detect(int x,int y){
vis[x][y]=1;
vis_quantity++;
mark[x][y]=0;
if(rect[x][y]){
if(rect[x][y]==1000)exploded=1;
return;
}
if(!vis[x-1][y-1])detect(x-1,y-1);
if(!vis[x-1][y])detect(x-1,y);
if(!vis[x-1][y+1])detect(x-1,y+1);
if(!vis[x][y-1])detect(x,y-1);
if(!vis[x][y+1])detect(x,y+1);
if(!vis[x+1][y-1])detect(x+1,y-1);
if(!vis[x+1][y])detect(x+1,y);
if(!vis[x+1][y+1])detect(x+1,y+1);
}
bool DisableConsoleSelect(){
HANDLE hIn=GetStdHandle(STD_INPUT_HANDLE);
DWORD Mode;
if(hIn==INVALID_HANDLE_VALUE)return false;
if(!GetConsoleMode(hIn,&Mode))return false;
if(!SetConsoleMode(hIn,Mode&(~ENABLE_QUICK_EDIT_MODE)&(~ENABLE_MOUSE_INPUT)))return false;
return true;
}
bool HideConsoleCursor(){
HANDLE hOut=GetStdHandle(STD_OUTPUT_HANDLE);
if(hOut==INVALID_HANDLE_VALUE)return false;
CONSOLE_CURSOR_INFO cci;
if(!GetConsoleCursorInfo(hOut,&cci))return false;
cci.bVisible=FALSE;
if(!SetConsoleCursorInfo(hOut,&cci))return false;
return true;
}
void print(){
POINT mouse;
GetSelectedWordPos(&mouse,wordsize_width,wordsize_height);
for(int i=1;i<=16;i++){
for(int j=1;j<=16;j++){
gotoxy(i*2,j);
if(vis[i][j]){
if(rect[i][j]==0){
if(i!=mouse.x/2||mouse.x%2==1||j!=mouse.y){
color(8);
}else{
color(f8);
}
putchar('0');
}else if(rect[i][j]==1){
if(i!=mouse.x/2||mouse.x%2==1||j!=mouse.y){
color(1);
}else{
color(f1);
}
putchar('1');
}else if(rect[i][j]==2){
if(i!=mouse.x/2||mouse.x%2==1||j!=mouse.y){
color(2);
}else{
color(f2);
}
putchar('2');
}else{
if(i!=mouse.x/2||mouse.x/2==1||j!=mouse.y){
color(4);
}else{
color(f4);
}
printf("%d",rect[i][j]);
}
}else if(mark[i][j]){
if(i!=mouse.x/2||mouse.x%2==1||j!=mouse.y){
color(c);
}else{
color(fc);
}
putchar('F');
}else{
if(i!=mouse.x/2||mouse.x%2==1||j!=mouse.y){
color(8);
}else{
color(f8);
}
putchar('+');
}
}
}
}
void last_print(){
for(int i=1;i<=16;i++){
for(int j=1;j<=16;j++){
gotoxy(i*2,j);
if(mark[i][j]&&rect[i][j]!=1000){
color(5);
putchar('F');
}else if(rect[i][j]==1000){
if(vis[i][j]){
color(4f);
}else{
color(f);
}
putchar('X');
}
}
}
}
int main(){
for(int i=1;!DisableConsoleSelect();i++)if(i>100)return -1;
system("MODE CON COLS=38 LINES=19");
system("TITLE 扫雷");
puts("鼠标指针位置:你选中的位置。\n左键:探测。\n空格:标记。");
color(8);
puts("为啥不是右键标记?因为我不会关右键菜单。");
color(7);
printf("标错为“");
color(5);
putchar('F');
color(7);
puts("”");
color(a);
system("PAUSE");
color(7);
system("CLS");
HWND hConsole=GetConsoleWindow();
init_rect();
POINT mouse;
puts("+---------------------------------+");
for(int i=1;i<=16;i++)puts("| |");
puts("+---------------------------------+");
while(true){
if(!GetConsoleWordSize(wordsize_width,wordsize_height))continue;
print();
if(!HideConsoleCursor())continue;
if(GetAsyncKeyState(VK_LBUTTON)){
if(!GetSelectedWordPos(&mouse,wordsize_width,wordsize_height))continue;
if(mouse.x%2==1||1>mouse.x/2||mouse.x/2>16||1>mouse.y||mouse.y>16)continue;
if(vis[mouse.x/2][mouse.y]||mark[mouse.x/2][mouse.y])continue;
detect(mouse.x/2,mouse.y);
}else if(kbhit()){
if(getch()!=' ')continue;
if(!GetSelectedWordPos(&mouse,wordsize_width,wordsize_height))continue;
if(mouse.x%2==1||1>mouse.x/2||mouse.x/2>16||1>mouse.y||mouse.y>16)continue;
if(vis[mouse.x/2][mouse.y])continue;
if(1>mouse.x/2||mouse.x/2>16||1>mouse.y||mouse.y>16)continue;
mark[mouse.x/2][mouse.y]=!mark[mouse.x/2][mouse.y];
}
if(exploded){
last_print();
gotoxy(1,18);
color(47);
printf("你失败了!");
Sleep(1000);
color(8);
printf("按任意键退出");
system("PAUSE>NUL");
return 0;
}
if(vis_quantity==216){
gotoxy(1,18);
color(a0);
printf("扫雷成功!");
Sleep(1000);
color(8);
printf("按任意键退出");
system("PAUSE>NUL");
return 0;
}
Sleep(50);
}
return 0;
}
1 条评论
-
LazyOperator703 LV 3 @ 2026-07-27 10:31:03
学着windows.h里TEXT()的宏定义,套了两层宏,警告果然少了
- 1