登場人物の一般化 A to Z(3)
P1P2は二つのC1P2に分解できる。D1D2D3は三つのC1D2D3に分解できる。
この分解を「正規化」と呼んでいる。もちろん俺の造語だ。
P1P2はどちらかが主人公になる。P1P2のキャラ定義を正確に書けば、自分が主人公の時相手はNPC、自分がNPCのとき相手は主人公、となる。自分がAのとき相手はBという形で、キャラ定義がキャラ数の二乗になる。
こうなるとジャンプ可能かどうかや、分岐がキャラを尽くしているかどうかのチェックルーチンも二乗の処理になる。実際はビット演算ができるのでO(N)の処理だが、これはもったいない。
自分は誰、相手は誰、という形で固定できるようにすれば、O(1)の処理に出来る。C1P2やC1D2D3ならばO(1)に出来る。また、自分を主人公に固定することでいくらか分かりやすくなる。
class 顔にUnkoを投げつける : P1P2Episode<顔にUnkoを投げつける> { public 顔にUnkoを投げつける() { Start.Set( Normalize(投げつける側.Start, 投げつけられる側.Start) ); } class 投げつける側 : C1P2Episode<投げつける側> { public 投げつける側() { Start.Set( JibunText("ウンコを喰らえ!!"), If(delegate{ //ウンコを避けるかどうかのアルゴリズム }, TrueBlock( AiteText( CS(Yamada,"そんなウンコくらわんでゴンス!"), CS(Tendo,@" 手に持った排泄物、目線の動き…@ あなたの狙いは見え見えよ。そんな排泄物、私が喰らうと思って!?") ), Base("ウンコは避けられてしまった!!") ), FalseBlock( Base("ウンコが顔に当たった!!"), AiteText( CS(Yamada,@" め、目が見えないでゴンス!! 猛烈な異臭がするでゴンス!!"), C(Tendo, AiteText(@" 私の顔に排泄物を投げつけるなんて!! どうなるかわかっているの!?"), JibunText("さあ?&教えてもらいたいね。"), AiteText("演歌界の総力を結集して、あなたを潰すわ!!") ) ) ) )) } } class 投げつけられる側 : C1P2Episode<投げつけられる側> { public 投げつけられる側() { Start.Set( AiteText( CS(Yamada, "おいどんのウンコを喰らうでゴンス!!"), CS(Tendo, "私の排泄物を味わいなさい!!") ), Select("ウンコを投げつけてきた!!", S("避ける",yokeru), S("避けない",yokenai) ) } Act yokeru = new Act(); Act yokenai = new Act(); Construct Yokeru() { yokeru.Set( JibunText("そんなもの喰らうかよ!!"), Base("ウンコを避けた!!") ) yokenai.Set( JibunText(@" やったー!! ウンコ大好き!!"), Base("時枝は思うさまウンコを味わった。") ) } } }