三國殺武將技能在程序內部是如何執行的?

武將技能近似於自然語言,是如何「翻譯」成程序語言的.

武將技能是否存在優先順序,開發者是否人為判斷誰遇到誰的所有情況。如何考慮可擴展性的?


其實就是個簡單的狀態機。你把武將狀態描述出來就可以搞了。簡單地說一下。

武將有以下屬性:

靜態屬性:ID(實現的時候肯定不用姓名來判定!),性別,勢力,最大血量,技能,跟遊戲無關的還有武將名字,武將描述,武將畫像。

動態屬性:當前血量,當前階段(回合外,開始階段,判定階段,摸牌階段,出牌階段,棄牌階段,結束階段,做一個枚舉類型),裝備(包括武器,防具,+1,-1),手牌,延時錦囊,翻面,橫置,其他狀態(比如覺醒技中的覺醒部分和限定技是否已發動,神將帶來的各種標記等)。

一局遊戲,涉及的數據除了N個武將以外還有武將座次,身份,牌堆和棄牌堆。這裡先不考慮用戶系統什麼的。

接下來就開始玩兒,主公先來,按座次依次運行。每個動作都對應修改上面的武將屬性。比如A在出牌階段殺了B,B出閃,A的手牌里就去掉那張殺,B的手牌里就去掉那張閃,然後棄牌堆里多了殺和閃。

比較煩的是技能的判定。因為技能的觸發條件多種多樣。主動技能主要看是否主動觸發(當然也要附帶一些其他條件,比如驅虎要求雙方都有手牌且對方血量比荀彧高這種)。其他技能的檢測非常繁瑣。但是機制不複雜。簡單的說就是任意一個遊戲事件觸發之後都要檢查是否滿足某技能的觸發條件。比如任意人出牌階段出殺(殺人,不包括決鬥和南蠻出殺),檢查發現滿足關平的龍吟觸發條件,於是系統應該提示關平是否發動龍吟。還有比如任何一個判定發生,都滿足了司馬的天命和張角的鬼道,然後分別詢問二者是否發動。只要將所有遊戲中的事件都劃分好,這些其實都很自然地對應到程序行為上去。

然後是技能本身,其實所有技能的效果對我最開始列出的武將屬性的修改是不是確定的?在任意情況下你是不是也知道技能的效果會改掉那些屬性?傷害就改當前血量,跳過出牌就跳過出牌階段嘛。這些修改拿程序來完成是不是就沒有問題啦~當然武將技能非常多且不具備整體的相似性。現在三國殺OL的做法應該也是每個技能單獨對應一段代碼。這些代碼只是多而已,並不難寫。

好了,下一個優先順序的問題。所有優先順序都是定死的,唯一動態的也就是同一優先順序的東西從當前回合者開始詢問/結算,最典型的就是司馬的天命和張角的鬼道(倆改判定)。然後還有武器效果啊,瀕死求桃啊相對於武將技能什麼的,優先順序都是固定的。比較簡單的就是瀕死求桃優先順序高於一切。於是荀彧瀕死必須先救回來才能節命。如果你玩過國戰知道三尖兩刃刀這件武器的話,也能理解為什麼要先救回來才能發動它的特效。相比之下,麒麟弓的特效發動時機是在傷害之前,所以先棄馬,後掉血。這些先後都是有講究的。比如你裝備麒麟弓殺一血空手牌孫尚香,發動特效棄了她一匹馬,孫尚香的梟姬優先順序比「傷害」這個事件高(注意,此時瀕死求桃的事件並未發生),於是先發動梟姬,摸兩張牌,這時候如果摸到桃子和酒是可以使用的。所以,不存在「人為」判定的情況。一切都是按照三國殺的規則來的。

至於可擴展性。在最開始講的這個框架基礎上,擴展起來很簡單啊。加武將加牌都不用動系統,加一堆數據而已。不過,三國殺的精髓也就在於這堆「數據」。


