題目:
本作業將使用C語言進行踩地雷遊戲的數字計算。
大部分的人都玩過踩地雷的遊戲,遊戲的開始是在一個M*N的陣列中佈有許多地雷,你必須將佈有地雷的地方插一個旗子,在沒有地雷的地方,填入這個格字的週遭(即上下左右斜上斜下等八個格子)佈有地雷的數字。下圖為Windows作業系統所附的遊戲畫面。
在這個作業中,題目的產生藉執行 finalproj2_gen.exe 程式而來,執行時,你必須輸入你的學號(不含A)七個數字作為命令列的引數。下列的問題就是在命令列輸入:finalproj2_gen 9628000 所得到,因此每個人的題目是不相同的。這個程式產生的題目會放在名稱為 "A"+學號+".in" 的檔案中,例如這裡的問題會放在 A9628000.in 的檔案中。題目中的 '*' 表示是地雷,'.' 表示不是地雷。題目第一列的兩個整數分別表示地雷矩陣的大小,亦即列數與行數。
17 36
*..*.**..........*.....*.........*..
.......*.....*.*......*.....*...**..
...**...............*...*.....*.....
........*...........*......**.*.....
.......*.....**..........*.....*..*.
...**............*...*.*.*.....*....
*...*.....**.*.*..*........*...**...
*...............*....*.....*........
.................*..*...........*...
....*...............**...**...*.....
*..**..*..*...........*.*....*.*...*
..**......*..........*.*.**...**....
.*.....*.............*..*...*.....*.
...*..**...*.*.**.....*......**.*.*.
....*.*.....*............**.........
..*...........*.*..*.**..*....**.**.
.*.*..**..**.....*...*...........*..
作業的輸出是以C語言計算所有非地雷點的週遭地雷數,輸出的格式第一行為"Answer for field " + 學號。接著列印地雷矩陣的資訊,有地雷的地方仍然印著 '*' ,沒地雷的地方則印著其週遭的地雷數。上述例題的答案如下所示。你必須將你的答案直接用程式輸出,輸出檔案的命名為 "A"+學號+".out" 。例如此例答案的輸出檔名為A9628000.out 。
Answer for field A9628000
*11*2**2100011212*10012*100111013*20
1123433*10001*2*211112*32101*212**20
001**112210011211002*312*11334*32210
00122112*10012210002*201222**3*31111
0012211*21001**1111122213*32223*21*1
111**211112233422*211*2*3*31103*4211
*213*20001**2*2*33*12231213*202**100
*201110001222122*3222*10002*20133200
11011100000000012*12*42012321112*100
1113*211111100001112**222**112*32111
*23**21*12*20000000134*3*5421*5*201*
23**312222*2000000002*4*4**223**2122
1*43213*2122212221002*43*322*44423*2
112*23**201*3*2**10012*223222**2*3*2
0123*3*31012*334321123322**113443432
12*32333112322*2*22*3**12*3101**3**1
1*3*11**11**11122*213*31111001223*31
話說...有些人連這都不會開...
流程:
>讀入檔案,並使用字串陣列接收。
>>將字串陣列的符號轉成數字代替,並用一個二維陣列接收。(EX:有地雷-->arr[i][j]=9,無地雷:-->arr[i][j]=0)
>>>用數個if 判斷arr[i][j]四周的8種不同的狀況,若成立,使arr[i][j]+1。
>>>>輸出檔案。
其實,做法只需要用fscanf(@@,##,$$)就可以一行一行的輸入.in的內容了。
@@=FILE指標的名稱 ##=%s(若欲輸入的內容是數字,就可以用%d) $$=字串名稱(char ch[80][80] 或 int input-->切記要"&input")
至於印出的話,可以用fprintf(@@,"",$$)。用法跟printf()一樣,只是最前面多了@@-->FILE指標名稱
(我覺得提示的有點太多了...)
判斷關鍵:
利用二維陣列的索引值相關性做判斷。其原理很簡單。
假設正中間的Arr[i][j]是陣列檢查到的值。
那麼,你只需要利用i、j的索引值去檢查他四周8個陣列的值是不是有出現地雷,這樣就可以知道Arr[i][j]四周有幾顆地雷。
原始碼:
#include stdio.h
#include stdlib.h
int main(void)
{
FILE *fin,*fout;//fin讀入題目的檔案指標 fout輸出答案的檔案指標
char ch[80][80];//讀入資料之字串陣列
int row,col,i=0,j,k1,k2,**arr,*arrData;//row欄 col列 i j控制陣列用 arr答案陣列 k1 k2判斷範圍之用
bool judge=0;//判斷用
/*////////////開始導入題目////////////*/
fin=fopen("\A9628393.in","r");
if(fin!=NULL)
{
if(judge==0)
{//第一次讀入 寫入列、欄
fscanf(fin,"%d %d",&col,&row);
judge=1;
}
while(!feof(fin))
{
//第二次之後 寫入地雷原型
fscanf(fin,"%s",ch[i]);
i++;
}
printf("題目檔開檔完成!\n");
fclose(fin);
}
else
printf("題目檔開檔失敗!\n");
/*/////////用malloc製作動態陣列/////////*/
arr=(int **)malloc(col*sizeof(int *));
arrData=(int *)malloc(col*row*sizeof(int));
for(i=0;i <col;i++,arrData+=row)< />
arr[i]=arrData;
/*////////////將動態陣列歸零////////////*/
for(i=0;i <col;i++)< />
for(j=0;j <row;j++)< />
arr[i][j]=0;
/*將字串陣列的地雷原型寫入至arr二維陣列:地雷=9 無地雷=0*/
for(i=0;i <col;i++)< />
{
for(j=0;j <row;j++)< />
{
if(ch[i][j]==42)
arr[i][j]=9;
else if(ch[i][j]==42)
arr[i][j]=0;
}
}
/*//////判斷arr[i][j]圍繞地雷之九宮格的值都加1//////*/
for(i=0;i <col;i++)< />
{
for(j=0;j <row;j++)< />
{
if(arr[i][j]==9)
{
for(k1=-1;k1<=1;k1++)
{
for(k2=-1;k2<=1;k2++)
{
if(i+k1>=0 && j+k2>=0 && i+k1
0 && k2!=0)
{
arr[i+k1][j+k2]++;
}//if
}
}//判斷範圍
}//if
}
}//主迴圈
/*//////////////開始導出答案//////////////*/
fout=fopen("\A9628393.out","w");
if(fout!=NULL)
{//將答案arr陣列寫入至A9628393.out
fprintf(fout,"Answer for field A9628393\n");
for(i=0;i <col;i++)< />
{
for(j=0;j <row;j++)< />
{
if(arr[i][j]==9)
fprintf(fout,"*");
else
fprintf(fout,"%d",arr[i][j]);
}
fprintf(fout,"\n");
}
printf("解答寫入完成!\n");
fclose(fout);
}
else
printf("解答寫入失敗!\a\n");
system("pause");
return 0;
}
我如果要做的話 如果 array[i][j] 剛好為 * 做出適當判斷 再依判斷把周圍符合條件的格子+1
回覆刪除喵的~老子每次看到你左邊那張穿著燭苳高中制服的照片,就會笑個不停...
回覆刪除嗯嗯~~會的~~~
回覆刪除關於讀檔與動態陣列的部分
回覆刪除我的建議是int ch[80][80]是不必要的
可以在if(judge==0)的時候就把col跟row讀入
用malloc建立動態陣列了
然後在下面就可以直接用動態列讀入資料了
就不用在下面再附加一個迴圈把資料從ch轉移過去arrData
這樣會比較省記憶體且能節省運算
重要的是既然用到動態陣列了
而ch是固定在80*80只要col或row超過了
那麼資料轉移的時候就會發生問題
呃 另外
回覆刪除"*" 是字串
'*' 是字元
兩者看起來相同其實是不同
"*" = {'*','0'}
'*' = {'*'}
小心使用有時候會有錯誤發生