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