6. 単語群

里々の単語群(@)は、湊にはありません。代わりに、次の3つの方法があります。里々の単語群が持っていた「ランダムに1つ選ぶ」「重複を避ける」「条件で絞る」の機能を、どれで実現するかで選びます。

方法ランダム選択重複回避条件で絞る向く場面
① 配列 + rand()○自分で書く自分で書く短い固定リスト。順番に出すなど自由な制御
② 同名トーク + return○自動(一巡)if(...)里々の単語群に一番近い。数が多いとき
③ choose()条件による2択——真偽で2つから選ぶだけ

① 配列と rand()

里々の単語群 @果物 に当たるのは、配列です。ランダムに選ぶには、rand() % 要素数 を添字に使います。

OnBoot => {
    let words = ["りんご", "みかん", "ぶどう"]
    湊: ${words[rand() % len(words)]}が好き。
}
\0りんごが好き。\e
\0みかんが好き。\e
\0ぶどうが好き。\e

rand() は大きな整数(0〜約43億)を返すので、% len(…) で範囲を絞ります。この方法には重複回避がありません。同じ単語が続けて選ばれることもあります。

何度も使うなら、選ぶ処理を関数にしておきます。

func 選ぶ(list) {
    return list[rand() % len(list)]
}

OnBoot => {
    湊: ${選ぶ(["朝", "昼", "夜"])}ですね。
}
\0朝ですね。\e
\0昼ですね。\e
\0夜ですね。\e

順番に選ぶ(里々の「降順」)

里々の $単語群「○」の重複回避【タブ】降順 のように、順番に選びたいときは、保存した番号を使います。

OnBoot => {
    let words = ["春", "夏", "秋", "冬"]
    global save.i ?= 0
    湊: ${words[save.i % len(words)]}
    global save.i += 1
}
\0春\e
\0夏\e
\0秋\e
\0冬\e
\0春\e

単語の追加

里々の (単語の追加,…) は、配列に push で追加します。push は元の配列を変えず、新しい配列を返すので、代入し直す必要があります。

OnBoot => {
    global save.覚えた ?= []
    global save.覚えた = push(save.覚えた, "りんご")
    global save.覚えた = push(save.覚えた, "みかん")
    湊: ${join(save.覚えた, "、")}|${len(save.覚えた)}
}
\0りんご、みかん|2\e

同様に pop、reverse、unique、delete(マップ用)も、新しい値を返すだけで元の値は変えません。

② 同名トークと return

同じ名前のトークを複数書き、return で文字列を返す形です。里々の @ に最も近く、一巡するまで同じものを選ばないことが自動で保証されます(4. トーク)。

果物 => {
    return "りんご"
}

果物 => {
    return "みかん"
}

果物 => {
    return "ぶどう"
}

OnBoot => {
    湊: ${果物()}が好き。
}
\0りんごが好き。\e
\0みかんが好き。\e
\0ぶどうが好き。\e

${果物()} が、里々の (果物) に当たります。

里々の「1回のトークの中で同名の単語群を何度呼んでも、同じ単語は選ばれない」という動きも、この方法なら再現できます。

色 => {
    return "赤"
}

色 => {
    return "青"
}

OnBoot => {
    湊: ${色()}と${色()}
}
\0赤と青\e
\0青と赤\e

2つの候補を2回呼ぶと、必ず別々の色になります。ただし、候補がちょうど2つのときは、最初の1周の順序が決まると、そのあとは毎回同じ順序で交互に選ばれます(周回の境目で同じものを続けないという規則のため)。上の例では、1回の実行中は「赤と青」か「青と赤」のどちらか一方だけが繰り返されます。

条件で絞る

里々の @単語群【タブ】条件式 に当たるのは、トーク定義の if(...) です。

天気 if(save.雨) => {
    return "雨"
}

天気 if(!save.雨) => {
    return "晴れ"
}

OnBoot => {
    湊: 今日は${天気()}です。
}

OnRain => {
    global save.雨 = true
}
\0今日は晴れです。\e
(204)
\0今日は雨です。\e

すべての候補が条件で除外されると、${…} は空文字列になります。 作者向けのログに通知が残ります(セリフは出力されるので、気づきにくい点に注意してください)。

単語の中に単語

return に返す文字列の中で、別の単語を呼べます。

色 => {
    return "赤"
}

りんご => {
    return "${色()}いりんご"
}

OnBoot => {
    湊: ${りんご()}です
}
\0赤いりんごです\e

セリフを含むトークは単語群に向かない

return ではなく、湊: のセリフを書いたトークを ${…()} で呼ぶと、スコープタグ(\0 など)も一緒に文字列に入ってしまいます。

挨拶 => {
    湊: こんにちは
}

OnBoot => {
    湊: 「${挨拶()}」
}
\0「\0こんにちは」\e

単語や短い文だけを返すトークは、return "…" で書いてください。

③ choose

真偽で2つのうち1つを選ぶだけなら、choose(条件, 真のときの値, 偽のときの値) が使えます。里々の (when,条件,真,偽) に当たります。

OnBoot => {
    湊: ${choose(true, "はい", "いいえ")}
}
\0はい\e

選ばれなかった側の式は評価されません(saori() などの副作用がある式を書いても、実行されません)。

里々の単語群の細かい機能

里々湊
1行が1候補①なら配列の1要素、②なら1つのトーク
単語群の中に (別の単語群)②の return "${別のトーク()}"
単語の追加・削除の関数push pop delete(新しい値を返すので代入し直す)
重複回避の方式の変更(無効・直前・降順・昇順)②は「一巡」固定。他の方式は①で自作

YAYAから来た方へ

  • YAYAの 名前 { "a" "b" "c" }(複数の文字列から1つを選ぶ関数)は、②の同名トークに当たります。YAYAでは : nonoverlap を付けて重複を避けますが、湊の②は常に一巡します。
  • YAYAの -- で区切って複数の単語群を連結する書き方は、${…} を並べて書きます。

次は7. 選択肢・条件分岐・ウェイトに進んでください。