如果你仔細研究的話你會發現那些規則還是相當精確的,只是那種自然語言的描述方法跟我們寫程序用的邏輯思維的方法是不一致的。當然我相信題主你肯定可以寫出那樣的程序,只是如果你關心建模方法的話,你可以去看那個過氣了的Aspect Oriented Programming。技能的描述長得跟這個略像。


三國殺的遊戲流程依賴一個自動機。這個遊戲運行的部件包括

基本規則(卡牌功能,回合一殺,桃不能滿血吃等等)

牌桌,包括

  • 牌堆
  • 棄牌堆
  • 玩家
  • 武將牌
  • 身份牌
  • 手牌
  • 裝備
  • 判定區(不屬於玩家)

要說程序實現,最直觀的想法肯定是先把牌桌上的東西對象化,把各種屬性用類欄位之類的表示出來。至於規則,則必須將三國殺里的動作和事件進行細化,分解為無法拆分和中斷的「原子事件」和「原子動作」,然後就可以把自然語言的描述變成代碼。就好像一套用於sgs的指令集一樣

事件和動作有些很明顯的,比如進入各個階段(還有「之前」、「之後」這種微妙的時機)、牌脫手、棄牌、展示牌、X對Y使用某牌,X(對Y)打出某牌,X對Y造成傷害,X恢復Y點體力,X體力流失、計算距離等等。每個動作和事件都有對細節的記錄,而動作和事件會不斷引發更多的動作和事件。將這些亂七八糟的東西組合一下差不多就是武將們的技能了。為了讓武將們的技能有良好互動,我們要把這些事件也對象化,然後在用代碼描述技能的時候對他們排列組合就可以了。

舉個簡單的例子:呂布的無雙,在用殺和決鬥的時機觸發。白板A對白板B使用殺之後的結算是這樣的:「使用牌」進入事件隊列並被分揀,執行「殺」的功能,行動權交給B,B被「規則」要求響應一張閃,同時手牌被過濾,只有閃為可選,或者在裝備八卦時先被詢問是否發動八卦,接下來B如果引發了「B打出一張閃」的事件,則免受傷害,結算結束,行動權返回A,否則B點取消,殺將觸發A對B的傷害事件(普通傷害,1點,來自A,對B,殺 草花7)。無雙的介入將導致B收到兩個「出一張閃的請求」,逐一結算,所以是「依次打出」,這樣才有了一血神將戲耍呂布的故事。

其他的技能也大同小異。再選將結束後,登場武將的技能與玩家綁定並開始「監聽」事件隊列里的事件(卡牌功能也可如此),遇到自己關心的事件則做進一步檢測(如果需要,如,連營關注有牌脫手事件→手牌為0→連營)。有些不是那麼明顯,例如西涼馬術,在借刀殺人和自己出牌階段選擇了殺之後,可能會觸發計算距離的動作來過濾可選目標。空城,則是在有玩家過濾殺和角斗的目標時候觸發。武神使神2爺在允許或要求出殺的時候,紅桃的桃園結義也是可選的。SP曹仁的數裝備也是非常個性的一個了。

在講武將技能編碼為程序的時候,個人認為關鍵在於如何更好的與描述等效。例如貂蟬的離間,其等效打出的角斗不被無懈響應,但又要讓孫策和呂布之流正確互動。

這套東西有一個(我覺得挺屌的)用法,你可以不用為無中生有和樂不思蜀設置標記「瞬發錦囊」和「延時錦囊」,直接檢測卡牌預置的行為也可判斷(雖然拐彎抹角的)。

至於題主問道的優先順序問題,以張角和司馬的改判順序為例,這個優先順序是依賴基本規則的,不難實現。優先順序暫時沒想到什麼詳細的例子,想到再補充。


如果要考慮不同武將技能的優先順序,那麼其可擴展性就太差了。每次新出一個都要面臨大修改,這是不現實的。

@( ̄- ̄)@

@( ̄- ̄)@

確實如同@歸辰 所言可以轉化成為一個狀態機,但我認為並不是他描述得那麼簡單。

這裡說一下一直以來的想法吧。

首先,先放上三國殺官方的資料用語集。這個頁面的「通則」部分貌似沒有寫好。

http://dadao.net/sgs/guo.html 【官方微博曾經提供的鏈接】

