焼き魚のお気持ち表明ブログ

お気持ち表明する自己満足ブログです。記事の正確性は保証しません。

つぶやき プログラミング 鉄道

#JAM2022 #国際鉄道模型コンベンション #山手線ゲーム2nd

投稿日:

お盆明け、コミケ明けに国際鉄道模型コンベンション21thがありました。
私は初参加でしたが、山手線ゲーム2ndのプログラムを少しだけ関わりました。改めまして、遊んでいただいた方ありがとうございました。
少しだけ関わったのと技術情報開示のある程度の許可を頂いたので、忘れないうちに関わった部分の反省及び仕組みを少しだけ公開いたします。

目次

今回関わった部分と設計思想

この画面に出ているところを担当いたしました。
お客様に見える部分で、車掌スイッチを扱うとドア開閉するし、発車メロディーを扱うと発車メロディーが鳴ったり止まったりします。

LEDは0~9 組み合わせて任意な時間を表示できるように

まずこの画面ですが、に書いて頂いたのですが、1枚絵ではなくて1つ1つのパーツがバラバラになっています。
透過画像なので下から順番に重ねていけば綺麗に並びます。
レピーター、ATOS等もベースはこれで、ATOSのLED表示はそれを組み合わせて自由に表示できるような仕組みです。

ドア開閉部分は動画です。
当初はGIFで行く予定でしたが、工数見合いで動画を全パターン出してもらってそれを組み込むことにしました。

列停やレピーター、ATOSはGIFを再生しているわけではなくて組み合わせて表現しておりました。

絵の部分の設計思想はお任せしていたので私が考えたわけではありませんが、後述に必要な説明なのでちょっと序章として書かせていただきました。
で、ここからほんの少しだけ技術的な話になります。

意外と簡単そうに見えるのですが、何だかんだで考えることが多いのが今回のプログラムです。
電車が来たら電車を表示して、ドア開けたらドアを開けて、発車メロディーを鳴らしたら発車メロディーを鳴らせばいい。言ってしまえばただそれだけですが、これらの処理を内回り外回りで同時に到着や発車メロディーが鳴っても大丈夫なように、かつプログラムのメンテナンス性を意識しながら書いていく必要があります。

お金が発生する仕事ではないので技術者として色々試そうとし、今回のこのプログラムは正直に言うと大失敗なのですが、とにかくコードの量を減らすということを目標としました。
お金が発生しないかつ、人様の目に触れるようなプログラムを書くことなど滅多にない機会です。一つの挑戦、お試しとして今回は駅の状態をビットで判断するということをしました。

状態を考えてみよう

初期状態は列車がいない

初期状態は列車がいないものとして扱います。

状態①接近

列車が接近したとき、ATOSに「電車が」「来ます」と表示します。
同時に、接近放送を鳴らします。

ATOS制御はsetInterval()で、繰り返します。
処理は


if (direction == 1) {
//外回り
if ($('#soto-densyaga').css('display') == 'block') {
// 表示されている場合の処理
$('#soto-densyaga').hide();
$('#soto-kimasu').show();
} else {
// 非表示の場合の処理
$('#soto-densyaga').show();
$('#soto-kimasu').hide();
}
}

一定間隔で無限にループさせて、「電車が」が表示されているときは、「電車が」を消して「きます」を表示。
「電車が」が非表示のときは「電車が」を表示。
初期状態は「電車が」が非表示なので「電車が」を表示。以降ループでいい感じに電車がきますを交互に表示することができました。

この時に、状態②で表示させる列車がE231かE235かを判別するためサーバーから情報を受け取ります。
なお、タグの調子が悪いとか何らかの理由で受信できなかった場合はE231と判定するようにしました。

状態②駅に到着

ドアは自動では開きません。
車両がホームトラックに突っ込んだら、画面に列車を表示させる必要があります。
状態①で取得した車両情報を参照しながら車両を駅に表示させます。

状態③駅を出発

車両がホームの次のトラックに突っ込んだら、画面から列車を消す必要があります。
また、ATOS状態、レピーターを全てリセットする必要があります。
ATOSが「延発」を指示しているときは、そのままATOSが表示されたまま出発することになりますので、この処理を怠ると永遠に延発が残り続けるバグが残ってしまいます。

