登場人物の一般化A to Z(2)

 登場人物の配置は「一人目が誰で二人目が誰で三人目が誰」というようなことが非常に大事だ。一人目も二人目も三人目も型は同じなので指定を間違えてもコンパイルエラーになってくれない。

 俺は、一人目を「自分」、二人目を「相手」、三人目を「三者」と呼んでいる。自分が主人公であるとは限らないし、三者が主人公でないとも限らない。けれど「何人目か」を指定するのに、「一人目」とか「二人目」とかの抽象的な呼び方をしていると一発で間違える。自分とか相手とか少しでも具体的なほうがいい。

 一人目とか二人目とかを実行中に入れ替えることは出来ない。入れ替えられた方が書きやすい部分はあって、昔のSGでは入れ替えられたんだけど、とにかく間違いやすい。入れ替えた結果今誰が何人目なのか、というようなことが全然わからなくなってしまう。

 そのためにLimitedSubというのを作った。制限されたサブルーチンの意だ。ここにジャンプすると、一人目二人目が一時的に変更でき、サブルーチンから戻ると元に戻る。

class Unkoを見せる : P1P2Episode<Unkoを見せる>
{
  public override DefinedChara Jibun{ get{ return DefinedChara.All; } }
  public override DefinedChara Aite{ get{ return DefinedChara.All; } }

  public Act Start = new Act();

  public Unkoを見せる()
  {
    Start.Set(
      //相手から自分へのあいさつ
      JumpLSub(Aisatu.Hello, ECharaPlace.Aite, ECharaPlace.Jibun),
      JibunSwitchText( 
        CS(Tokieda, "ねえ、僕のウンコを見てくれないかな。"),
        CS(Yamada, "おいどんのウンコ、見てくんさい。"),
        CS(Tendo, "ちょっと、私の排泄物見なさいよ。")),

      TokiedaSwitch(
        //自分が主人公だったら
        If(delegate{
          //NPCがウンコを見るかどうかを決めるアルゴリズム...
        },
        //見る場合 
        TrueBlock(AiteSwitchText(
          CS(Yamada,"見てもいいでゴンス"),
          CS(Tendo,"みてもいいわよ")
        )),

        //見ない場合
        FalseBlock(AiteSwitchText(
          CS(Yamada,"なんでそんなもの見なきゃならんのでゴンすか"),
          CS(Tendo,"みないわよ。死になさい")
        )),

        //自分がNPCだったら、見るか見ないかの選択肢を表示
        Select( S("見る",miru), S("見ない",minai))
      ));
  }
}

//LimitedSub あいさつ。デュアルである。
class Aisatu : DLSub<Aisatu>
{
  public override DefinedChara Jibun{ get{ return DefinedChara.All; } }
  public override DefinedChara Aite{ get{ return definedChara.All; } }
  LSub hello = new LSub();

  public static LSub Hello{ get{ return Ice.hello; } }

  public Aisatu()
  {
    hello.Set(JibunSwitchText(
      CS(Tokieda, "こんにちは"),
      CS(Yamada,"うっす。こんちわっす。"),
      CSP(Tendo,Tokieda, "こんにちわ、時枝さん"),
      CSP(Tendo,Yamada,"こんにちわ、山田さん")));
  }
}

 LimitedSubを使うことで、自分や相手の配置に関係ない一般的なソースが再利用できる。