nDmロール(2):for文
そろそろダイス振ります。
で、そのダイスについて以下に。
オンラインセッション用ダイスに求められる仕様とは?
足し合わせた結果だけでなく、その内訳も見られることだと思います。
今までに利用した幾つかのダイスボットに共通して見られた仕様なのですが、これは感覚的に納得できます。
最終的に判定に使う数値はすべてのダイスを足し合わせた結果ですが、数値がずらーっと並ぶと、やっぱり「振った!」っていう実感がわくんです。だから多くのダイスボットはそういう仕様にしてるんだと思います。
ループ文「for」
さて、やることが、『n面ダイスを振ることを、ダイスの個数回繰り返し』なので、ここで定数回繰り返しの文「for」を使います。概要・構文については以下の通り。
概要
丸括弧で囲まれ、セミコロンにより分けられた、3 つの省略可能な式で構成されるループを作成します。式の後にはループの中で実行される文が続きます。
構文
for - JavaScript | MDN
for ([initial-expression]; [condition]; [final-expression])
statement
これもすごいなあと思うのですが、forに続く()の中で、
- カウンタ用変数の宣言と初期化
- カウンタ用変数が終了条件にいたったか否かの評価
- カウンタ用変数に変更または増加の処理
を一気に指定しまいます。
このスクリプトの場合だとこんな感じに。
numDice:ダイスの個数(n)
として、
for (var i = 0; i < numDice; i++){ (以下ダイスを振るスクリプト) }
たとえばダイスの数が15個だとして。
iが0〜14までの15回ループします、という指定になります。
i++ は i = i + 1 の意味。
で、こんなスクリプトになりました。
function event::onChannelText(prefix, channel, text) { if (text.match(/#\d+D\d+/i)) { //該当文字列を配列arrMatchedTextに格納 var arrMatchedText = text.match(/#\d+D\d+/i); //文字列からダイスの面数と個数を配列arrDiceに格納 var arrDice = arrMatchedText[0].match(/(\d+)/g); //個数と面数をそれぞれの変数に格納 var numDice = parseInt(arrDice[0]); //個数(n) var faceDice = parseInt(arrDice[1]); //面数(m) //結果を格納する変数の設定と初期化 var diceRolled = 0; //ダイス1個のロール結果 var diceTotal = 0; //ダイスロールの合計 var diceRecord = ""; //出目すべての記録 //ループ開始 for (var i = 0; i < numDice; i++){ //ダイス振る diceRolled = parseInt(Math.random() * faceDice)+ 1; diceTotal = diceTotal + diceRolled; if (i==0){ diceRecord = diceRecord + diceRolled; } else { diceRecord= diceRecord + ',' + diceRolled; } } //出力 send(channel, prefix.nick + ':' + numDice + 'd' + faceDice + '=(' + diceRecord + ')= ' + diceTotal); } }
で、実行結果↓
21:23 (ten-you) aaaaaaaaaaaaaaa#2D10aaaaaaaaaaaa
21:23 (ten-you) ten-you:2d10=(7,2)= 9
形になりました。よかった。
まとめ
forについて。
- 書式は「for(条件部){条件成立時に繰り返すスクリプト}」
- 条件部は「;」区切りで以下の3つに分かれる
- カウンタ用変数の宣言と初期化
- カウンタ用変数が終了条件にいたったか否かの評価
- カウンタ用変数に変更または増加の処理