割り込み処理① ATOS(延発/出発/通知)

これらはどこで来るかわかりません。適当なタイミングでどこでも来ます。
ATOS表示や列停の表示は、状態①のようなsetInterval()を駆使して再現します。

割り込み処理② レピーター/列停/ドア開閉/発車メロディーON/OFF

どちらかと言うとユーザー入力系の操作です。
割り込み処理①と同様にいつ来るかわからない処理ではありますが、どちらかと言うと入力される系、駅の状態を表すのでATOSと分けて考えます。

ビットの考え方

 

7 6 5 4 3 2 1 0
駅情報 到着 接近 レピーター点灯 ドア開 発車メロディー再生 発車メロディー停止 列停
ATOS 抑止 通知 延発 出発 接近 試験

内回りと外回りでこれらの状態を組み合わせで持つので、駅と状態はたった4つの変数で定義することができます。

たとえば、駅情報が0b00100000のときは接近。0b00110000のときは接近中でレピーター点灯、のような形で状態を表すことができます。
リセットしたければ0b00000000にすれば良いです。
ATOSも横に足せばさらに変数を減らすことができますが、流石に変数が長くなりすぎますし、8bit、オール1で255という気持ちよさが無くなるのでやめました。
ですが、これは正直失敗だったかなと思います。書き方にもよりますが、結構後で修正しようとしたときに可読性があまりないのが災いして非常にデバッグがしにくいです。

一番簡単な方法は、すべてに対して変数を持つことですが、それはそれで定義が大変ですし行数も長くなりますしそれはそれで可読性はあまり良くないので、
次があれば連想配列で作るのがいいのかなと思っています。

実はこんなものも作ってました

外回り内回りで作ったのに進行方向がめちゃくちゃだったり、そもそも線形が鏡になっていたり
ほぼ完成したと思った途端、このような大幅ミスに気がつき結局ボツとなった内部向けTIDを作成していました。睡眠って大事です。
寝てはいたものの、睡眠時間は不足気味だったという言い訳をします。

次があれば強化して、チラ見えしたときになんか本物の駅員みたい!ってなるようなものを作成しようと思います。

下にあるボタンたちは、完成していて色々なイベントを起こせるようになっていました。

抑止も起こせますし、延発、通知、列停、出発指示は完璧。

実際に在線したときは赤で表示され列番も表示できる予定でした。
鎖錠は出ませんでしたが、ここまで完璧にできたらいいなぁと思ったり。関係者が持っているとカッコいいシリーズでした。

おわりに

今回遊んでいただいた方には感謝しかありません。
更に、楽しかったというお言葉はやってよかったと達成感がありましたし、嬉しかったです。

-つぶやき, プログラミング, 鉄道

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

ブログ整理した

このブログyakizakana.netは大分昔からやっていて、AdSenseの審査も通っているんですけど、なんか微妙で、閉鎖(メンテナンス)と、再開を繰り返してきた。 結局、閉鎖したところで大した変化 …

no image

最適解は何か(Python/django/PHP/Laravel/Java/Vue.js)

何かWebアプリを作りたいなぁと思うものの、何がいいのか悩みに悩み散らかしている。 さっくり決めてやれば進むのだろうが、環境構築が最強に難しい。 一部の超できるプログラマーを除いて、アプリ屋はインフラ …

悪天候で北海道に閉じ込められたから8時間かけて鉄道で帰ってきた時の話

2019/01/05 大雪により多数の飛行機欠航・遅延が起き、私も巻き込まれました。 今後の運航の見通し(新千歳空港にて) これは、飛ばないだろうな。。と思いながら、待ちましたが、1時間後には全便欠航 …

no image

Air Koryo事情

フライトレコーダーみていると、定期便が復活しているように見える高麗航空こと、AirKoryo。 Air Koryoのホームページを見ていると、タイムテーブルのページや、予約ページ等も”形式上”復活して …

no image

Pixel6予約した

Pixel6が予約開始されましたね。 Pixelシリーズは3から触り始めて、1年おきに買い替えるくらいハマりました。Pixel3、4、5と買ってきました。 目次 中々買えないPixel6 想像以上に安 …