# 基于Qt的扫雷游戏（附源码）

## 核心算法

### 生成随机地图

bool Mine::MallocMemForMap(int in_raw, int in_column, int in_mineNum)
{
//非法入参
if(1 > in_raw || 1 > in_column || 1 > in_mineNum || in_mineNum > in_raw * in_column)
{
cout << "error: para error!" << endl;
return false;
}
if(NULL != map)
{
for(int i = 0; i < raw; i ++)
{
delete map[i];
}
delete map;
}
map = NULL;

raw = in_raw;
column = in_column;
mineNum = in_mineNum;

map = new unsigned char*[raw];
for(unsigned char j = 0; j < raw; j ++)
{
map[j] = new unsigned char[column];
}
return true;
}

bool Mine::InitMap()
{
int xpos, ypos, mineLeft = mineNum;
int xs, xe, ys, ye;//填值时使用的上下左右边界值

if(NULL == map)
{
cout << "error: null ptr!" << endl;
return false;
}
//初始化内存，全部填0
for(int i = 0; i < raw; i ++)
{
for(int j = 0; j < column; j ++)
{
map[i][j] = 0;
}
}

//埋雷---采用随机生成雷坐标的方式,雷使用符号'*'的ASCII
srand(time(NULL));//以当前时间为随机种子，保证随机性
while(0 != mineLeft)
{
xpos = rand() % raw;
ypos = rand() % column;
if(0 == map[xpos][ypos])
{
map[xpos][ypos] = '*';
mineLeft --;
}
continue;
}

//根据雷的分布填充其他方格数值
for(int i = 0; i < raw; i ++)
{
for(int j = 0; j < column; j ++)
{
if('*' == map[i][j])
{
//设定雷周围可遍历方格的区间
xs = (i - 1 >= 0) ? (i - 1) : i;
xe = (i + 1 < raw) ? (i + 1) : i;
ys = (j - 1 >= 0) ? (j - 1) : j;
ye = (j + 1 < column) ? (j + 1) : j;

for(xpos = xs; xpos <= xe ; xpos ++)
{
for(int ypos = ys; ypos <= ye; ypos ++)
{
if('*' == map[xpos][ypos])
{
continue;
}
map[xpos][ypos] ++;
}
}
}
}
}
return true;
}


###递归翻开格子

void MainWindow::recursiveFreshBlock(int raw_pos, int col_pos)
{
int raw_s, raw_e, col_s, col_e;//上下左右边界值
//设定周围可遍历方格的区间
raw_s = (raw_pos - 1 >= 0) ? (raw_pos - 1) : raw_pos;
raw_e = (raw_pos + 1 < raw) ? (raw_pos + 1) : raw_pos;
col_s = (col_pos - 1 >= 0) ? (col_pos - 1) : col_pos;
col_e = (col_pos + 1 < column) ? (col_pos + 1) : col_pos;

map_flag[raw_pos][col_pos] = 1;

for(int i = raw_s; i <= raw_e; i ++)
{
for(int j = col_s; j <= col_e; j ++)
{
if(i == raw_pos && j == col_pos)
{
continue;
}
if(0 == m.map[i][j] && 0 == map_flag[i][j])
{
recursiveFreshBlock(i, j);
}
else
{
map_flag[i][j] = 1;
}
}
}
}


## 源码链接

2018.04.05 更新

1.局域网内联机对战，一台做server，一台做clinet即可。
2.刚好租了搬瓦工的服务器一台，打算把server迁移到服务器端
3.手写一个扫雷AI，部署到服务器上（其实算不上AI），只是想把自己分析扫雷的思路凝聚一下。
4.增加一个可以自由设计地图的功能，自由摆雷。设计好的地图可以以二进制文件形式进行存储，随时加载使用。目的是为了设计一些有趣的地图形状。
。。。

2018.09.22更新