【问题标题】:Minesweeper game扫雷游戏
【发布时间】:2016-02-23 18:06:35
【问题描述】:

你知道windows的扫雷游戏吗?好吧,下面的问题也是一样的,你要输入m和n...

0 < n,m <= 100
n : colons , m : rows

输入:

4 4
*...
....
.*..
....

输出:

*100
2210
1*10
1110

而且,那是我的代码。

#include <stdio.h>
#include <stdlib.h>
char ms[100][101] ;
int m , n;
void input(){
    for(int r = 0 ; r < m ; r++)
        for(int c = 0 ; c <= n ; c++){
            scanf("%c",&ms[r][c]);
            if('.' == ms[r][c])
                ms[r][c] += 2 ;
        }
}
void calc(int m , int n){
    for(int r = m ; r <= (m+2) ; r++)
        for(int c = n ; c <= (n+2) ; c++)
            if(r >= 0 && c >= 0 && ms[r][c] != '*')
                ms[r][c] += 1 ;

}
void solve(){
    for(int r = 0 ; r < m ; r++)
        for(int c = 0 ; c < n ; c++)
            if( '*' == ms[r][c])
                calc(r-1 , c-1);
}
void output(){
    for(int r = 0 ; r < m ; r++)
        for(int c = 0 ; c <= n ; c++)
            printf("%c ", ms[r][c]);
}
int main()
{

    scanf("%d%d" , &m , &n);
    input();
    solve();
    output();

    return 0;
}

运行我的代码时,如果输入有 * 在第一个如下:

4 4
*...
....
.*..
....

输出是: important to see it .. click here 注意:我尝试打印出现在图片中的符号的值,它是 11 的 ascii 代码,它是垂直制表符。

如果 * 在最后,另一个问题如下:

4 4
...*
....
....
...*

000*
0000
0000
000*

但是当 * 位于中间时我的代码运行良好,如下所示:

4 4
....
..*.
.*..
....

0111
12*1
1*21
1110

那么,我的代码有什么问题?

【问题讨论】:

  • 请不要发布文字图片,也请不要发布可能过时的图片链接。将文本复制粘贴到问题中。
  • 有一个叫做“调试”的东西可以让你跟踪你的代码。有时自己尝试可以帮助您更好地理解它,并帮助您避免犯同样的错误。
  • 您的问题可能与字符格式为%cscanf 有关:它还读取换行符。据我所知,单元格的唯一有效输入是点(免费)或星号(我的)。强制执行该条件并跳过所有其他输入。 (或者跳过所有其他空白并退出,否则会出错。)
  • for(int c = 0 ; c &lt;= n ; c++) 可能你需要使用c &lt; n
  • 当您计算网格边界上的相邻地雷时,会出现另一个最大问题:无条件考虑所有相邻单元格,您可能会越界。

标签: c arrays string algorithm


【解决方案1】:

在这一行你可以越界:

        if(r >= 0 && c >= 0 && ms[r][c] != '*')
            ms[r][c] += 1 ;

你只测试 rc 是否不是负数,但你也应该测试它们不是太大。

事情变得更加复杂,因为你有全局变量 mn 这是你的数组的维度,但它们在 calc 函数,因为那里有同名的局部变量。

所以你最好使用不同的变量名。然后你应该测试r&lt;mc&lt;n,如下:

void calc(int p , int q){
    for(int r = p ; r <= (p+2) ; r++)
        for(int c = q ; c <= (q+2) ; c++)
            if(r >= 0 && c >= 0 && r < m && c < n && ms[r][c] != '*')
                ms[r][c] += 1 ;

}

现在您看到 ASCII 11 的原因可以解释为 ASCII 10 是标记行结束的换行符。然后当你的代码对它执行ms[r][c] += 1(因为它走得太远了),它就变成了那个有趣的角色。

您的数组中有 ASCII 10 可以通过您读取输入的方式来解释(请参阅@pmg 的答案)。如果您没有读取那些空白字符,您仍然会溢出,并且可能会触摸下一行数据中的数据,这不是您想要发生的。

【讨论】:

    【解决方案2】:
    scanf("%d", ...);
    

    在输入缓冲区中留下空格(ENTER)。那么

    scanf("%c", ...);
    

    将该空格读入变量中。

    在读取星号和圆点之前(和期间)您需要忽略空格。

    使用

    scanf(" %c", ...);
    //    ^^^ ignore whitespace
    

    注意:转换说明符 "%d"(以及许多其他说明符)已经包含忽略空格;例外是 "%c""%[" 和 [出于不同原因] "%n")。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-04
      • 2012-11-15
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 2013-04-11
      相关资源
      最近更新 更多