“简单”的扫雷游戏
程序员文章站
2022-04-12 10:33:12
...
废话不多说直接放源码
鉴于还没有完全优化
所以会持续更新
game.h
#ifndef _GAME_H__
#define _GAME_H__
#define COL 10
#define ROW 10
#define COLS COL+2
#define ROWS ROW+2
//#include <conio.h>
#include<windows.h>
#include<time.h>
#include<stdio.h>
void game();
void init_mine(int mine[ROWS][COLS], int rows, int cols,int count);
void init_show(char show[ROWS][COLS], int rows, int cols);
void printmine(int mine[ROWS][COLS], int row, int col);
void printshow(char show[ROWS][COLS], int row, int col);
int sweep_mine(int mine[ROWS][COLS], char show[ROWS][COLS], int row, int col, int count);
int is_win(char show[ROWS][COLS], int row, int col,int count);
void menu();
int select_mode();
#endif
test.c
#include "Game.h"
int main()
{
int input;
srand((unsigned int)time(NULL));
res: //restart
menu();
do
{
printf("请选择>");
scanf_s("%d", &input);
switch (input)
{
case 0: break;
case 1:
game();
system("pause");
system("cls");
goto res;//restart
default:
printf("输入错误!请重新输入:\n");
}
} while (input);
system("pause");
return 0;
}
game.c
#include "Game.h"
void game()
{
int x = 0;
int y = 0;
int countsao = 0;
int mine[ROWS][COLS] = {0};
char show[ROWS][COLS] = {0};
int count = 0;
int win = 1;
count = select_mode();
init_mine(mine, ROWS, COLS, count);
init_show(show, ROWS, COLS);
while (win)
{
system("cls");
printshow(show, ROW, COL);
//printmine(mine, ROW, COL);
countsao++;
win = sweep_mine(mine, show, ROW, COL, count, countsao);
if (is_win(show, ROW, COL, count))
{
system("cls");
printf("\n恭喜你排完了所有的雷!\n");
break;
}
}
//printshow(show, ROW, COL);//扫雷界面
printmine(mine, ROW, COL);//雷信息
}
void menu()
{
printf(" 欢迎来到扫雷世界! \n");
printf("\n\n***********************************\n");
printf("*********** 1.开始 ************\n");
printf("***********************************\n");
printf("*********** 0.退出 ************\n");
printf("***********************************\n");
}
int select_mode()
{
int num = 0;
system("cls");
printf("\n\n**************************************\n");
printf("*1.简单 2.困难 3.大师*\n");
printf("**************************************\n");
while(1)
{
printf("请输入选择>");
scanf_s("%d", &num);
switch (num)
{
case 1:return ROWS;
case 2:return ROWS+ROWS/2;
case 3:return ROW*8;
default:printf("输入错误请重新输入!\n");
//case 3:return ROW*2+ROW/2;
}
}
}
void init_show(char show[ROWS][COLS], int rows, int cols)
{
int i = 0;
int j = 0;
for (i = 0; i < rows; i++)
{
for (j = 0; j < cols; j++)
{
show[i][j] = '0';
}
}
}
void init_mine(int mine[ROWS][COLS],int rows,int cols,int count)//布雷
{
int x = 0;
int y = 0;
int i = count;
while (i)
{
x = rand()%(rows -2)+1;
y = rand()%(cols -2)+1;
if (9 != mine[x][y])
{
mine[x][y] = 9;
i--;
if (9!=mine[x][y - 1])//周围雷数量
mine[x][y - 1]++;
if (9!= mine[x][y + 1])
mine[x][y + 1]++;
if (9!= mine[x - 1][y + 1])
mine[x - 1][y + 1]++;
if (9 != mine[x - 1][y])
mine[x - 1][y]++;
if (9 != mine[x - 1][y - 1])
mine[x - 1][y - 1]++;
if (9 != mine[x + 1][y - 1])
mine[x + 1][y - 1]++;
if (9 != mine[x + 1][y])
mine[x + 1][y]++;
if (9 != mine[x + 1][y + 1])
mine[x + 1][y + 1]++;
}
}
}
void printmine(int arr[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
int k = 0;
for(j=0; j<=col; j++)
{
if(j == 0)
printf("|");
printf("---+");
}
printf("\n");
for (i=0; i<=row; i++)
{
if(i == 0)
printf("|");
printf(" %-2d|",i);
/*if(i < row)
printf("|");*/
}
printf("\n");
for (i=0; i<=row; i++)
{
if(i == 0)
printf("|");
printf("---+");
/*if(i < row)
printf("|");*/
}
printf("\n");
for (i=1; i<=row; i++)
{
printf("| %-2d|",i);
for (j=1; j<=col; j++)
{
if (9 == arr[i][j])
{
printf(" ●|");
}
else
{
printf(" %-2d|", arr[i][j]);
//printf(" ");
}
/*if(j <= col)
printf("|");*/
}
printf("\n");
for (j=0; j<=col; j++)
{
if(j == 0)
printf("|");
printf("---+");
/*if(j <= col)
printf("|");*/
}
printf("\n");
}
}
void printshow(char show[ROWS][COLS], int row, int col)
{
int i = 0;
int j = 0;
for(j=0; j<=col; j++)
{
if(j == 0)
printf("|");
printf("---+");
}
printf("\n");
for (i=0; i<=row; i++)
{
if(i == 0)
printf("|");
printf(" %-2d|",i);
/*if(i < row)
printf("|");*/
}
printf("\n");
for (i=0; i<=row; i++)
{
if(i == 0)
printf("|");
printf("---+");
/*if(i < row)
printf("|");*/
}
printf("\n");
for (i=1; i<=row; i++)
{
printf("| %-2d|", i);
for (j=1; j<=col; j++)
{
if ('0'== show[i][j])
{
printf(" ▇|");
}
else if(1 == show[i][j])
{
printf(" ●|");
}
else
{
printf(" %2c|", show[i][j]);
}
/*if(j < col)
printf("|");*/
}
printf("\n");
for (j=0; j<=col; j++)
{
if(j == 0)
printf("|");
printf("---+");
/*if(j <= col)
printf("|");*/
}
printf("\n");
}
}
void sweepmine(int mine[ROWS][COLS],char show[ROWS][COLS], int x, int y,int row,int col)//递归判定
{
if (0 == mine[x][y])
{
show[x][y] = ' ';
}
if (' ' != show[x - 1][y])
{
if (0 == mine[x - 1][y] && x - 1 >= 1)
{
sweepmine(mine, show, x-1, y, row, col);
}
else
{
show[x - 1][y] = '0' + mine[x - 1][y];
}
}
if (' ' != show[x + 1][y])
{
if (0 == mine[x + 1][y] && x + 1 <= row && ' ' != show[x + 1][y])
{
sweepmine(mine, show, x+1, y, row, col);
}
else
{
show[x + 1][y] = '0' + mine[x + 1][y];
}
}
if (' ' != show[x][y-1])
{
if (0 == mine[x][y - 1] && y - 1 >= 1 && ' ' != show[x][y - 1])
{
sweepmine(mine, show, x, y-1, row, col);
}
else
{
show[x][y - 1] = '0' + mine[x][y - 1];
}
}
if (' ' != show[x - 1][y-1])
{
if (0 == mine[x - 1][y - 1] && x - 1 >= 1 && y - 1 >= 1 && ' ' != show[x - 1][y - 1])
{
sweepmine(mine, show, x-1, y-1, row, col);
}
else
{
show[x - 1][y - 1] = '0' + mine[x - 1][y - 1];
}
}
if (' ' != show[x + 1][y-1])
{
if (0 == mine[x + 1][y - 1] && x + 1 <= row && y - 1 >= 1 && ' ' != show[x + 1][y - 1])
{
sweepmine(mine, show, x+1, y-1, row, col);
}
else
{
show[x + 1][y - 1] = '0' + mine[x + 1][y - 1];
}
}
if (' ' != show[x + 1][y+1])
{
if (0 == mine[x + 1][y + 1] && x + 1 <= row && y + 1 <= col && ' ' != show[x + 1][y + 1])
{
sweepmine(mine, show, x+1, y+1, row, col);
}
else
{
show[x + 1][y + 1] = '0' + mine[x + 1][y + 1];
}
}
if (' ' != show[x - 1][y +1])
{
if (0 == mine[x - 1][y + 1] && x - 1 >= 1 && y + 1 <= col && ' ' != show[x - 1][y + 1])
{
sweepmine(mine, show, x-1, y+1, row, col);
}
else
{
show[x - 1][y + 1] = '0' + mine[x - 1][y + 1];
}
}
if (' ' != show[x ][y + 1])
{
if (0 == mine[x][y + 1] && y + 1 <= col && ' ' != show[x][y + 1])
{
sweepmine(mine, show, x, y+1, row, col);
}
else
{
show[x][y + 1] = '0' + mine[x][y + 1];
}
}
}
int is_win(char show[ROWS][COLS],int row,int col,int count)
{
int x = 0;
int y = 0;
int countmine = 0;
for (x = 1; x <= row; x++)
{
for (y = 1; y <= col; y++)
{
if ('0' != show[x][y])
countmine++;
}
}
return (countmine >= (row*col - count));
}
int sweep_mine(int mine[ROWS][COLS],char show[ROWS][COLS],int row,int col,int count, int countsao)
{
int i = 0,j = 0, x = 0, y = 0;
char c;
while (1)
{
if(countsao > 1)
{
printf("是否进行标记?(y/n)");
scanf("%c",&c);
fflush(stdin);
if('y' == c)
{
printf("请输入标记坐标:");
scanf("%d %d",&x,&y);
fflush(stdin);
show[x][y] = 1;
system("cls");
printshow(show, ROW, COL);
}
while('y' == c)
{
printf("是否继续标记?(y/n)");
scanf("%c",&c);
fflush(stdin);
if('y' == c)
{
printf("请输入标记坐标:");
scanf("%d %d",&x,&y);
fflush(stdin);
show[x][y] = 1;
system("cls");
printshow(show, ROW, COL);
}
}
}
printf("请输入排雷坐标>");
scanf_s("%d %d", &x, &y);
fflush(stdin);
if (x>=1&&x<= row &&y>=1&&y<= col)
{
if (9 == mine[x][y])//避开第一次就踩雷
{
if (1 == countsao)
{
//system("cls");
//init_mine( mine, row+2, col+2, count);
//countsao = 0;
//sweep_mine( mine, show, row, col, count);
while (9 == mine[x][y])
{
i = rand() % row + 1;
j = rand() % col + 1;
if(mine[i][j] != 9 )
{
mine[x][y] = 0;
mine[i][j] = 9;
if (9!=mine[x][y - 1] )//原位置周围雷数量
mine[x][y - 1]--;
else
mine[x][y]++;
if (9!= mine[x][y + 1] )
mine[x][y + 1]--;
else
mine[x][y]++;
if (9!= mine[x - 1][y + 1] )
mine[x - 1][y + 1]--;
else
mine[x][y]++;
if (9 != mine[x - 1][y] )
mine[x - 1][y]--;
else
mine[x][y]++;
if (9 != mine[x - 1][y - 1] )
mine[x - 1][y - 1]--;
else
mine[x][y]++;
if (9 != mine[x + 1][y - 1] )
mine[x + 1][y - 1]--;
else
mine[x][y]++;
if (9 != mine[x + 1][y] )
mine[x + 1][y]--;
else
mine[x][y]++;
if (9 != mine[x + 1][y + 1] )
mine[x + 1][y + 1]--;
else
mine[x][y]++;
if (9!=mine[i][j - 1])//新位置周围雷数量
mine[i][j - 1]++;
if (9!= mine[i][j + 1])
mine[i][j + 1]++;
if (9!= mine[i - 1][j + 1])
mine[i - 1][j + 1]++;
if (9 != mine[i - 1][j])
mine[i - 1][j]++;
if (9 != mine[i - 1][j - 1])
mine[i - 1][j - 1]++;
if (9 != mine[i + 1][j - 1])
mine[i + 1][j - 1]++;
if (9 != mine[i + 1][j])
mine[i + 1][j]++;
if (9 != mine[i + 1][j + 1])
mine[i + 1][j + 1]++;
}
}
}
else
{
system("cls");
printf("很遗憾,你挂了!\n");
return 0;
}
}
if (0 == mine[x][y])
{
sweepmine(mine, show, x, y, row, col);
}
else
{
show[x][y] = '0' + mine[x][y];
}
break;
}
else
{
printf("输入有误,请重新输入\n");
}
}
return 1;
}
更新日志:
4月21日更新了第一次踩雷出现的bug;优化了部分代码和UI。
4月22日更新了标记地雷功能;优化了部分代码。
上一篇: 简单扫雷游戏