在c中初始化一个扫雷器
Initialize a minesweeper in c
我目前正在使用 CSFML 库用 C 重写一个扫雷程序。
我在管理第一次点击后的初始化时遇到了一些问题,更准确地说是在我应该将点击周围的图块设置为空的部分。
我找不到在不冒移除炸弹风险的情况下清空这些方块的方法。
这是我现在的初始化代码块:
int current = 0;
temp.bombs = BOMB_EASY;
temp.difficulty = EASY;
temp.mapEasy = malloc(sizeof(sTILE *) * (Y_EASY + 1));
for (int i = 0; i < Y_EASY + 1 ; i++)
{
temp.mapEasy[i] = malloc(sizeof(sTILE) * (X_EASY + 1));
}
for (int i = 0; i < X_EASY + 1; i++)
{
temp.mapEasy[Y_EASY][i].type = 0;
}
while (current < BOMB_EASY)
{
for (int i = 0; i < Y_EASY; i++)
{
for (int j = 0; j < X_EASY; j++)
{
int isBomb = rand() % 10;
if (isBomb == 0 && current < BOMB_EASY && temp.mapEasy[i][j].type != 9)
{
temp.mapEasy[i][j].type = 9;
current++;
}
else if (temp.mapEasy[i][j].type != 9)
{
temp.mapEasy[i][j].type = 0;
}
}
}
}
for (int i = 0; i < Y_EASY; i++)
{
for (int j = 0; j < X_EASY; j++)
{
if (temp.mapEasy[i][j].type == 0)
{
temp.mapEasy[i][j].type = HowManyBombs(temp.mapEasy, i, j, Y_EASY, X_EASY);
}
temp.mapEasy[i][j].isRevealed = sfFalse;
temp.mapEasy[i][j].isFlagged = sfFalse;
}
}
}
我知道我的问题可能看起来很愚蠢,而且可能已经有人回答了,但我找不到答案,所以感谢那些愿意回答我的人。
- 创建一个空矩阵
- 在随机位置用 n 个地雷填充它。生成 (x, y) 坐标后,检查它们是否已被占用。
如果已经取得坐标,则应将地雷放置在下一个可用位置。
例如将x增加1,检查是否空闲,如果没有,再次增加x。到达行尾后,改为增加 y 并从 x=0 重新开始。
如果您只是生成一个新的随机数,理论上您的算法可能会永远停滞不前。在实践中它可能会起作用,但我希望这样的算法生成网格的速度比只选择下一个空闲点的算法慢1)。
1) rand() 调用开销是该算法中最有可能的瓶颈。但是,如果您选择下一个位置而不是再次调用 rand() , CPU 可能能够推测性地加载预取数据缓存中的(部分)数组。当你每次选择它时,内存位置实际上是随机的,这是不可能的。
我目前正在使用 CSFML 库用 C 重写一个扫雷程序。
我在管理第一次点击后的初始化时遇到了一些问题,更准确地说是在我应该将点击周围的图块设置为空的部分。
我找不到在不冒移除炸弹风险的情况下清空这些方块的方法。 这是我现在的初始化代码块:
int current = 0;
temp.bombs = BOMB_EASY;
temp.difficulty = EASY;
temp.mapEasy = malloc(sizeof(sTILE *) * (Y_EASY + 1));
for (int i = 0; i < Y_EASY + 1 ; i++)
{
temp.mapEasy[i] = malloc(sizeof(sTILE) * (X_EASY + 1));
}
for (int i = 0; i < X_EASY + 1; i++)
{
temp.mapEasy[Y_EASY][i].type = 0;
}
while (current < BOMB_EASY)
{
for (int i = 0; i < Y_EASY; i++)
{
for (int j = 0; j < X_EASY; j++)
{
int isBomb = rand() % 10;
if (isBomb == 0 && current < BOMB_EASY && temp.mapEasy[i][j].type != 9)
{
temp.mapEasy[i][j].type = 9;
current++;
}
else if (temp.mapEasy[i][j].type != 9)
{
temp.mapEasy[i][j].type = 0;
}
}
}
}
for (int i = 0; i < Y_EASY; i++)
{
for (int j = 0; j < X_EASY; j++)
{
if (temp.mapEasy[i][j].type == 0)
{
temp.mapEasy[i][j].type = HowManyBombs(temp.mapEasy, i, j, Y_EASY, X_EASY);
}
temp.mapEasy[i][j].isRevealed = sfFalse;
temp.mapEasy[i][j].isFlagged = sfFalse;
}
}
}
我知道我的问题可能看起来很愚蠢,而且可能已经有人回答了,但我找不到答案,所以感谢那些愿意回答我的人。
- 创建一个空矩阵
- 在随机位置用 n 个地雷填充它。生成 (x, y) 坐标后,检查它们是否已被占用。
如果已经取得坐标,则应将地雷放置在下一个可用位置。
例如将x增加1,检查是否空闲,如果没有,再次增加x。到达行尾后,改为增加 y 并从 x=0 重新开始。
如果您只是生成一个新的随机数,理论上您的算法可能会永远停滞不前。在实践中它可能会起作用,但我希望这样的算法生成网格的速度比只选择下一个空闲点的算法慢1)。
1) rand() 调用开销是该算法中最有可能的瓶颈。但是,如果您选择下一个位置而不是再次调用 rand() , CPU 可能能够推测性地加载预取数据缓存中的(部分)数组。当你每次选择它时,内存位置实际上是随机的,这是不可能的。