不建議使用,可以參考
單片機源程序如下:
- #include "Maze.h"
- /*********************************************************************************************************
- 全局變量定義
- *********************************************************************************************************/
- static uint8 GucXStart = 0; /* 起點橫坐標 */
- static uint8 GucYStart = 0; /* 起點縱坐標 */
- static uint8 GucXGoal0 = XDST0; /* 終點X坐標,有兩個值 */
- static uint8 GucXGoal1 = XDST1;
- static uint8 GucYGoal0 = YDST0; /* 終點Y坐標,有兩個值 */
- static uint8 GucYGoal1 = YDST1;
- static uint8 GucMouseTask = WAIT; /* 狀態機,初始狀態為等待 */
- static uint8 GucMapStep[MAZETYPE][MAZETYPE] = {0xff}; /* 保存各坐標的等高值 */
- static MAZECOOR GmcStack[MAZETYPE * MAZETYPE] = {0}; /* 在mapStepEdit()中作堆棧使用 */
- static MAZECOOR GmcCrossway[MAZETYPE * MAZETYPE] = {0}; /* Main()中暫存未走過支路坐標() */
- //用戶自定義變量
- /*********************************************************************************************************
- ** Function name: Delay
- ** Descriptions: 延時函數
- ** input parameters: uiD :延時參數,值越大,延時越久
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void delay (uint32 uiD)
- {
- for (; uiD; uiD--);
- }
- /*********************************************************************************************************
- ** Function name: mapStepEdit
- ** Descriptions: 制作以目標點為起點的等高圖
- ** input parameters: uiX: 目的地橫坐標
- ** uiY: 目的地縱坐標
- ** output parameters: GucMapStep[][]: 各坐標上的等高值
- ** Returned value: 無
- *********************************************************************************************************/
- void mapStepEdit (int8 cX, int8 cY)
- {
- uint8 n = 0; /* GmcStack[]下標 */
- uint8 ucStep = 1; /* 等高值 */
- uint8 ucStat = 0; /* 統計可前進的方向數 */
- uint8 i,j;
-
- GmcStack[n].cX = cX; /* 起點X值入棧 */
- GmcStack[n].cY = cY; /* 起點Y值入棧 */
- n++;
- /*
- * 初始化各坐標等高值
- */
- for (i = 0; i < MAZETYPE; i++) {
- for (j = 0; j < MAZETYPE; j++) {
- GucMapStep[i][j] = 0xff;
- }
- }
- /*
- * 制作等高圖,直到堆棧中所有數據處理完畢
- */
- while (n) {
- GucMapStep[cX][cY] = ucStep++; /* 填入等高值 */
- /*
- * 對當前坐標格里可前進的方向統計
- */
- ucStat = 0;
- if ((GucMapBlock[cX][cY] & 0x01) && /* 前方有路 */
- (GucMapStep[cX][cY + 1] > (ucStep))) { /* 前方等高值大于計劃設定值 */
- ucStat++; /* 可前進方向數加1 */
- }
- if ((GucMapBlock[cX][cY] & 0x02) && /* 右方有路 */
- (GucMapStep[cX + 1][cY] > (ucStep))) { /* 右方等高值大于計劃設定值 */
- ucStat++; /* 可前進方向數加1 */
- }
- if ((GucMapBlock[cX][cY] & 0x04) &&
- (GucMapStep[cX][cY - 1] > (ucStep))) {
- ucStat++; /* 可前進方向數加1 */
- }
- if ((GucMapBlock[cX][cY] & 0x08) &&
- (GucMapStep[cX - 1][cY] > (ucStep))) {
- ucStat++; /* 可前進方向數加1 */
- }
- /*
- * 沒有可前進的方向,則跳轉到最近保存的分支點
- * 否則任選一可前進方向前進
- */
- if (ucStat == 0) {
- n--;
- cX = GmcStack[n].cX;
- cY = GmcStack[n].cY;
- ucStep = GucMapStep[cX][cY];
- } else {
- if (ucStat > 1) { /* 有多個可前進方向,保存坐標 */
- GmcStack[n].cX = cX; /* 橫坐標X值入棧 */
- GmcStack[n].cY = cY; /* 縱坐標Y值入棧 */
- n++;
- }
- /*
- * 任意選擇一條可前進的方向前進
- */
- if ((GucMapBlock[cX][cY] & 0x01) && /* 上方有路 */
- (GucMapStep[cX][cY + 1] > (ucStep))) { /* 上方等高值大于計劃設定值 */
- cY++; /* 修改坐標 */
- continue;
- }
- if ((GucMapBlock[cX][cY] & 0x02) && /* 右方有路 */
- (GucMapStep[cX + 1][cY] > (ucStep))) { /* 右方等高值大于計劃設定值 */
- cX++; /* 修改坐標 */
- continue;
- }
- if ((GucMapBlock[cX][cY] & 0x04) && /* 下方有路 */
- (GucMapStep[cX][cY - 1] > (ucStep))) { /* 下方等高值大于計劃設定值 */
- cY--; /* 修改坐標 */
- continue;
- }
- if ((GucMapBlock[cX][cY] & 0x08) && /* 左方有路 */
- (GucMapStep[cX - 1][cY] > (ucStep))) { /* 左方等高值大于計劃設定值 */
- cX--; /* 修改坐標 */
- continue;
- }
- }
- }
- }
- /*********************************************************************************************************
- ** Function name: mouseSpurt
- ** Descriptions: 電腦鼠從起點以最短路徑跑向終點
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void mouseSpurt (void)
- {
- uint8 ucTemp = 0xff;
- int8 cXdst = 0, cYdst = 0;
- /*
- * 對終點的四個坐標分別制作等高圖
- * 取離起點最近的一個點作為目標點
- */
- if (GucMapBlock[GucXGoal0][GucYGoal0] & 0x0c) { /* 判斷該終點坐標是否有出口 */
- mapStepEdit(GucXGoal0,GucYGoal0); /* 制作等高圖 */
- if (ucTemp > GucMapStep[GucXStart][GucYStart]) { /* 保存離起點最近的坐標 */
- cXdst = GucXGoal0;
- cYdst = GucYGoal0;
- ucTemp = GucMapStep[GucXStart][GucYStart];
- }
- }
- if (GucMapBlock[GucXGoal0][GucYGoal1] & 0x09) { /* 判斷該終點坐標是否有出口 */
- mapStepEdit(GucXGoal0,GucYGoal1); /* 制作等高圖 */
- if (ucTemp > GucMapStep[GucXStart][GucYStart]) { /* 保存離起點最近的坐標 */
- cXdst = GucXGoal0;
- cYdst = GucYGoal1;
- ucTemp = GucMapStep[GucXStart][GucYStart];
- }
- }
- if (GucMapBlock[GucXGoal1][GucYGoal0] & 0x06) { /* 判斷該終點坐標是否有出口 */
- mapStepEdit(GucXGoal1,GucYGoal0); /* 制作等高圖 */
- if (ucTemp > GucMapStep[GucXStart][GucYStart]) { /* 保存離起點最近的坐標 */
- cXdst = GucXGoal1;
- cYdst = GucYGoal0;
- ucTemp = GucMapStep[GucXStart][GucYStart];
- }
- }
- if (GucMapBlock[GucXGoal1][GucYGoal1] & 0x03) { /* 判斷該終點坐標是否有出口 */
- mapStepEdit(GucXGoal1,GucYGoal1); /* 制作等高圖 */
- if (ucTemp > GucMapStep[GucXStart][GucYStart]) { /* 保存離起點最近的坐標 */
- cXdst = GucXGoal1;
- cYdst = GucYGoal1;
- ucTemp = GucMapStep[GucXStart][GucYStart];
- }
- }
- zlg7289Download(1, 0, 1, 1);
- zlg7289Download(1, 1, 1, 1);
- zlg7289Download(1, 2, 1, 2);
- zlg7289Download(1, 3, 1, 3);
- zlg7289Download(1, 4, 1, 4);
- objectGoTo(cXdst,cYdst); /* 運行到指定目標點 */
- }
- /*********************************************************************************************************
- ** Function name: objectGoTo
- ** Descriptions: 使電腦鼠運動到指定坐標
- ** input parameters: cXdst: 目的地的橫坐標
- ** cYdst: 目的地的縱坐標
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void objectGoTo (int8 x, int8 y)
- {
- uint8 ucStep = 1;
- int8 cNBlock = 0, cDirTemp;
- int8 cX,cY;
- cX = GmcMouse.cX;
- cY = GmcMouse.cY;
- mapStepEdit(x,y); /* 制作等高圖 */
- /*
- * 根據等高值向目標點運動,直到達到目的地
- */
- while ((cX != x) || (cY != y)) {
- ucStep = GucMapStep[cX][cY];
- /*
- * 任選一個等高值比當前自身等高值小的方向前進
- */
- if ((GucMapBlock[cX][cY] & 0x01) && /* 上方有路 */
- (GucMapStep[cX][cY + 1] < ucStep)) { /* 上方等高值較小 */
- cDirTemp = UP; /* 記錄方向 */
- if (cDirTemp == GucMouseDir) { /* 優先選擇不需要轉彎的方向 */
- cNBlock++; /* 前進一個方格 */
- cY++;
- continue; /* 跳過本次循環 */
- }
- }
- if ((GucMapBlock[cX][cY] & 0x02) && /* 右方有路 */
- (GucMapStep[cX + 1][cY] < ucStep)) { /* 右方等高值較小 */
- cDirTemp = RIGHT; /* 記錄方向 */
- if (cDirTemp == GucMouseDir) { /* 優先選擇不需要轉彎的方向 */
- cNBlock++; /* 前進一個方格 */
- cX++;
- continue; /* 跳過本次循環 */
- }
- }
- if ((GucMapBlock[cX][cY] & 0x04) && /* 下方有路 */
- (GucMapStep[cX][cY - 1] < ucStep)) { /* 下方等高值較小 */
- cDirTemp = DOWN; /* 記錄方向 */
- if (cDirTemp == GucMouseDir) { /* 優先選擇不需要轉彎的方向 */
- cNBlock++; /* 前進一個方格 */
- cY--;
- continue; /* 跳過本次循環 */
- }
- }
- if ((GucMapBlock[cX][cY] & 0x08) && /* 左方有路 */
- (GucMapStep[cX - 1][cY] < ucStep)) { /* 左方等高值較小 */
- cDirTemp = LEFT; /* 記錄方向 */
- if (cDirTemp == GucMouseDir) { /* 優先選擇不需要轉彎的方向 */
- cNBlock++; /* 前進一個方格 */
- cX--;
- continue; /* 跳過本次循環 */
- }
- }
- cDirTemp = (cDirTemp + 4 - GucMouseDir)%4; /* 計算方向偏移量 */
-
- if (cNBlock) {
- mouseGoahead(cNBlock); /* 前進cNBlock步 */
- }
- cNBlock = 0; /* 任務清零 */
-
- /*
- * 控制電腦鼠轉彎
- */
- switch (cDirTemp) {
- case 1:
- mouseTurnright();
- break;
- case 2:
- mouseTurnback();
- break;
- case 3:
- mouseTurnleft();
- break;
- default:
- break;
- }
- }
- /*
- * 判斷任務是否完成,否則繼續前進
- */
- if (cNBlock) {
- mouseGoahead(cNBlock);
- }
- }
- /*********************************************************************************************************
- ** Function name: mazeBlockDataGet
- ** Descriptions: 根據電腦鼠的相對方向,取出該方向上迷宮格的墻壁資料
- ** input parameters: ucDir: 電腦鼠的相對方向
- ** output parameters: 無
- ** Returned value: GucMapBlock[cX][cY] : 墻壁資料
- *********************************************************************************************************/
- uint8 mazeBlockDataGet (uint8 ucDirTemp)
- {
- int8 cX = 0,cY = 0;
-
- /*
- * 把電腦鼠的相對方向轉換為絕對方向
- */
- switch (ucDirTemp) {
- case MOUSEFRONT:
- ucDirTemp = GucMouseDir;
- break;
- case MOUSELEFT:
- ucDirTemp = (GucMouseDir + 3) % 4;
- break;
- case MOUSERIGHT:
- ucDirTemp = (GucMouseDir + 1) % 4;
- break;
- default:
- break;
- }
-
- /*
- * 根據絕對方向計算該方向上相鄰格的坐標
- */
- switch (ucDirTemp) {
- case 0:
- cX = GmcMouse.cX;
- cY = GmcMouse.cY + 1;
- break;
-
- case 1:
- cX = GmcMouse.cX + 1;
- cY = GmcMouse.cY;
- break;
-
- case 2:
- cX = GmcMouse.cX;
- cY = GmcMouse.cY - 1;
- break;
-
- case 3:
- cX = GmcMouse.cX - 1;
- cY = GmcMouse.cY;
- break;
-
- default:
- break;
- }
-
- return(GucMapBlock[cX][cY]); /* 返回迷宮格上的資料 */
- }
- /*********************************************************************************************************
- ** Function name: rightMethod
- ** Descriptions: 右手法則,優先向右前進
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void rightMethod (void)
- {
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_R) && /* 電腦鼠的右邊有路 */
- (mazeBlockDataGet(MOUSERIGHT) == 0x00)) { /* 電腦鼠的右邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnright(); /* 電腦鼠右轉 */
- return;
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_F) && /* 電腦鼠的前方有路 */
- (mazeBlockDataGet(MOUSEFRONT) == 0x00)) { /* 電腦鼠的前方沒有走過 */
- return; /* 電腦鼠不用轉彎 */
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_L) && /* 電腦鼠的左邊有路 */
- (mazeBlockDataGet(MOUSELEFT ) == 0x00)) { /* 電腦鼠的左邊沒有走過 */
- // delay(20000);
- // delay(10000);
- mouseTurnleft(); /* 電腦鼠左轉 */
- return;
- }
- }
- /*********************************************************************************************************
- ** Function name: leftMethod
- ** Descriptions: 左手法則,優先向左運動
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void leftMethod (void)
- {
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_L) && /* 電腦鼠的左邊有路 */
- (mazeBlockDataGet(MOUSELEFT ) == 0x00)) { /* 電腦鼠的左邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnleft(); /* 電腦鼠左轉 */
- return;
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_F) && /* 電腦鼠的前方有路 */
- (mazeBlockDataGet(MOUSEFRONT) == 0x00)) { /* 電腦鼠的前方沒有走過 */
- return; /* 電腦鼠不用轉彎 */
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_R) && /* 電腦鼠的右邊有路 */
- (mazeBlockDataGet(MOUSERIGHT) == 0x00)) { /* 電腦鼠的右邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnright(); /* 電腦鼠右轉 */
- return;
- }
- }
- /*********************************************************************************************************
- ** Function name: frontRightMethod
- ** Descriptions: 中右法則,優先向前運行,其次向右
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void frontRightMethod (void)
- {
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_F) && /* 電腦鼠的前方有路 */
- (mazeBlockDataGet(MOUSEFRONT) == 0x00)) { /* 電腦鼠的前方沒有走過 */
- return; /* 電腦鼠不用轉彎 */
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_R) && /* 電腦鼠的右邊有路 */
- (mazeBlockDataGet(MOUSERIGHT) == 0x00)) { /* 電腦鼠的右邊沒有走過 */
- //delay(20000);
- //delay(10000);
- mouseTurnright(); /* 電腦鼠右轉 */
- return;
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_L) && /* 電腦鼠的左邊有路 */
- (mazeBlockDataGet(MOUSELEFT ) == 0x00)) { /* 電腦鼠的左邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnleft(); /* 電腦鼠左轉 */
- return;
- }
- }
- /*********************************************************************************************************
- ** Function name: frontLeftMethod
- ** Descriptions: 中左法則,優先向前運行,其次向左
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void frontLeftMethod (void)
- {
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_F) && /* 電腦鼠的前方有路 */
- (mazeBlockDataGet(MOUSEFRONT) == 0x00)) { /* 電腦鼠的前方沒有走過 */
- return; /* 電腦鼠不用轉彎 */
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_L) && /* 電腦鼠的左邊有路 */
- (mazeBlockDataGet(MOUSELEFT ) == 0x00)) { /* 電腦鼠的左邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnleft(); /* 電腦鼠左轉 */
- return;
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_R) && /* 電腦鼠的右邊有路 */
- (mazeBlockDataGet(MOUSERIGHT) == 0x00)) { /* 電腦鼠的右邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnright(); /* 電腦鼠右轉 */
- return;
- }
- }
- /*********************************************************************************************************
- ** Function name: centralMethod
- ** Descriptions: 中心法則,根據電腦鼠目前在迷宮中所處的位置覺定使用何種搜索法則
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void centralMethod (void)
- {
- if (!(GmcMouse.cX & 0x08)) {
- if (!(GmcMouse.cY & 0x08)) {
-
- /*
- * 此時電腦鼠在迷宮的左下角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- default:
- break;
- }
- } else {
-
- /*
- * 此時電腦鼠在迷宮的左上角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- default:
- break;
- }
- }
- } else {
- if (!(GmcMouse.cY & 0x08)) {
-
- /*
- * 此時電腦鼠在迷宮的右下角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- default:
- break;
- }
-
- } else {
- /*
- * 此時電腦鼠在迷宮的右上角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- default:
- break;
- }
- }
- }
- }
- //搜索返回的法則
- void mazeBackChoice()
- {
- if (!(GmcMouse.cX & 0x08)) {
- if (!(GmcMouse.cY & 0x08)) {
-
- /*
- * 此時電腦鼠在迷宮的左下角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- default:
- break;
- }
- } else {
-
- /*
- * 此時電腦鼠在迷宮的左上角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- default:
- break;
- }
- }
- } else {
- if (!(GmcMouse.cY & 0x08)) {
-
- /*
- * 此時電腦鼠在迷宮的右下角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- default:
- break;
- }
-
- } else {
- /*
- * 此時電腦鼠在迷宮的右上角
- */
- switch (GucMouseDir) {
-
- case UP: /* 當前電腦鼠向上 */
- // delay(20000);
- leftMethod(); /* 左手法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- // delay(20000);
- rightMethod(); /* 右手法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- // delay(20000);
- frontRightMethod(); /* 中右法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- // delay(20000);
- frontLeftMethod(); /* 中左法則 */
- break;
- default:
- break;
- }
- }
- }
- }
- /*********************************************************************************************************
- ** Function name: crosswayCheck
- ** Descriptions: 統計某坐標存在還未走過的支路數
- ** input parameters: ucX,需要檢測點的橫坐標
- ** ucY,需要檢測點的縱坐標
- ** output parameters: 無
- ** Returned value: ucCt,未走過的支路數
- *********************************************************************************************************/
- uint8 crosswayCheck (int8 cX, int8 cY)
- {
- uint8 ucCt = 0;
- if ((GucMapBlock[cX][cY] & 0x01) && /* 絕對方向,迷宮上方有路 */
- (GucMapBlock[cX][cY + 1]) == 0x00) { /* 絕對方向,迷宮上方未走過 */
- ucCt++; /* 可前進方向數加1 */
- }
- if ((GucMapBlock[cX][cY] & 0x02) && /* 絕對方向,迷宮右方有路 */
- (GucMapBlock[cX + 1][cY]) == 0x00) { /* 絕對方向,迷宮右方沒有走過 */
- ucCt++; /* 可前進方向數加1 */
- }
- if ((GucMapBlock[cX][cY] & 0x04) && /* 絕對方向,迷宮下方有路 */
- (GucMapBlock[cX][cY - 1]) == 0x00) { /* 絕對方向,迷宮下方未走過 */
- ucCt++; /* 可前進方向數加1 */
- }
- if ((GucMapBlock[cX][cY] & 0x08) && /* 絕對方向,迷宮左方有路 */
- (GucMapBlock[cX - 1][cY]) == 0x00) { /* 絕對方向,迷宮左方未走過 */
- ucCt++; /* 可前進方向數加1 */
- }
- return ucCt;
- }
- /*********************************************************************************************************
- ** Function name: crosswayChoice
- ** Descriptions: 選擇一條支路作為前進方向
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void crosswayChoice (void)
- {
- switch (SEARCHMETHOD) {
-
- case RIGHTMETHOD:
- rightMethod();
- break;
-
- case LEFTMETHOD:
- leftMethod();
- break;
-
- case CENTRALMETHOD:
- centralMethod();
- break;
- case FRONTRIGHTMETHOD:
- frontRightMethod();
- break;
- case FRONTLEFTMETHOD:
- frontLeftMethod();
- break;
- default:
- break;
- }
- }
- /*********************************************************************************************************
- ** Function name: StopMazeSearch
- ** Descriptions: 停止向前搜索的函數
- ** input parameters: 當前的坐標
- ** output parameters: 無
- ** Returned value: 0代表結束,1代表繼續
- *********************************************************************************************************/
- int8 StopMazeSearch(int8 cX,int8 cY)
- {
- if(cX==7 && cY==7)
- return 1;
- if(cX==8 && cY==7)
- return 1;
- if(cX==7 && cY==8)
- return 1;
- if(cX==8 && cY==8)
- return 1;
- return 0;
- }
- /*********************************************************************************************************
- ** Function name: FastOperating
- ** Descriptions: 對特殊格子處理的函數
- ** input parameters: 當前的坐標
- ** output parameters: 無
- ** Returned value: 1表示前方,2表示右方,3表示后方,4表示左方
- *********************************************************************************************************/
- int8 FastOperating(int8 cX,int8 cY)
- {
- if(cX==5 && cY==7){
- if(GucMapBlock[cX][cY] & 0x02)
- return 2;
- }
- if(cX==5 && cY==8){
- if(GucMapBlock[cX][cY] & 0x02)
- return 2;
- }
-
- if(cX==6 && cY==7){
- if(GucMapBlock[cX][cY] & 0x02)
- return 2;
- }
- if(cX==6 && cY==8){
- if(GucMapBlock[cX][cY] & 0x02)
- return 2;
- }
-
- if(cX==7 && cY==5){
- if(GucMapBlock[cX][cY] & 0x01)
- return 1;
- }
- if(cX==8 && cY==5){
- if(GucMapBlock[cX][cY] & 0x01)
- return 1;
- }
- if(cX==7 && cY==6){
- if(GucMapBlock[cX][cY] & 0x01)
- return 1;
- }
- if(cX==8 && cY==6){
- if(GucMapBlock[cX][cY] & 0x01)
- return 1;
- }
-
- if(cX==10 && cY==7){
- if(GucMapBlock[cX][cY] & 0x08)
- return 4;
- }
- if(cX==10 && cY==8){
- if(GucMapBlock[cX][cY] & 0x08)
- return 4;
- }
- if(cX==9 && cY==7){
- if(GucMapBlock[cX][cY] & 0x08)
- return 4;
- }
- if(cX==9 && cY==8){
- if(GucMapBlock[cX][cY] & 0x08)
- return 4;
- }
-
- if(cX==8 && cY==10){
- if(GucMapBlock[cX][cY] & 0x04)
- return 3;
- }
- if(cX==7 && cY==10){
- if(GucMapBlock[cX][cY] & 0x04)
- return 3;
- }
- if(cX==8 && cY==9){
- if(GucMapBlock[cX][cY] & 0x04)
- return 3;
- }
- if(cX==7 && cY==9){
- if(GucMapBlock[cX][cY] & 0x04)
- return 3;
- }
- return 0;
- }
- /*********************************************************************************************************
- ** Function name: piontMethod
- ** Descriptions: 向點法則,電腦鼠從終點找起點
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- void piontMethod(void)
- {
- switch(GucMouseDir)
- {
- case UP:
- leftMethod();
- break;
- case RIGHT:
- rightMethod();
- break;
- case DOWN:
- frontRightMethod();
- break;
- case LEFT:
- frontLeftMethod();
- break;
- default:
- break;
- }
- }
- /*********************************************************************************************************
- ** Function name: StopMazeSearch
- ** Descriptions: 停止向前搜索的函數
- ** input parameters: 當前的坐標
- ** output parameters: 無
- ** Returned value: 0代表結束,1代表繼續
- *********************************************************************************************************/
- int8 StopSearch(int8 cX,int8 cY,int8 n)
- {
- int8 i;
- for(i=0;i<n;i++){
- if(GmcCrossway[i].cX == cX && GmcCrossway[i].cY == cY){
- return 1;
- }
- }
- if(cX==7 && cY==7)
- return 1;
- if(cX==8 && cY==7)
- return 1;
- if(cX==7 && cY==8)
- return 1;
- if(cX==8 && cY==8)
- return 1;
- return 0;
- }
- /*********************************************************************************************************
- ** Function name: main
- ** Descriptions: 主函數
- ** input parameters: 無
- ** output parameters: 無
- ** Returned value: 無
- *********************************************************************************************************/
- main (void)
- {
- uint8 n = 0; /* GmcCrossway[]下標 */
- uint8 ucRoadStat = 0; /* 統計某一坐標可前進的支路數 */
- uint8 ucTemp = 0; /* 用于START狀態中坐標轉換 */
-
- //用戶自定義變量
- int8 cXdst = 0, cYdst = 0;
-
- mouseInit(); /* 底層驅動的初始化 */
- zlg7289Init(); /* 顯示模塊初始化 */
- while (1) {
- switch (GucMouseTask) { /* 狀態機處理 */
-
- case WAIT:
- sensorDebug();
- voltageDetect();
- delay(100000);
- if (keyCheck() == true) { /* 檢測按鍵等待啟動 */
- zlg7289Reset(); /* 復位ZLG7289 */
- GucMouseTask = START;
- }
- break;
-
- case START: /* 判斷電腦鼠起點的橫坐標 */
- mazeSearch(); /* 向前搜索 */
- if (GucMapBlock[GmcMouse.cX][GmcMouse.cY] & 0x08) { /* 判斷電老鼠左邊是否存在出口 */
- if (MAZETYPE == 8) { /* 修改四分之一迷宮的終點坐標 */
- GucXGoal0 = 1;
- GucXGoal1 = 0;
- }
- GucXStart = MAZETYPE - 1; /* 修改電腦鼠起點的橫坐標 */
- GmcMouse.cX = MAZETYPE - 1; /* 修改電腦鼠當前位置的橫坐標 */
- /*
- * 由于默認的起點為(0,0),現在需要把已記錄的墻壁資料轉換過來
- */
- ucTemp = GmcMouse.cY;
- do {
- GucMapBlock[MAZETYPE - 1][ucTemp] = GucMapBlock[0][ucTemp];
- GucMapBlock[0 ][ucTemp] = 0;
- }while (ucTemp--);
- /*
- * 在OFFSHOOT[0]中保存起點坐標
- */
- GmcCrossway[n].cX = MAZETYPE - 1;
- GmcCrossway[n].cY = 0;
- n++;
- GucMouseTask = MAZESEARCH; /* 狀態轉換為搜尋狀態 */
- }
- if (GucMapBlock[GmcMouse.cX][GmcMouse.cY] & 0x02) { /* 判斷電老鼠右邊是否存在出口 */
- /*
- * 在OFFSHOOT[0]中保存起點坐標
- */
- GmcCrossway[n].cX = 0;
- GmcCrossway[n].cY = 0;
- n++;
- GucMouseTask = MAZESEARCH; /* 狀態轉換為搜尋狀態 */
- }
- break;
-
- case MAZESEARCH:
- //從起點搜索找終點
- if(StopMazeSearch(GmcMouse.cX,GmcMouse.cY)==1){
- cXdst=GmcMouse.cX,cYdst=GmcMouse.cY;
- mouseTurnback();
- GucMouseTask = BACKSEARCH;
- n--;
- objectGoTo(GmcCrossway[n].cX,GmcCrossway[n].cY);
- break;
- }
- ucRoadStat = crosswayCheck(GmcMouse.cX,GmcMouse.cY);
- if (ucRoadStat) { /* 有可前進方向 */
- if (ucRoadStat > 1) { /* 有多條可前進方向,保存坐標 */
- GmcCrossway[n].cX = GmcMouse.cX;
- GmcCrossway[n].cY = GmcMouse.cY;
- n++;
- }
- switch(FastOperating(GmcMouse.cX,GmcMouse.cY)){
- case 0:
- centralMethod();
- mazeSearch();
- break;
- case 1:
- objectGoTo(GmcMouse.cX,GmcMouse.cY+1);
- // mazeSearch();
- break;
- case 2:
- objectGoTo(GmcMouse.cX+1,GmcMouse.cY);
- // mazeSearch();
- break;
- case 3:
- objectGoTo(GmcMouse.cX,GmcMouse.cY-1);
- // mazeSearch();
- break;
- case 4:
- objectGoTo(GmcMouse.cX-1,GmcMouse.cY);
- // mazeSearch();
- break;
- default:
- break;
- }
- }else{ /* 沒有可前進方向,回到最近支路*/
- while (--n) {
- ucRoadStat = crosswayCheck(GmcCrossway[n].cX,GmcCrossway[n].cY);
- if (ucRoadStat) {
- objectGoTo(GmcCrossway[n].cX,GmcCrossway[n].cY);
- if (ucRoadStat > 1) {
- n++;
- }
- centralMethod();
- mazeSearch();
- break;
- }
-
- }
- if (n == 0){ /* 走完了所有的支路,回到起點 */
- objectGoTo(GmcCrossway[0].cX, GmcCrossway[0].cY);
- mouseTurnback();
- //異常處理那種死迷宮(即根本走不出去的迷宮)
- if(GmcMouse.cX==GucXStart && GmcMouse.cY==GucYStart){
- while(1){
- if(keyCheck()==true){
- break;
- }
- sensorDebug();
- delay(20000);
- }
- }
- }
- }
- break;
- case BACKSEARCH:
- //從終點搜索找起點
- /* while(1){
- if(keyCheck()==true){
- break;
- }
- sensorDebug();
- delay(20000);
- }*/
- ucRoadStat = crosswayCheck(GmcMouse.cX,GmcMouse.cY);
- if (ucRoadStat) { /* 有可前進方向 */
- if (ucRoadStat > 1) { /* 有多條可前進方向,保存坐標 */
- GmcCrossway[n].cX = GmcMouse.cX;
- GmcCrossway[n].cY = GmcMouse.cY;
- n++;
- }
- piontMethod(); //設定為向點法則
- mazeSearch(); // 前進一格
- }else{ /* 沒有可前進方向,回到最近支路*/
- while (--n) {
- if(GmcMouse.cX==0 && GmcMouse.cY==0){
- mouseTurnback();
- GucMouseTask=SPURT;
- break;
- }
- ucRoadStat = crosswayCheck(GmcCrossway[n].cX,GmcCrossway[n].cY);
- if(ucRoadStat) {
- objectGoTo(GmcCrossway[n].cX,GmcCrossway[n].cY);
- if (ucRoadStat > 1) {
- n++;
- }
- piontMethod();
- mazeSearch();
- break;
- }
- if(n==0){
- GucMouseTask=SPURT;
- break;
- }
- }
- }
- break;
- case SPURT:
- // mouseSpurt ();
- objectGoTo(cXdst,cYdst);
- n--;
- objectGoTo(GmcCrossway[n].cX, GmcCrossway[n].cY);
- GucMouseTask = BACKSEARCH;
- break;
- default:
- break;
- }
- }
- }
- /*********************************************************************************************************
- END FILE
- *********************************************************************************************************/
- /*********************************************************************************************************
- ** Function name: piontMethod
- ** Descriptions: 向點法則,電腦鼠從終點找起點
- ** input parameters: 無
- ** output parameters: GmcMouse.cX,GmcMouse.cY
- ** Returned value: 無
- *********************************************************************************************************/
- void piontMethod(int8 cX,int8 cY)
- {
- if (!(GmcMouse.cX & 0x08))
- {
- if (!(GmcMouse.cY & 0x08))
- {
- /*
- * 此時電腦鼠在迷宮的左下角
- */
- switch (GucMouseDir)
- {
-
- case UP: /* 當前電腦鼠向上 */
- LeftMethod(); /* 左手法則 */
- break;
- case RIGHT: /* 當前電腦鼠向右 */
- RightMethod(); /* 右手法則 */
- break;
- case DOWN: /* 當前電腦鼠向下 */
- frontRightMethod(); /* 中右手法則 */
- break;
- case LEFT: /* 當前電腦鼠向左 */
- frontLeftMethod(); /* 中左手法則 */
- break;
- default:
- break;
- }
- }
- }
- else
- {
-
- frontLeftMethod(); /* 中左法則 */
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_F) && /* 電腦鼠的前方有路 */
- (mazeBlockDataGet(MOUSEFRONT) == 0x00)) { /* 電腦鼠的前方沒有走過 */
- return; /* 電腦鼠不用轉彎 */
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_L) && /* 電腦鼠的左邊有路 */
- (mazeBlockDataGet(MOUSELEFT ) == 0x00)) { /* 電腦鼠的左邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnleft(); /* 電腦鼠左轉 */
- return;
- }
- if ((GucMapBlock[GmcMouse.cX][GmcMouse.cY] & MOUSEWAY_R) && /* 電腦鼠的右邊有路 */
- (mazeBlockDataGet(MOUSERIGHT) == 0x00)) { /* 電腦鼠的右邊沒有走過 */
- //delay(20000);
- // delay(10000);
- mouseTurnright(); /* 電腦鼠右轉 */
- return;
- }
- }
- }
復制代碼
所有資料51hei提供下載:
.rar
(198.73 KB, 下載次數: 18)
2018-11-2 13:20 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|