Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BBNTRPGを追加 #166

Merged
merged 6 commits into from
Apr 29, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- 「コード:レイヤード」で達成値修正とクリティカル値変更に対応。くずもちさんありがとうっ! (#149)
- 「SwordWorld/2.0/2.5」 レーティング表で半減ができるように。銀色のかぼちゃさん提案ありがとうっ! (#151)
- ダイスボットに「迷宮キングダム 基本ルールブック」を追加。TakaYamsさんありがとうっ! (#152)
- ダイスボットに「BBNTRPG」を追加。neuzさん、エレリーナさんありがとうっ! (#166)

### Ver2.04.00 2020/03/26
- ダイスボットに「獸ノ森」を追加。ゆいこさんありがとうっ! (#124)
Expand Down
138 changes: 138 additions & 0 deletions src/diceBot/BBN.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# -*- coding: utf-8 -*-

class BBN < DiceBot
# ダイスボットで使用するコマンドを配列で列挙する
setPrefixes(['\d+BN.*'])

ID = 'BBN'.freeze

NAME = 'BBNTRPG'.freeze

SORT_KEY = 'ひいひいえぬTRPG'.freeze

HELP_MESSAGE = <<MESSAGETEXT.freeze
・判定(xBN±y>=z[c,f])
 xD6の判定。クリティカル、ファンブルの自動判定を行います。
 1Dのクリティカル値とファンブル値は1。2Dのクリティカル値とファンブル値は2。
 nDのクリティカル値とファンブル値は n/2 の切り上げ。
 クリティカルとファンブルが同時に発生した場合、クリティカルを優先。
 x:xに振るダイス数を入力。
 y:yに修正値を入力。省略可能。
z:zに目標値を入力。省略可能。
c:クリティカルに必要なダイス目「6」の数の増減。省略可能。
f:ファンブルに必要なダイス目「1」の数の増減。省略可能。
 例) 3BN+4 3BN>=8 3BN+1>=10[-1] 3BN+1>=10[,1] 3BN+1>=10[1,1]
MESSAGETEXT

def rollDiceCommand(command)
unless parse(command)
return nil
end

# ダイスロール
dice, dice_str = roll(@roll_times, 6)
dice_list = dice_str.split(',').map(&:to_i).sort

total = dice + @modify

# 出力文の生成
sequence = [
"(#{command})",
"#{dice}[#{dice_str}]#{@modify_str}",
total
]

# クリティカルとファンブルが同時に発生した時にはクリティカルが優先
if critical?(dice_list)
sequence.push("クリティカル!", *additional_roll(dice_list.count(6), total))
elsif fumble?(dice_list)
sequence.push("ファンブル!")
elsif @difficulty
sequence.push(total >= @difficulty ? "成功" : "失敗")
end

return sequence.join(" > ")
end

private

# コマンド文字列をパースする
#
# @param command [String] コマンド
# @return [Boolean] パースに成功したか
def parse(command)
m = /^(\d+)BN([+-]\d+)?(>=(([+-]?\d+)))?(\[([+-]?\d+)?(,([+-]?\d+))?\])?/.match(command)
unless m
return false
end

@roll_times = m[1].to_i
@modify_str = m[2] || ''
@modify = m[2].to_i
@difficulty = m[4] ? m[4].to_i : nil

base = critical_base(@roll_times)
@critical = base + m[7].to_i
@fumble = base + m[9].to_i

return true
end

# 振るダイスの数からクリティカルとファンブルの基本値を算出する
#
# @param roll_times [Integer] 振るダイスの数
# @return [Integer] クリティカルの値
def critical_base(roll_times)
case roll_times
when 1, 2
roll_times
else
(roll_times.to_f / 2).ceil
end
end

# @return [Boolean] クリティカルか
def critical?(dice_list)
dice_list.count(6) >= @critical
end

# @return [Boolean] ファンブルか
def fumble?(dice_list)
dice_list.count(1) >= @fumble
end

# クリティカルの追加ロールをする
# 追加ロールで6が出た場合、さらに追加ロールが行われる
#
# @param additional_dice [Integer] クリティカルによる追加のダイス数
# @param total [Integer] 現在の合計値
# @return [Array<String>]
def additional_roll(additional_dice, total)
sequence = []
reroll_count = 0

# 追加クリティカルは無限ループしうるので、10回に制限
while additional_dice > 0 && reroll_count < 10
reroll_count += 1

dice_total, dice_str = roll(additional_dice, 6)
additional_dice = dice_str.split(',').map(&:to_i).count(6)

sequence.push("#{total}+#{dice_total}[#{dice_str}]")
sequence.push("追加クリティカル!") if additional_dice > 0

total += dice_total
end

if additional_dice > 0
sequence.push("無限ループ防止のため中断")
end

sequence.push total
if @difficulty
sequence.push(total >= @difficulty ? "成功" : "失敗")
end

return sequence
end
end
174 changes: 174 additions & 0 deletions src/test/data/BBN.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
input:
1BN クリティカル
output:
BBN : (1BN) > 6[6] > 6 > クリティカル! > 6+4[4] > 10
rand:6/6,4/6
============================
input:
1BN ファンブル
output:
BBN : (1BN) > 1[1] > 1 > ファンブル!
rand:1/6
============================
input:
1BN
output:
BBN : (1BN) > 5[5] > 5
rand:5/6
============================
input:
2BN クリティカル
output:
BBN : (2BN) > 12[6,6] > 12 > クリティカル! > 12+2[1,1] > 14
rand:6/6,6/6,1/6,1/6
============================
input:
2BN 2Dの時は6ゾロのみクリティカル
output:
BBN : (2BN) > 8[6,2] > 8
rand:6/6,2/6
============================
input:
2BN ファンブル
output:
BBN : (2BN) > 2[1,1] > 2 > ファンブル!
rand:1/6,1/6
============================
input:
2BN 2Dの時はピンゾロのみクリティカル
output:
BBN : (2BN) > 3[1,2] > 3
rand:1/6,2/6
============================
input:
3BN クリティカル
output:
BBN : (3BN) > 13[6,6,1] > 13 > クリティカル! > 13+2[1,1] > 15
rand:6/6,6/6,1/6,1/6,1/6
============================
input:
3BN ファンブル
output:
BBN : (3BN) > 8[6,1,1] > 8 > ファンブル!
rand:6/6,1/6,1/6
============================
input:
3BN クリティカルでもファンブルでもない
output:
BBN : (3BN) > 10[6,1,3] > 10
rand:6/6,1/6,3/6
============================
input:
4BN クリティカル
output:
BBN : (4BN) > 21[6,6,4,5] > 21 > クリティカル! > 21+5[2,3] > 26
rand:6/6,6/6,4/6,5/6,2/6,3/6
============================
input:
4BN ファンブル
output:
BBN : (4BN) > 11[1,1,4,5] > 11 > ファンブル!
rand:1/6,1/6,4/6,5/6
============================
input:
4BN クリティカルでもファンブルでもない
output:
BBN : (4BN) > 16[1,6,4,5] > 16
rand:1/6,6/6,4/6,5/6
============================
input:
4BN クリティカルとファンブルはクリティカルが優先
output:
BBN : (4BN) > 14[6,6,1,1] > 14 > クリティカル! > 14+6[2,4] > 20
rand:6/6,6/6,1/6,1/6,2/6,4/6
============================
input:
2BN 追加クリティカル1回
output:
BBN : (2BN) > 12[6,6] > 12 > クリティカル! > 12+7[6,1] > 追加クリティカル! > 19+1[1] > 20
rand:6/6,6/6,6/6,1/6,1/6
============================
input:
2BN 追加クリティカル1回
output:
BBN : (2BN) > 12[6,6] > 12 > クリティカル! > 12+12[6,6] > 追加クリティカル! > 24+2[1,1] > 26
rand:6/6,6/6,6/6,6/6,1/6,1/6
============================
input:
2BN 追加クリティカル3回
output:
BBN : (2BN) > 12[6,6] > 12 > クリティカル! > 12+7[6,1] > 追加クリティカル! > 19+6[6] > 追加クリティカル! > 25+6[6] > 追加クリティカル! > 31+1[1] > 32
rand:6/6,6/6,6/6,1/6,6/6,6/6,1/6
============================
input:
2BN[-1]
output:
BBN : (2BN[-1]) > 8[6,2] > 8 > クリティカル! > 8+2[2] > 10
rand:6/6,2/6,2/6
============================
input:
2BN[1,-1]
output:
BBN : (2BN[1,-1]) > 6[5,1] > 6 > ファンブル!
rand:5/6,1/6
============================
input:
2BN[,-1]
output:
BBN : (2BN[,-1]) > 6[5,1] > 6 > ファンブル!
rand:5/6,1/6
============================
input:
4BN[1,1] クリティカルとファンブル引き上げ
output:
BBN : (4BN[1,1]) > 14[6,6,1,1] > 14
rand:6/6,6/6,1/6,1/6
============================
input:
4BN[1,1] クリティカル
output:
BBN : (4BN[1,1]) > 19[6,6,6,1] > 19 > クリティカル! > 19+6[4,1,1] > 25
rand:6/6,6/6,6/6,1/6,4/6,1/6,1/6
============================
input:
4BN[1,2] ファンブル
output:
BBN : (4BN[1,2]) > 4[1,1,1,1] > 4 > ファンブル!
rand:1/6,1/6,1/6,1/6
============================
input:
1BN 無限ループ防止のため追加クリティカルは10回まで
output:
BBN : (1BN) > 6[6] > 6 > クリティカル! > 6+6[6] > 追加クリティカル! > 12+6[6] > 追加クリティカル! > 18+6[6] > 追加クリティカル! > 24+6[6] > 追加クリティカル! > 30+6[6] > 追加クリティカル! > 36+6[6] > 追加クリティカル! > 42+6[6] > 追加クリティカル! > 48+6[6] > 追加クリティカル! > 54+6[6] > 追加クリティカル! > 60+6[6] > 追加クリティカル! > 無限ループ防止のため中断 > 66
rand:6/6,6/6,6/6,6/6,6/6,6/6,6/6,6/6,6/6,6/6,6/6
============================
input:
3BN+3>=10[-1,-1]
output:
BBN : (3BN+3>=10[-1,-1]) > 7[2,3,2]+3 > 10 > 成功
rand:2/6,3/6,2/6
============================
input:
3BN+3>=10[-1,-1]
output:
BBN : (3BN+3>=10[-1,-1]) > 6[2,2,2]+3 > 9 > 失敗
rand:2/6,2/6,2/6
============================
input:
3BN-2>=10[-1,-1] クリティカルによって成功
output:
BBN : (3BN-2>=10[-1,-1]) > 8[6,1,1]-2 > 6 > クリティカル! > 6+5[5] > 11 > 成功
rand:6/6,1/6,1/6,5/6
============================
input:
3BN-2>=10[-1,-1] クリティカルしたけど失敗
output:
BBN : (3BN-2>=10[-1,-1]) > 8[6,1,1]-2 > 6 > クリティカル! > 6+2[2] > 8 > 失敗
rand:6/6,1/6,1/6,2/6
============================
input:
3BN+3>=10[-1,-1] 目標値は超えてるけどファンブル
output:
BBN : (3BN+3>=10[-1,-1]) > 11[1,5,5]+3 > 14 > ファンブル!
rand:1/6,5/6,5/6
============================