2005-11-23, 04:25 PM | #1 |
管理版主
|
程式 - 高智慧 老鼠走迷宮Ver1.0
設計原理
圖解說明 老鼠可只放任一隻或兩隻在場上比賽 VB原始程式碼 + 已編譯.exe檔 + 三個範例地圖檔 + 解說 http://d.turboupload.com/d/167775/Mouse.rar.html new download: http://www.funp.net/9091186 完成度 95% 在走入甜甜圈單一出口路徑下 可能會鬧便扭 這一點是可以改進的地方 另外 [路線圖] 功能未完成 有興趣的同好可以試試完成之 (有需要解說的地方請於此帖發問) 簡言之只要參考 .FlagX(X).FlagY(Y) 紀錄 應該不難寫出 最後 程式還有一點例外處理沒盡善 比如地圖檔出現規則外的字元 所以還請見諒 此帖於 2008-03-04 03:57 PM 被 mini 編輯. |
送花文章: 2013,
|
有 2 位會員向 mini 送花:
|
2005-11-29, 01:55 AM | #4 (permalink) |
註冊會員
|
我可以先問問題嗎??...煩請大大指點嚕!!!
Dim strMapFile As String 這是把地圖的檔案名稱用字串定義嗎??? Private Sub ExitCommand_Click() End End Sub 這個物件事直接執行還是說由按鈕來控制 Call MeCaptionIs mecaption是代表什麼意思呢??? NumbersOnly SpeedText NumbersOnly TimeText Maze_Initial Dir(App.Path + "\" + "MAP*.txt"), MapPicture Call Initial 上述兩行看不懂 |
送花文章: 112,
|
2005-11-29, 09:12 AM | #5 (permalink) |
管理版主
|
Dim strMapFile As String
A:這是把地圖的檔案名稱用字串定義嗎??? Q:對呀,因為按重置後不能再用 Dir(App.Path + "\" + "MAP*.txt") 這個方式得到 地圖的檔案名稱,所以要把目前的 地圖檔名 用這個字串變數記錄起來 Private Sub ExitCommand_Click() End End Sub Q:這個物件事直接執行還是說由按鈕來控制 A:按鈕,這是 [離開] 按鈕的 Click(點擊) 事件, End 是保留字 (以下是 MSDN中文版的解釋) End 陳述式可以強制程式碼終止,無須經過 Unload、QueryUnload,或 Terminate 事件,或任何其它的 Visual Basic 程式碼。Unload、QueryUnload,表單與物件類別模組的 Terminate 事件都不會執行。由物件類別模組所建立的物件會被破壞、以 Open 陳述式開啟的檔案會被關閉,程式所佔用的記憶體空間也會被釋放。 End 陳述式是一種強制程式停止執行的方式。一般要結束 Visual Basic 程式前,都必須先載出所有表單,確定沒有其它程式引用到其中的物件,且沒有執行中的程式碼,才能結束。 Call MeCaptionIs A:mecaption是代表什麼意思呢??? Q:搜尋 MeCaptionIs 副程式可看到 '顯示版本 語法:
Private Sub MeCaptionIs() 'App.Major + App.Minor + App.Revision '主、次、修訂 Me.Caption = "老鼠走迷宮 Ver" + CStr(App.Major) + "." + CStr(App.Minor) If App.Revision <> 0 Then Me.Caption = Me.Caption + "." + CStr(App.Revision) End Sub Maze_Initial 是地圖處理副程式 Initial 是數據處理副程式 '初始 的意思 Private Sub Initial() ... Dir(App.Path + "\" + "MAP*.txt") 是 在應用程式下 用 "MAP*.txt" 為搜尋條件 (就像是DOS打 dir map*.txt),會傳回第一個符合條件的字串,都沒有的話會回傳 "" 空字串 MapPicture 是 PictureBox 物件,表示將地圖數據畫在這上面 經驗談: 欲解析他人的程式 請善用 搜尋 如副程式內容過於零亂 那建議不要深究 (除非想了解那段副程式使用到的技巧) 欲學好 MS 出版的 VC++、VB、... 可以用 emule 下一套 MSDN中文版 來用用 比如對 End 點兩下按 F1 鍵,就會出現該解釋及用法 如查無此字,就表示他是一個 windows api 或 自制副程式 新版 v1.0.3 http://d.turboupload.com/d/178219/Mouse.rar.html Ver 1.0.4 .針對 迷宮初始 之運算 做效能提升 http://d.turboupload.com/d/178354/MazeModule.bas.html (請取代原 MazeModule.bas ※需重新編譯) 這個創作其實有個弱點 就是 當能走的方向都已走過(旗標皆為1)時 用 "亂數決定方向" 之方法 會使 老鼠產生猶豫不定的現象 這點有待解決... 不過老鼠是一定能走到終點(不會陷入永久迴圈),因此相較其他 老鼠走迷宮 之構思 還算是比較好的方法 |
送花文章: 2013,
|
2005-12-03, 10:05 PM | #6 (permalink) |
註冊會員
|
大大請問一下喔!!!
If RectBrick.W > RectBrick.H Then SpeedText.Text = Int(RectBrick.H / 3) Else SpeedText.Text = Int(RectBrick.W / 3) End If 這個我看不懂 .OldMapX = 0 .OldMapY = 0 ReDim .FlagX(.OldMapX + 1) Shape(Index).Top = 600 If Index = 1 Then LeftIs = 240 ElseIf Index = 2 Then LeftIs = 720 上述那些600、240、720各代表啥意思呢?? strMapFile = CommonDialog_Click(Me) strMapFile = StringSplit_Str(strMapFile, "1\0$.txt", 1) 這些我也看不懂..... 我就先問這些好了!!!... |
送花文章: 112,
|
2005-12-04, 09:31 AM | #7 (permalink) |
管理版主
|
If RectBrick.W > RectBrick.H Then
SpeedText.Text = Int(RectBrick.H / 3) Else SpeedText.Text = Int(RectBrick.W / 3) End If 因為磚塊大多情況是長方形 (分 RectBrick.W 與 RectBrick.H) 而一步移動距離(SpeedText.Text)是不分長寬的 所以就取最短的一邊 (RectBrick.W與 RectBrick.H 比較) 給 SpeedText.Text 為了使移動時 不移動過頭 (到磚塊裡) Q:上述那些600、240、720各代表啥意思呢?? A:只是個老鼠(Shape(Index) )於休息室位址的定位 (水平位址 Shape(Index).Left ) strMapFile = CommonDialog_Click(Me) 是呼叫WinAPI的 對話框 來賦予地圖檔名 這裡捨棄 VB提供的 CommonDialog控制項 元件,目的是如此就不需考慮該PC有無 comdlg32.ocx (VB的插件) 您可以在這三行設下中斷點 strMapFile = CommonDialog_Click(Me) strMapFile = StringSplit_Str(strMapFile, "1\0$.txt", 1) If strMapFile = "" Then strMapFile = Dir(App.Path + "\" + "MAP*.txt") 來體會 strMapFile = CommonDialog_Click(Me) strMapFile = StringSplit_Str(strMapFile, "1\0$.txt", 1) 的作用 ( 其實照理講 strMapFile = StringSplit_Str(strMapFile, "1\0$.txt", 1) 是多此一舉 但因為 CommonDialog_Click(Me)設計的關係 會傳回一個 257字元長度的字串 ※ 原因在CommonDialog_Click含式的 OpenFile.lpstrFile = String(257, 0) 這一行 所以利用 strMapFile = StringSplit_Str(strMapFile, "1\0$.txt", 1) 來捨去 .txt 以後的 字串 ※ chr(0) 無法用 trim 來捨棄 ) StringSplit_Str是一個自制的字串分割 函數 StringSplit_Str(欲作用的字串, 分割用參數, 傳回第幾分割字串) 其實VB 有一個 Split 保留字 只是他傳回值 是一個陣列變數 會傳回全部子分割字串 (要用第幾個就用( )來指定第幾分割字串,也可 Split(欲作用的字串, 分割用字串)(傳回第幾分割字串) 方式來直接指定 傳回第幾分割字串 但花費時間不變 ) 因此效能不及個人的 StringSplit_Str (有測試過) strMapFile, "1\0$.txt", 1 表示 用 .txt 針對 strMapFile 做對半分割 傳回 前半段+".txt" 字串 (如是 "1\0$.txt", 0 就是取後半段) (1\0$ 後的字串是切割辨識字串) 如果 strMapFile= "c:\temp\Map100.txt %#@%@# " 就會回傳 "c:\temp\Map100.txt" 而 StringSplit_Str 還有其他用法 比如 StringSplit_Str(strMapFile, chr(13)+chr(10), 5) 會傳回第5行字串 (因為 chr(13)+chr(10) 是換行字串,也可用vbCrLf 或 vbNewLine ) 如沒有第5行即傳回 "" 空字串 |
送花文章: 2013,
|
2005-12-23, 10:41 AM | #8 (permalink) |
管理版主
|
Q:Mouse(1).(2)-->代表滑鼠左右鍵嗎??
A:可見到 MouseModule.bas Public Mouse(1 To 2) As Mouse_Data '老鼠資料(結構) Mouse(1)表示為1號老鼠的結構 (資料紀錄) 這裡不是指滑鼠 Q:這兩行我看不懂代表啥意思?? A:是指 Initial 副程式的程式代碼嗎? 同樣首先看到 MouseModule.bas 有解釋 Mouse(i).FlagX(x).FlagY(y) 是一個老鼠心中的 地圖 用來記錄走過的路 redim 沒有用到 Preserve 保留字 就表示重新宣告變數,之前的內容都會被清空 所以 Redim .FlagX(.OldMapX+1) Redim .FlagX(j).FlagY(.OldMapY+1) 是表示老鼠宣告一份新的地圖 這份地圖一開始為 Mouse(老鼠編號).FlagX(x寬度).FlagY(y寬度) 這般大小 那網友一定會說 Q:老鼠怎麼知道目前自己處於 迷宮陣列的(x,y)位址呢? A:基於程式必須提供 一份 矩陣資料結構(來給老鼠指示 哪裡可走) + 老鼠本身知到自己的 .Left .Top 座標 + 所以 可算出來 自己處於 迷宮陣列的(x,y)那個位址 (這就是與現實世界的最大不同) 說起來 "迷宮矩陣資料結構 個人的設計 會透露這個迷宮有多大 給老鼠" 這一點有點作弊的嫌疑 不過因為當初是 邊寫邊作規劃的情況下 (未嚴格限制) 所以就不作多說... 作弊的地方就是... Private Function NotIsNewCoordinate_Range(....) As Boolean With MoveObject '現在所處的地圖 陣列座標 X = Int((OBJ.cx(MoveObject)) / RectBrick.W) + 1 Y = Int((OBJ.cy(MoveObject)) / RectBrick.H) + 1 這裡算出了目前處於 "迷宮陣列的(x,y)那個位址" RectBrick.W 及 RectBrick.H ---->分別代表 迷宮陣列的 最大維度 老鼠應該是不知的才對 不過程式設計原本就有 變數最大值的限制 所以 老鼠知道 迷宮陣列有多大 來準備一份空白地圖 也是合情合理的 (現實世界可比喻成 老鼠的腦容量) 當然要限制老鼠不知 "迷宮陣列的 最大維度" 也可以 此時就要用 鍊結 的方式來設計 不過程式設計難度會變大... (有無其他方法...有空再看看 ) 最後... .FlagX(0).FlagY(0)=UBound(.FlagX) .FlagX(0).FlagY(1)=UBound(.FlagY(1).FlagY) Q: 該不會是把舊的宣告利用UBound來重新宣告嗎?? A: 是的... .FlagX(0).FlagY(0) '紀錄 心中陣列地圖X軸上限 .FlagX(0).FlagY(1) 'Y軸上限 .FlagX(>1).FlagY(>1) '表示 X,Y軸 障礙物等級 |
送花文章: 2013,
|
2005-12-26, 10:53 PM | #11 (permalink) |
管理版主
|
上面都有解說
比如 MazeModule.bas '********************************** '* 作者: mini 模組: 迷宮結構&形式 * '********************************** .bas模組 主要是為了做成 公用(Public)方程式,如此使用會方便點 而且 winapi 的宣告大多也是在.bas模組裡宣告 物件模組 只是一個class的示範 這裡的 OBJClass.cls 是定位成 "個性" 比如 mouse 的中心點座標 OBJ.cx(mouse) , OBJ.cy(mouse) 在這個專案裡 並沒有將class的特性表露出來 class 的特性是動態宣告 將屬性製作出 個性 |
送花文章: 2013,
|
2006-01-02, 06:46 AM | #13 (permalink) |
註冊會員
|
小弟我有問題想請教一下大大
Int(RectBrick.H/3) 那/3是一定要除以三嗎???還是說代表其他意思呢?? if MLineCheck(MouseIndex)=1 Then MapPicture.Line(.OldPosX,.OldPosY)-(OBJ.cx(Shape(MouseIndex)),.OldPosY),Shape(MouseIndex).BlackColor 這句代表啥意思呢? 在來就是 Shape(MouseIndex).ZOrder1 Shape(MouseIndex).Left=480 Shape(MouseIndex).Top=360 這三句第一句我看不懂.... 感謝大大的回答..... 大大寫的程式...小弟我大概都看的懂..除了CommonDialog那邊小弟我不是很懂...學校才提到一點點...至於OBJ.class裡面大概都不是很懂... |
送花文章: 112,
|
2006-01-02, 01:02 PM | #14 (permalink) |
管理版主
|
應該是指 SpeedText.Text = Int(RectBrick.H / 3)
除以3 是為了使移動看起來比較順(個人觀點) 要大一點或小一點都可以 只是不要小於 1 就好了 if MLineCheck(MouseIndex)=1 Then MapPicture.Line(.OldPosX,.OldPosY)-(OBJ.cx(Shape(MouseIndex)),.OldPosY),Shape(MouseIndex).BlackColor 這句代表啥意思呢? A: 用 MLineCheck 核取框決定是否畫出行走的 路跡 Shape(MouseIndex).ZOrder 1 '後到的 排後面 Shape(MouseIndex).Left = 480 Shape(MouseIndex).Top = 360 首先可知 ZOrder 方法如下 語法: object.ZOrder position ZOrder 方法的語法具有下列幾個單元: <object 選擇性引數> 物件運算式, 其值為「適用於」清單中的某個物件。如果省略 object,則假設具有駐點的 Form 物件為 object。 <Position 選擇性引數> 整數, 用以指示 object 相對於同一 object 其它執行個體的位置。如果 position 為 0 或省略,則 object 放置在疊置順序前面。如果 position 為 1,則 object 放置在疊置順序後面。 所以 Shape(MouseIndex).ZOrder 1 就是 後來的 排後面 (先來的排前面) (如果有兩隻老鼠,用來安排 先來後到 誰壓住誰) |
送花文章: 2013,
|