我想创建一个雷区。首先,我做了一个矩阵,让用户输入行和列。
I need to:
- 放炸弹
- 表示附近的炸弹数量。
#include <stdio.h>
#include <stdlib.h>
int main(){
int rows, columns, i, j, bombs, **matrix;
printf("Enter the rows: ");
scanf("%d", &rows);
printf("Enter the columns:");
scanf("%d", &columns);
printf("Enter the bombs:");
scanf("%d", &bombs);
if (bombs>= (rows*colums)){
printf("Error");
}
if (bombs<= 0){
printf("Error);
}
for (i = 0; i < rows; i++){
for (j = 0; j < columns; j++){
matrix[i][j] = rand() % 10;
}
}
// show the map //
for (i = 0; i < rows; i++){
for (j = 0; j < columns; j++) {
printf("%d", matrix[i][j]);
}
printf("nn");
}
return 0;
}
``
数据结构
与其使用int
,然后记住神奇的数字,比如-1
表示矿山,不如明确地说出这些数字的含义更自然。然后你就可以改变主意或添加内容,而不用担心重写整个程序。在整个雷区,没有cols
和rows
,只有int **m
是没有用的。这种相互依赖表明,您还应该将它们打包在一个结构中,作为一个变量传递。
struct tile { unsigned nearby : 4, is_mine : 1, is_revealed : 1; };
struct map { size_t x, y; struct tile **tile; };
这些定义与您之前的定义非常相似,但是它们更好地表达了代码的意图。
阵列我就会忘记你的复杂alocMatrix
就使用一个配置,但是你必须使用tiles[y * map->x + x]
。个人喜好;我认为有一个构造函数返回一个分配的块更容易。
struct map { size_t x, y; struct tile *tile; };
...
if(!(map = malloc(sizeof *map + sizeof *tile * x * y)))
{ if(!errno) errno = ERANGE; return 0; }
...
map->tile = (struct tile *)(map + 1);
memset(map->tile, 0, sizeof *tile * x * y);
矿山均匀随机布设地雷的一种方法是反复随机选择一个瓦片,把你看到的瓦片扔出去。另一种方法是访问所有瓷砖并计算每个瓷砖的概率,P(mines left / tiles left)
。这取决于挖矿的数量,哪个更快。
const size_t x1 = map->x, y1 = map->y;
size_t x, y, squares = x1 * y1;
assert(map && mines < squares);
for(x = 0; x < x1; x++) {
for(y = 0; y < y1; y++) {
struct tile *tile = &map->tile[y * x1 + x];
tile->is_revealed = 0;
tile->is_mine = rand() < RAND_MAX / squares * mines;
mines -= tile->is_mine;
squares--;
}
}
for(x = 0; x < x1; x++) for(y = 0; y < y1; y++)
map->tile[y * x1 + x].nearby =
(x && y && map->tile[(y-1) * x1 + (x-1)].is_mine) +
...
(x && y < y1 - 1 && map->tile[(y+1) * x1 + (x-1)].is_mine);
如何使用这个函数来放置炸弹?通过传递m
的地址来调用它。记住,用适当的数字标记剩下的方块必须发生在炸弹放置之后(它不应该依赖于对rand
的调用)。此外,必须初始化映射以避免意外。
void placeBombs(int*** map, int numOfRows, int numOfColumns, int numOfBombs)
{
while (numOfBombs > 0) {
int column = rand() % numOfColumns;
int row = rand() % numOfRows;
if ((*map)[row][column] != -1) {
(*map)[row][column] = -1;
--numOfBombs;
}
/* Else, if a bomb already exists in the cell,
* we iterate without placing a bomb
*/
}
}