[心得] 骰子與骰子組
有在玩 D&D 的玩家一定知道所謂的 d20 系統…
也就是 20 面骰子的系統。不過說是 20 面骰子,
事實上還有各種其他面數的骰子:
http://www.wizards.com/d20modern/d20mdice/dice.htm
更有甚者,其實整個 WarCraft III 的普通攻擊也是整個用骰子去做成的。
比方說,Human 的 Knight 的攻擊力就是 2d5 + 25, 也就是五面骰丟兩個,
然後再加上 25 成為最終傷害。如果我沒記錯的話,每升一次級,則是加上
一顆骰子。也就是 3 級的 Knight 是 5d5 + 25. 查查官方網站,
http://www.battle.net/war3/human/units/knight.shtml
一個沒升級的 Knight 傷害平均是 31, (2+2*5)/2+25, 確實是 31,
滿級的是 40, (5+5*5)/2+25, 確實是 40...
然後一個單位的傷害極限是 100d100 +... 好吧,那個 +... 不要管了,
總之這樣傷害力就會是 100 ~ 10000, 一個很鬼扯的傷害範圍
為了查證我的推測沒錯,還不小心發現官網有看起來很有趣的地圖……
有空可以抓來試試看。不過當然以上都不是重點,只是想表述一下骰子
對於遊戲的重要性。
重點在於,今天下午我開始試著用 Ruby 實作骰子系統。想要做到的就是
可以方便呼叫骰子,使用骰子。當然我知道這個東西很簡單,所以我也只是
大概寫寫,然後稍微介紹一下我是怎麼寫的…
目標使用介面是這樣:
2.roll # 等同於 2d20 => 2 ~ 40
3.roll(4) # 等同於 3d4 => 3 ~ 12
dice = 6.dice # 儲存 6d20 的骰子(s)
dice = 8.dice(4) # 儲存 8d4 的骰子(s)
dice.roll # 搖出那骰子(s)
只有這樣就太無趣了,來個結構比較複雜的骰子組,比方說 2d20 + 3d4 + 8d4
dice_set = DiceSet.new(2.dice, 3.dice(4), 8.dice(d))
dice_set.roll # 這就是… 2~40 + 3~12 + 8~32 共 13~84
更有甚者,使用 composite pattern...
another_dice_set = DiceSet.new(2.dice, dice_set)
現在上面這個 another_dice_set 變成 2d20 + 原本設定好的 dice_set
another_dice_set << 2.dice # 再追加 2d20
another_dice_set << DiceSet.new(dice_set, dice_set, 2.dice)
現在這個 another_dice_set 已經變成很瘋狂的骰子組了,我懶得算了…
another_dice_set.roll # 擲出剛剛那瘋狂的骰子組
實作很簡單,相信看到這裡的各位都已經知道怎麼寫了,不過還是稍微
說明一下好了,也許還有在觀望的讀者也說不定?
由於 5.times 之類的東西讓我驚艷,所以我決定把骰子也加到數字裡面。
而這可以靠著 Ruby 動態擴充 class 來辦到,所以現在要決定的是要擴充
到哪個 class 中? 5 的型別是 Fixnum, 不過野心可以大一點,加到 Numeric
感覺會比較爽,於是可以丟出這種詭異的骰子:-123.456.roll, 還有這種:
12972398574892734896769868686934059230491204821491.roll(Bignum)
當然意義是不大,不過這是爽度問題…反正也不是什麼正經程式 XD
class Numeric # 打開 Numeric 去擴充
def roll(faces = 20) # 沒輸入面數則預設 20 面(d20 中最常用)
return nil unless self > 0 && self.integer? &&
faces > 0 && faces.integer?
# 如果「面數」或「骰數」其中之一不是整數,或是負數,
# 則…說真的我也不知道這種骰子要怎麼骰,所以暫時傳回 nil
# 表示目前還不知道這個骰子的意義是什麼?
result = 0 # 這是骰子丟出來的結果,先初始化為 0
1.step(self){ |i| result += rand(faces) + 1 }
# ok, 這行的意思是 |i| 由 1 開始跑,|i| 遞增 1,
# 直到 self 這個數字為止(包含 self)
# self 的意思等同於 C++/Java 中的 this,
# 而這個東西指向的是:Numeric, 也就是 2.roll 的 "2"
# 所以 2.roll 的話,這裡的 self 是 2, 1 開始跑,到 2 為止,
# 正好是跑兩次,也就是丟兩顆骰子,rand(N) 產生 0~N-1 的數字
# 所以骰子需要 +1 成為 1~N, 也就是這裡的 1~20
result # 最後一行可以省略 return... 所以這等同於 return result
end
end
預知詳情,下回分曉……今天雜事有點多 =.=
下回介紹 Dice, DiceSet, 還有我拿來測試的 TestDice
--
Hear me exalted spirits. Hear me, be you gods or devils, ye who hold
dominion here:
I am a wizard without a home. I am a wonderer seeking refuge.
Sacrifice
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.28.18
推
08/09 23:55, , 1F
08/09 23:55, 1F
推
08/10 00:03, , 2F
08/10 00:03, 2F
推
08/10 00:09, , 3F
08/10 00:09, 3F
→
08/10 01:31, , 4F
08/10 01:31, 4F
推
08/10 07:15, , 5F
08/10 07:15, 5F
推
08/10 14:48, , 6F
08/10 14:48, 6F
推
08/10 23:35, , 7F
08/10 23:35, 7F
討論串 (同標題文章)
Ruby 近期熱門文章
PTT數位生活區 即時熱門文章