VBA永遠(yuǎn)的神 無所不能VBA能干什么? 其實(shí)除了枯燥的Excel數(shù)據(jù)處理,VBA還能寫幾個(gè)小游戲玩玩,比如我就用純粹的Excel VBA寫了這個(gè)漢諾塔游戲,順便復(fù)習(xí)了一下遞歸算法,游戲支持按鍵選擇和移動(dòng)方塊,也給一直無法解答的同學(xué)準(zhǔn)備了最完整的全自動(dòng)動(dòng)畫解答,超過6層以后還是有一些難度的,可以自己練好了教孩子,本文會(huì)簡(jiǎn)單講解游戲的開發(fā)過程,有興趣用VBA完成的同學(xué)可以參考,案例文件可到文章末尾獲取。 漢諾塔游戲簡(jiǎn)介 漢諾塔(Tower of Hanoi),又稱河內(nèi)塔,是一個(gè)源于印度古老傳說的益智玩具。大梵天創(chuàng)造世界的時(shí)候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規(guī)定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動(dòng)一個(gè)圓盤。 下面就來講解Excel版漢諾塔游戲的開發(fā)過程 漢諾塔游戲規(guī)則設(shè)計(jì)作為一個(gè)游戲,首先要確定游戲元素和制定游戲規(guī)則,一切都要圍繞這個(gè)規(guī)則進(jìn)行 游戲元素 1) 3根石柱,這里我稱之為3個(gè)塔座,分別在Excel里用3個(gè)區(qū)域畫出來,中間和底部單元格設(shè)為藍(lán)黑色背景,作為石柱,他們是固定元素,不需要參與到代碼中 游戲規(guī)則1) 游戲勝利目標(biāo)為左側(cè)圓盤全部移動(dòng)到最右側(cè)圓盤 Excel VBA代碼實(shí)現(xiàn)漢諾塔 游戲初始化要在最左側(cè)生成N個(gè)圓盤,我這里采取的是先預(yù)設(shè)一個(gè)矩形放在右邊空白區(qū),代碼復(fù)制這個(gè)形狀,根據(jù)要生成的個(gè)數(shù),計(jì)算每層的高度和位置,這就是循環(huán)基本功了,代碼如下,具體執(zhí)行的時(shí)候鏈接到重置按鈕 用戶切換選擇按鈕 既然是游戲就要有交互,需要提供給用戶選擇方塊,有同學(xué)肯定說直接用鼠標(biāo)點(diǎn)選,是可以,但是這里有個(gè)問題,因?yàn)槭髽?biāo)點(diǎn)的話,那所有盤子都能點(diǎn),不是頂部的也能點(diǎn)到,邏輯上就不太合理,所以這里采取切換選擇按鈕,在3個(gè)盤子的頂部來回切換選擇,這里的算法稍微復(fù)雜,因?yàn)樵谟螒蜻^程中,每個(gè)柱子區(qū)域頂部是哪個(gè)盤子是不確定的,所以要先計(jì)算頂部的盤子,這里寫了個(gè)遍歷形狀的子函數(shù)來處理,然后切換的時(shí)候就是通過塔座的序號(hào)加減實(shí)現(xiàn) 圓盤移動(dòng)按鈕 選擇了目標(biāo)以后 就是移動(dòng),移動(dòng)這里給了2個(gè)按鈕,左移和右移,移動(dòng)的時(shí)候主要是計(jì)算下一個(gè)塔座的編號(hào),那么就是首先要根據(jù)當(dāng)前選擇的盤子先計(jì)算當(dāng)前塔座編號(hào),左移就是編號(hào)-1,右移就是+1,注意1號(hào)左移要變?yōu)?,3號(hào)右移要變?yōu)?,游戲中要處理很多這種邊界情況 移動(dòng)動(dòng)畫的實(shí)現(xiàn) 上面一步實(shí)際在最開始做的時(shí)候,是沒有動(dòng)畫,只會(huì)看到圓盤咻的一下就到新位置了,作為演示移動(dòng)過程,這個(gè)不太直觀,所以中間我加入了一個(gè)動(dòng)畫處理,所謂動(dòng)畫也沒那么神奇,動(dòng)畫就是計(jì)算出圓盤也就是方塊的移動(dòng)路徑,給一個(gè)循環(huán),按一定的步長(zhǎng),逐步移動(dòng)到新位置,這個(gè)過程連續(xù)起來,人眼看起來就成了一個(gè)移動(dòng)的動(dòng)畫效果,實(shí)現(xiàn)代碼如下 游戲按鍵指定 一般來說,游戲都要支持純鍵盤操作,上面的按鈕操作,都可以指定到按鍵,這里使用Application.OnKey來指定按鍵,只是要記得在close事件里要取消指定按鍵,否則打開別的Excel文件這些按鍵會(huì)無法正常使用了 實(shí)現(xiàn)VBA漢諾塔自動(dòng)解題 前面做的都是游戲本身的交互,那現(xiàn)在開始做比較難的步驟,就是游戲求解,其實(shí)做這個(gè)游戲的初衷,就是為了講解遞歸算法,而漢諾塔就是一個(gè)經(jīng)典的編程算法題,我還記得在大學(xué)的c語言習(xí)題里就有這個(gè)案例,這里解題的重點(diǎn)在于要理解遞歸的構(gòu)造,本題的重點(diǎn)在于抽象出完成目標(biāo)的步驟 首先把目標(biāo)分解為移動(dòng)最下面的第N個(gè)盤子上面N-1個(gè)盤子 1) 首先要移動(dòng)塔座1的N-1個(gè)到塔座2上,他們需要借助塔座3完成 |
|