其次,再放上通則;

http://fl.act.qq.com/15637/addev/h5/31372 【資料來源於微信平台:我愛三國殺】&<--這個是

重點。。

所以可以引入狀態量的序號表示當前發生的事件,這樣由上面兩個網站的資料,所有事件都可以分解成具有原子性的子事件的組合。每一個子事件發生時需要檢測一系列此結點對應的技能。無論對應的技能擁有者在不在場。

舉個例子。小喬使用丈八蛇矛將黑桃2的寒冰劍和黑桃6的順手牽羊當做殺來殺于禁。

來模擬玩家使用/打出一張牌結算完畢的結算過程。這個並非官方,只是本人根據上述資料設想。真正的流程應該是類似的。

(1)玩家選擇一定數量的手牌,進行確認。

(2)先進行手牌數量合法性檢測(一般情況是一張,丈八蛇矛、貫石斧是兩張,諸葛恪則更不一定)。

(3)不通過,退到(1)。否則確認牌面信息。包括花色、點數。如果是1張牌,則按照牌面信息進行;2張及以上按以下規則:1)所有牌為單一花色則為該花色否則視為無花色;方片紅桃為紅色,梅花黑桃為黑色,所有牌同色視為該顏色否則為無色。2)點數相加,超過13視為K。

(4).牌面信息的轉化。1)確認花色,檢測技能【紅顏】;2)確認點數。超過13視為K,低於1視為1.檢測技能【丈八蛇矛】【鷹揚】

(5).牌的內容的轉化。對此產生影響的技能比較多,【看破】【奇襲】【龍膽】等等。

經過以上五步,初步完成了玩家「準備打出/使用一張牌」的流程。

(1)小喬選擇手中的【黑桃】【2】的【寒冰劍】和【黑桃】【6】的【順手牽羊】

(2)數量為2檢測通過;

(3)顏色為【黑】,花色為【黑桃】,點數是【8】,

(4)確認花色,小喬發動技能【天香】,花色修改成【紅桃】,顏色修改成【紅】;確認點數,無影響。

(5)牌的內容的轉化。由於丈八蛇矛的效果,兩張牌被視為一張【殺】

至此,小喬打出/使用了一張紅色的紅桃8。

繼續。

(6)根據上下文語境(不同狀態的號碼)確認「使用/打出」。

(7)如果是「使用」,則進行玩家使用合法性檢驗。檢測技能【雞肋】等;

(8)檢測通過則進行合法目標檢驗。此時計算玩家距離、檢測技能【謙遜】【帷幕】等;

(9)如果沒有一個合法目標,則此牌無法「使用」;

(10)如果存在合法目標,則進行目標數量確認。影響技能【滅計】【巧說】【方天畫戟】【天義】【短兵】等。可以指定小於等於最高合法數量數的目標。

(11)玩家手牌數檢測。影響技能有【連營】【傷逝】【絕策】等;

。。。額。

太多了,不寫完了,只是舉一個例子。

以上的每一步都可以用一個原子事件的序列號表示,這些步驟和武將身份無關、和武將擁有什麼技能無關。另外,如果同一步有多個技能發動,則按照當前回合逆時針的順序結算。

然後,每個序列號檢測一組技能,如果技能被玩家擁有,則提示是否發動。

怎麼樣,還是挺機械的吧。

只要詳細劃分指定殺的目標前指定殺的目標時指定殺的目標後成為殺的目標前成為殺的目標時成為殺的目標後造成傷害時受到傷害時受到傷害後扣減體力造成傷害後等等時間節點,還有死亡結算的六個步驟都分解了,這樣也不是很難,對的吧~


建議看看太陽神三國殺源碼,摺疊我吧


推薦閱讀:

需要在兩個星期內速成基本的R語言,之前幾乎無編程經驗,有什麼好的學習建議嗎?
纏論k線包含關係求解?
編程公式如何判定纏論中的線段的端點?
Python 有那麼神嗎?
編程的成就感,來自漂亮的代碼還是漂亮的功能?

TAG:遊戲 | 編程 | 三國殺 |