[英]Minesweeper game
你知道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
*...
....
.*..
....
輸出是: 重要的是要看它..單擊此處注意:我試圖打印出現在圖片中的符號的值,在ascii代碼中它是11,是垂直制表符。
並且,如果*最后是*,則另一個問題如下:
4 4
...*
....
....
...*
000*
0000
0000
000*
但是當*位於中間時,我的代碼運行良好,如下所示:
4 4
....
..*.
.*..
....
0111
12*1
1*21
1110
那么,我的代碼有什么問題?
在這一行中,您可以越界:
if(r >= 0 && c >= 0 && ms[r][c] != '*')
ms[r][c] += 1 ;
您僅測試r和c是否為負數,但還應該測試它們是否太大。
事情變得更加復雜,因為您有全局變量m和n ,它們是數組的維數,但是它們在calc函數中不可用,因為那里有同名的局部變量。
因此,最好使用不同的變量名。 然后,應測試r<m
和c<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的答案)。 如果您不會閱讀這些空格字符,則仍然會溢出,並且可能會觸摸下一行數據中的數據,這不是您想要的。
scanf("%d", ...);
在輸入緩沖區中保留空格(ENTER)。 然后
scanf("%c", ...);
將空白讀入變量。
在讀取星號和點之前(和期間),您需要忽略空格。
采用
scanf(" %c", ...);
// ^^^ ignore whitespace
注意:轉換說明符"%d"
(以及許多其他說明)已經包括忽略空格; 例外是"%c"
, "%["
和[由於不同的原因] "%n"
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.