【マイレース開発記録(11)】zone判定の設計崩壊                      

ここまでの開発で、
「うさぎの速さ」と「ジャンプの高さ」は計算できるようになりました。

しかし、ここで大きな問題が残っていました。

その結果を、どう意味づけるのか。

レースが動くだけでは、ただのアニメーションです。
「今日はどういう日なのか」を表すための、
ゾーン(流れの質)を設計する必要がありました。

マイレースでは、
レース結果をただ順位として表示するだけではなく、

その日の「流れの質」を
ゾーン(Zone)として表現しています。

現在の設計では、ゾーンは次の4種類です。

  • 追い風ゾーン(外の流れも内側のリズムも良い)
  • 慎重ゾーン(流れはあるが無理は禁物)
  • 楽しさ重視ゾーン(気分や好奇心を優先)
  • 整えるゾーン(休息・回復を優先)

それぞれのゾーンは、

  • 外側の流れ(スピード)
  • 内側のリズム(ジャンプ)

この2つの組み合わせから決まります。

最初は、かなり単純に考えていました。

ゾーンは次の2つの要素で決めることにしました。

  • スピード(外側の流れ)
  • ジャンプ(内側のリズム)

つまり





速い × 跳ねる → 追い風
速い × 跳ねない → 慎重
遅い × 跳ねる → 楽しさ
遅い × 跳ねない → 整える

コードとしては、こんな形です。

def detect_zone(is_fast: bool, is_jump: bool) -> str:
if is_fast and is_jump:
return "tailwind"
if is_fast and not is_jump:
return "steady"
if not is_fast and is_jump:
return "playful"
return "rest"

一見、問題はなさそうに見えます。

しかし、ここから問題が起き始めました。

アプリを動かしてみると、すぐに違和感が出てきました。

ユーザーの入力を変えても、

ゾーンがやたらと偏るのです。

特定のゾーンばかりが出る。

別のゾーンはほとんど出ない。

これは占いとしても、UIとしてもかなり不自然でした。

調べてみると、
問題は is_fast の判定方法にありました。

最初の実装では、

平均スピードより速いかどうか

で判定していました。

JavaScript側ではこう書いていました。

const avg = rs.map(x=>st.t[x.k]).reduce((a,b)=>a+b,0) / rs.length;
const isFast = st.t["work"] <= avg;

つまり、

平均より速いかどうか

だけで判定していたのです。

しかしこれには大きな問題がありました。

レースには5匹のうさぎがいます。

平均値を使うと、

必ず

  • 速い側
  • 遅い側

が生まれます。

つまり、

「普通」という状態が存在しない

のです。

結果として、ゾーン判定がかなり極端になりました。

ここでAIと一緒にコードを整理しました。

まず行ったのは、

状態を分解することです。

  • スピード
  • ジャンプ
  • フェーズ

をそれぞれログに出して確認しました。

この段階で初めて、「どこが歪んでいるか」が見えてきました。

私は開発の中で、

  • 状態が複雑になる
  • 複数の条件が絡む

という場面になると、

どこが原因なのか分からなくなる

ことがあります。

今回のゾーン問題も、最初は完全に混乱していました。

ですがAIとの対話を通して、

  • 条件を一つずつ分離する
  • ログを出して確認する
  • 仮説を立てて検証する

という手順を整理することができました。

このプロセスは、私にとって非常に大きな助けになっています。

最終的に、ゾーン判定は

2つの軸

で整理することにしました。

外側の流れ

天体トランジット → スピード

内側のリズム

位相フェーズ → ジャンプ

この2つの軸を掛け合わせることで、4つのゾーンが自然に分かれる形になりました。

今回のゾーン問題は、完全に設計ミスから始まりました。

しかしこの経験を通して実感したのは、設計は最初から正解にならない

ということです。

実装して
動かして
崩れて
修正する。

その繰り返しで
やっと形になっていきます。

ゾーン判定を整理したあと、今度は別の問題が起きました。

コードの中に、同じ関数が2回定義されているというバグです。

しかもその関数は、今回のゾーン判定の中心でした。

次の記事は、

【マイレース開発記録(12) detect_zoneの二重定義事件】

として、

バックエンドとフロントのロジックが衝突した話を書きます。

\ 最新情報をチェック /

コメントを残す

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