RumiCar シミュレータ v10.4.0 を公開しました。リリースノートは GitHub でも読めます。
v10.4.0
質問・提案の投稿で普通の言葉が弾かれる件・走行中に設定を変えたときの表示・順位表の並び・表示のエスケープ漏れ・キーボード操作・ライブ走行の loop() の呼び出し回数・学習プログラムのエラーを直しました (Stage BL・走行物理の式は無改変です — 出荷の公式サンプル大会の結果は変わりません。公式サンプル大会の verifyHash e9f1da0b と凍結ハッシュ f0〜f3 は改修前と同じで、出荷の見本プログラムの出力も改修前と同じです)。ライブ走行 (▶) の走りと、あなたのプログラムの動きが変わることがあります — 下の ⑥ と ⑦ を確かめてください。① 質問・提案の NG ワード判定 — 英字の語は語として判定し (前後が英数字なら別の語)、2 文字以下の日本語の語は前後が同じ文字種なら一致としないようにしました。v10.3.0 は「カスタム車種を作りたい」「cockpit view が欲しい」「Essex のコースを作った」「Dickens」「die hard な設定」を投稿前に拒否していましたが、通るようになりました。攻撃表現は引き続き拒否します (判定する語を 39 → 54 に増やし、「バカッ!」「アホー!」のように小書き仮名や長音の付いた形も拒否)。続けて書いた合成語が通ることや、無害な文が拒否されること (「少しね」「勢いを殺す」など) が残ります (moderate.js の冒頭に一覧しました)。② 走行中の設定変更 — 走行中にコース・タイヤ・ギア・サスペンション・ステア・ブレーキ・摩耗・物理モード・走行領域を変えると走行は止まりますが、v10.3.0 では車両カードがコード表示のまま固まり、エディタに戻りませんでした。■ を押したときと同じ止め方に揃えました。③ 順位表と大会 — 走行中の順位表で、同じ周回の車は先に線を越えた車を上に並べます (v10.3.0 は現周回の経過時間が短い車=後ろの車が上でした)。峠でゴールした車どうしは合計タイムの短い順です。同じ作者が複数のエントリーを出した大会で、📖 ショーケースと 👻 の相手がその作者の 1 件目を引いていたのを、名前で引くようにしました。👻 の再走は大会の物理・試走・摩耗の設定で走らせます (v10.3.0 は画面でいま選んでいる物理・試走なし・摩耗なしで走らせていた=👻 の結果が変わることがあります)。読めない値を含むエントリーのある大会の再実行検証は、黙って止まらずに「⚠ この大会のエントリーに読めない値があるため、再実行できませんでした」と出します。④ 表示のエスケープ — 自作車種・投稿車種の値と大会の結果の値の一部を、車種の表・編集フォーム・🏆 の詳細でエスケープせずに HTML に入れていました (値に <img src=x onerror=…> を書くとスクリプトが動きました)。文字列にできない値 ({"toString":1} など) を含む大会・投稿でも 🏆 の詳細・再実行検証・🍴・🏅・👻 が途中で止まらず、続けられないときは「【エラー】…」の 1 行を出します。⑤ 表示とキーボード操作 — 大きな画面のプログラム編集の背景が透明で後ろの画面が透けていたのを、他のダイアログと同じ背景にしました (glass テーマは他のダイアログと同じ半透明で、背後を暗く 2px ぼかします)。峠の立体プレビューの文言は英語表示でも英語になります。ファイルを選ぶ操作 (⬆・JSON 読込・📥 バックアップを読み込む) に Tab で届き、Space で選べるようにしました (v10.3.0 はマウスでしか選べませんでした)。⑥ ライブ走行の loop() — ライブ走行 (▶) で loop() を sim 時間 (画面の時計) 1 秒あたり 20 回呼ぶようにしました。v10.3.0 は 1 フレームに 1 回までで、1 フレームが 0.05 sim 秒を超えると回数が減り (30 fps × 速度 3× で約 10 回/秒。60 fps × 3× でも 1 フレームが 16.7 ms を超える分だけ減って実測 17.4〜18.2 回/秒)、呼べなかった分が「借り」として溜まって、画面が軽くなった後や速度を 1× に戻した後に毎フレーム呼ばれていました (約 60 回/秒)。いまは 1 フレームの sim 時間を 0.05 秒の区間に刻み、区間ごとに「期限の来た車の loop() → その区間の物理積分」を繰り返します (1 フレームの loop() は 1 台 3 回まで。画面で選べる条件では上限に当たりません)。2 回目以降の loop() はその前の区間を進めた後の姿勢とセンサーで呼ばれ、delay() も借りに飲まれずに効きます。負の delay() の借りは 1 周期を超える分を捨てます (負の delay をときどき呼ぶプログラムは 60 fps × 1× でも呼ばれる回数が変わります)。loop() は期限の来た区間の始まりで呼ぶので、間隔は一定ではありません (0 より長く 0.1 秒+delay 以下・平均は 0.05 秒+delay)。1 フレームが 0.05 sim 秒を超えるとき (低 fps のときや、既定の速度 3× で 1 フレームが 16.7 ms を超えたとき) は、同じプログラムでもライブ走行の軌跡が v10.3.0 と変わります — 壁に当たったときに残りを壁際で待つこと・自動復帰の後退・発走の順番待ち・逆走の向き直し・周回の判定が区間ごとに働くためで、壁への接触・自動復帰・向き直しが起きた時点から分かれます。1 フレームが 0.05 sim 秒以下 (60 fps で速度 1×・2× など) なら従来と同じです。公式レース (🏁) は固定 60Hz の決定論エンジンなので関係しません。⑦ 学習プログラムのエラー (py・C) — v10.3.0 でエラー無しで走っていたが v10.4.0 でエラーになる書き方 (多くは python3 でもエラーです): random.choice([])・random.choice("")・数や dict の random.choice (v10.3.0 は値なし=print は空行)、len(a, b)・random.choice(a, b) (v10.3.0 は 1 つ目だけを使いました。引数の数を数えるのは py・C のプログラムに書いた呼び出しだけで、JavaScript のプログラムと ["ab", "c"].map(len) のように別の関数が呼ぶ形は v10.3.0 と同じく 1 つ目だけを使います)。エラーの文言・行が変わった書き方: len(None)・len(5) (日本語固定・行番号なし → 表示言語・行番号付きの「len() には list・tuple・str・dict を渡してください (None には長さがありません)」)・len() と random.choice() (日本語固定・JS のエラー →「len() には引数を 1 つだけ渡してください (0 個渡されました)」。random.choice() も同じ形)・random.choice(None) (JS の「Cannot read properties of null …」→「random.choice() には list・tuple・str を渡してください …」)・深く入れ子にした list の str()/print() を while True: 型のプログラムや関数の外で行ったとき (JS の「Maximum call stack size exceeded」・行番号なし → 行番号付きの「入れ子が深すぎます (実行環境の呼び出しスタックが尽きました)。…」)・def loop() の中や上限 200 段より手前でスタックが尽きる再帰 (「呼び出しの入れ子が 1 段に達しました」のような実態と違う段数 → 同じ「入れ子が深すぎます」。上限 200 段に達したときの文言は従来どおり)・ループの条件で出たエラーの行 (while の 2 回目以降の条件・C の for の条件と更新部・do-while の条件。本体の最後の文の行 → そのループの行)・elif/else if の条件で出たエラーの行 (最初の if の行 → その行)・ステップ上限 (無限ループ) のエラーで、上限を越えた 1 歩がこれらの条件の中の関数の呼び出しのとき (→ そのループ/elif/else if の行。条件に関数の呼び出しの無いループは従来と同じ行)。dict の真偽 (if d:) と len(d) の値は v10.3.0 と同じです。変えていないこと: 走行物理の式・公式レース (🏁) の決定論エンジン (⑦ の書き方を使うプログラムはエラーで止まるようになります)・出荷の見本プログラムの出力・エラーの出ないときの実行位置の表示。直した項目と残る差は物理モデル解説 §0 (loop() の呼び出し) と §9 (学習プログラムの言語意味論) に書きました。このほか、常設の検証ゲートを 80 → 81 本にしました (wf_bl1_ui.mjs)。
