c語言實現老鼠走迷宮
在沒有智能手機的時代,不少人玩游戲會玩老鼠走迷宮這樣的闖關游戲。每一關有着不同的地圖場景,可能還會充斥着各種障礙。
- 老鼠走迷宮是經典的遞回求解的算法題
我們用二維數組表示迷宮場景。其中用2代表迷宮的牆壁,0代表可行通道。
我們用7*7的二維數組具體實現,假定我們設置[1][1]是迷宮入口,[5][5]是迷宮出口。
#define M 7
int maze[M][M] =
{
{2,2,2,2,2,2,2},
{2,0,0,0,0,0,2},
{2,0,2,0,2,0,2},
{2,0,0,2,0,2,2},
{2,2,0,2,0,2,2},
{2,0,0,0,0,0,2},
{2,2,2,2,2,2,2}
};
int start1=1,start2=1;
int end1=5,end2=5;
int main ()
{
int i,j;
printf("顯示迷宮:\n");
for(i=0;i<M;i++) //對擺放的數組迷宮進行打印
{
for(j=0;j<M;j++)
if(maze[i][j] == 2)
printf("◾");
else
printf(" ");
printf("\n");
}
}
這樣我們的迷宮繪制基本完成。下面我們對老鼠可能行走的路徑進行分析輸出。
我們定義一個visit函數,對老鼠行走方向進行邏輯分析。我們把老鼠走的路徑記作1,也就是數組中的0被改為1 。
int success = 0; //聲明全局變量,若到達出口,將被賦值為1
int visit(int i,int j)
{
maze[i][j] = 1; //傳過來的位置一定是老鼠所行路徑,賦值為1
if(i==end1 && j==end2) //判斷是否到達[5][5]出口位置
success = 1;
//判斷是否到達出口,沒有則分析老鼠可以在迷宮移動的方向,並遞歸求下一步.
if(success != 1 && maze[i][j+1] == 0) //老鼠先嘗試向右,如果可行就遞歸,不行則往下判定
visit(i,j+1);
if(success != 1 && maze[i+1][j] == 0) //老鼠嘗試向下,如果可行就遞歸,不行則往下判定
visit(i+1,j);
if(success != 1 && maze[i][j-1] == 0) //老鼠嘗試向左,如果可行就遞歸,不行則往下判定
visit(i,j-1);
if(success != 1 && maze[i-1][j] == 0) //最后一歩方向判定,老鼠嘗試向上,如果可行就遞歸。
visit(i-1,j);
//判斷是否到達出口,沒有則證明前面走的路徑並不能到達出口,那么返回,把走過的位置重新寫作0
if(success != 1)
maze[i][j] = 0;
return success;
}
我們寫好老鼠的行走路徑后,在主函數中調用,並且輸出。
以下代碼寫在主函數中
if(visit(start1,start2) == 0) //調用visit函數,判斷老鼠是否走出迷宮
printf("\n沒有找到出口!\n");
else{
printf("\n顯示路徑:\n");
for(i=0;i<M;i++)
{
for(j=0;j<M;j++)
{
if(maze[i][j] == 2) //當值為2時是牆壁
printf("◾");
else if(maze[i][j] == 1) //當值為1時是路徑
printf("🔷");
else
printf(" ");
}
printf("\n");
}
}
輸出:
顯示迷宮:
◾◾◾◾◾◾◾
◾ ◾
◾ ◾ ◾ ◾
◾ ◾ ◾◾
◾◾ ◾ ◾◾
◾ ◾
◾◾◾◾◾◾◾
顯示路徑:
◾◾◾◾◾◾◾
◾🔷 ◾
◾🔷◾ ◾ ◾
◾🔷🔷◾ ◾◾
◾◾🔷◾ ◾◾
◾ 🔷🔷🔷🔷◾
◾◾◾◾◾◾◾
以上是老鼠走迷宮問題的單個解決方法,迷宮未必只有一條路可以走。那么求多條路會不會很麻煩呢?
當然不會,只要單一路徑解決了,多條路解決方案無非就是在單一路徑稍作修改,對可行路徑進行遍歷就可以了。
下面是全部代碼:
#include <stdio.h>
#include <stdlib.h>
#define M 9
//把迷宮加大成9*9格局
int maze[M][M] =
{
{2,2,2,2,2,2,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,0,2,2,0,2,2,0,2},
{2,0,2,0,0,2,0,0,2},
{2,0,2,0,2,0,2,0,2},
{2,0,0,0,0,0,2,0,2},
{2,2,0,2,2,0,2,2,2},
{2,0,0,0,0,0,0,0,2},
{2,2,2,2,2,2,2,2,2}
};
int start1=1,start2=1; //假定[1][1]是入口
int end1=7,end2=7; //假定[7][7]是出口
void visit(int i,int j)
{
int m,n;
maze[i][j] = 1;
if(i==end1 && j==end2) //判斷是否到達[5][5]出口位置,到達直接輸出
{
printf("\n顯示路徑:\n");
for(m=0;m<M;m++)
{
for(n=0;n<M;n++)
{
if(maze[m][n] == 2)
printf("◾");
else if(maze[m][n] == 1)
printf("🔷");
else
printf(" ");
}
printf("\n");
}
}
//不再判定是否到達出口,只分析老鼠可以在迷宮移動的方向,並遞歸求下一步.
if(maze[i][j+1] == 0)
visit(i,j+1);
if(maze[i+1][j] == 0)
visit(i+1,j);
if(maze[i][j-1] == 0)
visit(i,j-1);
if(maze[i-1][j] == 0)
visit(i-1,j);
//若代碼運行到這一步,則證明前面走的路徑並不能到達出口,則返回,把走過的位置重新寫作0
maze[i][j] = 0;
}
int main ()
{
int i,j;
printf("顯示迷宮:\n");
for(i=0;i<M;i++) //對擺放的數組迷宮進行打印
{
for(j=0;j<M;j++)
if(maze[i][j] == 2)
printf("◾");
else
printf(" ");
printf("\n");
}
visit(start1,start2); //直接調用visit函數,把輸出內容放在visit函數中,好讓所有路徑進行遍歷
return 0;
}
老鼠走迷宮的算法是不是挺有意思呢?有能力的話還可以把老鼠走迷宮擴展成一個可以控制方向小游戲。