参議院で圧勝しているのに、総理になれなかった
衆議院の3票差の決選投票で負けた。
参議院では134対37で勝っていたのに。
「参議院にも首班指名があるのですか」と聞かれた。答えは「はい、あります」だった。
憲法67条1項は「国会の議決で、これを指名する」としていて、衆議院と参議院はそれぞれ独立に指名の議決を行う。前回まで実装していたのは衆議院の指名だけで、それは「最終的な結論は変わらないから」という理由からだった——両院が割れても、衆議院の議決が国会の議決になる(67条2項)。
だが結論が同じだからといって、そこに至る過程を見せる価値が無いわけではない。むしろ、ねじれ国会を実装した直後だからこそ、ここは埋めるべきだと思った。
参議院も同じ関数で戦える
実装は思ったより軽かった。首班指名選挙のロジック(`runInvestiture`)は、もともと「議席数」と「政党」を渡せば動く汎用的な作りにしてあった。衆議院の議席の代わりに参議院の議席を渡せば、そのまま参議院の指名選挙になる。
両院の結果を1つにまとめる関数を新設した。
- 衆議院と参議院、それぞれで指名選挙を行う
- 両院の指名が一致すれば、その場で決まる
- 割れたら両院協議会——一致する確率はごく低く設定した。実績は0/4(1948年・1998年・2007年・2008年、いずれも不調)。0にはしなかったのは、「開けば必ず不調」という台本になると、両院協議会を開く意味そのものが無くなるからだ
- 一致しなければ衆議院の議決が国会の議決になる(67条2項)
氏名で比較していた、恥ずかしいバグ
最初に動かしたとき、「両院の指名が一致した」と表示されているのに「結果:野党へ」になった。
原因はすぐ見つかった。政権を取れたかどうかの判定を、こう書いていた。
designation.designated === input.playerPartyId
designation.designatedは指名された人の名前(「岸辺 文夫」)で、input.playerPartyIdは党のID(「minji」)。名前とIDを比較していたので、絶対に一致しない。
元の(衆議院だけの)実装では、党IDどうしを比べていた。両院対応にする過程で、片方を氏名ベースの値に差し替えたのに、比較の相手を直し忘れていた。型としては両方とも string なので、コンパイラは何も言ってくれない。 実際に動かして初めて気づいた。
狙っていた画が、初回で出た
直したあとに何度か遊んでみたら、いきなり理想的な回を引いた。
衆議院の決選投票——野田川泉237票、山田太郎(自分)228票。9票差で敗れた。
同じ回の参議院——山田太郎134票、野田川泉37票。圧勝で1回目から過半数に達していた。
両院協議会は開かれたが一致せず、衆議院の議決がそのまま国会の議決になった。総理の座は野田川泉のものになり、自分は野党として次の総選挙に備えることになった。
参議院では負けていない。それどころか圧勝している。それでも、衆議院の数百票のうち9票が足りなかっただけで、政権はよそに渡る。
これがねじれ国会というものの手触りなのだと思う。「勝っている」と「政権を取れる」は、同じことではない。
参議院は指名にも組閣にも、同じ顔ぶれを見せる
最後に気をつけたのは一貫性だった。指名の画面で見せた参議院の議席と、組閣したあとダッシュボードに出る参議院の議席が、別物になってはいけない。
参議院を組み立てる関数に渡す乱数の種(seed)を、指名の時点で1回だけ引き、それを組閣(`formGovernment`)にもそのまま渡すようにした。同じ種から同じ参議院が組み上がる。指名画面で「123議席・ねじれ」と表示されたら、組閣後のダッシュボードにも同じ「123議席・ねじれ」が出る——当たり前のようでいて、seedの受け渡しを1本間違えると簡単に崩れる。
※運営者が個人で書いているnoteです。