游戲策劃咨訊
          做一個(gè)游戲并不難,難的是做一個(gè)好游戲;完美在于積累!
          圖-:
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 8, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 9, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0


            這是一張連連看的地圖,假設(shè)標(biāo)8和9的部分是兩張相同的牌。
            在數(shù)組矩陣中,0表示沒有牌,大于1表示有牌。至于是什么牌,那是隨機(jī)的了。
          不要告訴我,你說的“布局算法”是指怎么把牌剛剛好放上去,那個(gè)無所謂什么
          算法,你只要首先在地圖數(shù)組中準(zhǔn)備好偶數(shù)個(gè)1,在布牌時(shí)保證每種牌是偶數(shù)個(gè)
          (不同種類的牌用大于1的數(shù)來表示),相應(yīng)地放入每個(gè)1的位置上就可以了。

          一、計(jì)算地圖上這兩張牌能不能連通(當(dāng)然能了,哈哈)。

          這是連連看尋路算法的第一步。
          先定義一下兩張牌能連的充分條件:
          1.兩張牌是同一種。
          2.兩張牌之間有一條全是0的路可以連通。
          3.這一條路不能有兩個(gè)以上的拐角(corner)
          滿足這三個(gè)條件,就可以認(rèn)為這兩張牌是可以連的。

          首先,我們依據(jù)前兩個(gè)條件來完成一個(gè)基本的尋路算法。
          我們的目的是從8到9找出一條可以連通的路來。
          那么很明顯從8到9的第一步一其有四個(gè)方向可以選擇,分別是東,南,西,北
          (e, s, w, n以中國地圖方向?yàn)闃?biāo)準(zhǔn))四個(gè)方向,在第一步中我們首先假設(shè)四
          個(gè)方面沒有任何優(yōu)劣,那么我可以任意選擇一個(gè)方向移動(dòng),那就是東面吧。
          圖二:
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 8, -8, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 9, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          我從8向東移動(dòng)了一步,所以到達(dá)了-8的位置,我之所以可以移到-8位置,很明顯,
          是因?yàn)?8的位置上原來是一個(gè)0,表示沒有牌阻擋。
          那么現(xiàn)在尋路的問題就變成了,如何從-8找連通9的路了!
          說到這里應(yīng)該明白了吧,好多費(fèi)話,有點(diǎn)像娘們在說話。

          所以目前的尋路算法歸結(jié)為一個(gè)遞歸算法的基本問題。
          先從8到找到下一個(gè)結(jié)點(diǎn)-8,再用同樣的規(guī)則,從-8找到下一個(gè)結(jié)點(diǎn),比如-88。。。
          圖三:
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 8, -8, -88, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 9, 0
          0, 0, 0, 0, 0, 0, 0, 0 , 0, 0

          如果一直都能OK,沒有阻礙的話,最后找到了9,就算成功以,如要有一步不能走下去了,
          就再退回上個(gè)結(jié)點(diǎn),向別的方向發(fā)展,都不行,就再退回上級結(jié)點(diǎn),再向別的方向發(fā)展,
          這里的邏輯就是遞歸的思想了。

          用這樣的方法寫出來的算法已經(jīng)能在最優(yōu)的情形下用了,比如從8,到-88,哈哈。
          但在稍微復(fù)雜的情況下,會(huì)產(chǎn)生奇多的遞歸結(jié)點(diǎn)。P4機(jī)也跑不動(dòng)啊。我試過,哈哈。

          那么第二步就是為(e,s,w,n)四個(gè)方向加權(quán),也就是讓它們之間有一個(gè)優(yōu)先權(quán),說白了就
          是先試哪一條路。決定的法則應(yīng)該有好幾個(gè)吧,比如以9號的位置來看,它處于8號的東南面,
          那試路時(shí)當(dāng)然應(yīng)當(dāng)優(yōu)先選擇東面和南面,再比如9號如果牌8號的正東面,那當(dāng)然是選擇正東了。
          再比如,當(dāng)走到-8的位置時(shí),明顯只能再走三個(gè)方向,因?yàn)樗遣荒芑仡^的。

          經(jīng)過這樣的處理,遞歸算法生成的結(jié)點(diǎn)數(shù)會(huì)明顯變少,會(huì)更快的找到成功的路。但性能在最壞情況
          下沒有本質(zhì)改變。

          接下來,第三步,我們把第三個(gè)充分條件加進(jìn)來,來解決根本問題。
          3.這一條路不能有兩個(gè)以上的拐角(corner)

          按照面向?qū)ο蟮乃枷耄茏匀坏模医o每個(gè)在遞歸算法中生成的位置結(jié)點(diǎn)加上了個(gè)corner的屬性,
          來記錄這條路到目前為止拐了幾個(gè)角。
          這樣一下子就好辦了啊。如果發(fā)現(xiàn)這個(gè)結(jié)點(diǎn)已經(jīng)拐了兩個(gè)彎時(shí),如果要再拐彎,或者到達(dá)9之前注定
          要再增加cornor時(shí),就果斷over,返回上級結(jié)點(diǎn)。

          注意,要把二、三兩步的條件綜合起來詳細(xì)規(guī)劃一個(gè)個(gè)可能性,盡可能提早讓不可能的結(jié)點(diǎn)OVER,
          這就是提高性能的關(guān)鍵吧。算法預(yù)見性越強(qiáng),性能就越高吧。

          我們的算法在賽揚(yáng)500,256M的機(jī)器上,10萬次平均結(jié)果是一次運(yùn)算花時(shí)不超過0.1毫秒,算得還不
          精確,速度確實(shí)很快,因?yàn)樵诤軌牡那樾蜗拢a(chǎn)生的最大結(jié)點(diǎn)數(shù)是690幾個(gè),這樣必然會(huì)很快的
          ,詳細(xì)的數(shù)據(jù)已經(jīng)記不清了。


          說了這么多了,應(yīng)當(dāng)明白第一步連通算法的思路了吧,我所知道的,都已經(jīng)盡可能的講出來了。
          這個(gè)算法完全是自己按照連連看的特點(diǎn),度身定做的。因?yàn)槭且徊讲絫est出來的,所以我個(gè)人
          覺得是很自然的,沒有任何高深的地方,完成后,性能也很好,這才覺得是如此的簡單。相信大家
          仔細(xì)看看就能寫出自己的算法來的吧。


          二、整個(gè)地圖有沒有解???可以連通的總牌數(shù)?
            這是一個(gè)問題。
            解決這個(gè)問題之前,我們先來解決提示功能(hint)就是為玩家提供提示,哪一對牌可以連
          通。
            我的做法是,先把整個(gè)地圖中相同牌歸到一起,用數(shù)組也好,鏈表也好。
            像這樣,
           4,4,4,4
           5,5,5,5
           6,6,6,6
           ......
              然后計(jì)算比如4個(gè)4之間有哪兩對可以連,至于如何判斷能不能連,第一步算法已經(jīng)實(shí)現(xiàn)了吧,哈哈。
            一發(fā)現(xiàn)有可以連的牌就退出來,告訴玩家這兩張牌可以連啊!
            這就OK了。
            這完全是建立在第一步算法的基礎(chǔ)上實(shí)現(xiàn)的。

            好的,hint功能可以了,
            那么,整個(gè)地圖沒有解的算法是不是出來了?
            是的,如果找不到可以hint的牌,那當(dāng)然就是沒有解了!
            把所有可以hint的對數(shù)記下來,就是總的可以連通數(shù)了。

            至此,與連連看所有算法有關(guān)的問題解決完畢。
          第二步算法的實(shí)現(xiàn),明顯開銷要大很多,最壞情況應(yīng)當(dāng)會(huì)是單次連通算法計(jì)算量的大約50倍以上
          (與牌的總數(shù)量和擺的位置有關(guān))還好在一般的服務(wù)器上單次連通計(jì)算花的時(shí)間實(shí)在太少了,
          實(shí)際運(yùn)行中完全可以很流暢。以上數(shù)據(jù)都是我估計(jì)的理論值,因?yàn)閷?shí)際測試時(shí)一直沒有問題,
          我也懶得計(jì)算出真正比較可靠的均值了。
            
            這一部分也是我認(rèn)為可以有所改進(jìn)的部分,公開出來,也希望大家能提供一些更好,更巧妙
          的方法,我覺得我計(jì)算連通數(shù)和有無解的方法是比較笨的方法,幾乎是仗著基本的算法快,一
          個(gè)一個(gè)算出來的。有沒有更好的方法呢?期待中...

          posted on 2005-03-25 21:19 藍(lán)色雪焰 閱讀(556) 評論(0)  編輯  收藏 所屬分類: 編程技術(shù)
           
          主站蜘蛛池模板: 东丰县| 醴陵市| 巴塘县| 陈巴尔虎旗| 铅山县| 灵台县| 杂多县| 泗洪县| 江门市| 涞水县| 阳曲县| 奉贤区| 揭东县| 迁安市| 和平区| 墨竹工卡县| 阜城县| 奎屯市| 会泽县| 诸城市| 舒城县| 兴业县| 伊吾县| 巴彦县| 富阳市| 滨海县| 买车| 金堂县| 嘉定区| 凤翔县| 杨浦区| 甘洛县| 江源县| 陆河县| 肃宁县| 彭泽县| 邵东县| 锡林浩特市| 喀什市| 陇南市| 黑龙江省|