資料
ダウンロード

Technology > OpenJevで落ち物パズルの1手を選ばせてみた ― 文章を作らず、候補手の確率だけを読む

OpenJevで落ち物パズルの1手を選ばせてみた ― 文章を作らず、候補手の確率だけを読む

OpenJev を落ち物パズルに組み込み、各ターンで置き場所を1つ選ばせました。モデルにゲームを直接操作させているわけではありません。プログラム側で合法手を列挙し、その中のどれを選ぶかだけを聞きます。

戻ってきた候補ごとの確率から最大の手を JavaScript 側で実行し、次の盤面でも同じ処理を繰り返します。落下アニメや重力・衝突判定は JS 側です。本記事はその入出力と、手元環境での実測です。仕組みの一般論は 型付き判定コンポーネント OpenJev に譲ります。

紹介映像

※ 落ち物パズルの各手で、候補の確率を読んで着手するまで(約19秒)

今回やったこと

モデルが動かすのは「置き場所」だけです。

盤面→候補手→OpenJev(1回forward)→確率→argmax→着手(JS側)の流れ
盤面と合法手を渡し、1回の forward で候補ごとの確率を取る。最大値を JS 側で着手する。落下や衝突はモデルの仕事ではない。

OpenJev は、状況・問い・選択肢を渡すと各選択肢の確率を返します。文章や JSON は生成しません。今回使ったのはこの部分だけです。TypeSafe 社の Jev 本体の重み・学習・API は使っていません。公開モデルで同じ入出力の形を試す独立実装です。

1手を決める処理

ピースが確定するたびに、次の4段階を1回ずつ行います。

①状態を作る ②候補を列挙 ③確率を読む ④最大確率の手を hard drop
盤面をテキスト化し、回転×横位置の合法手を列挙する。OpenJev はスコアだけを読み、最大確率の候補を hard drop する。

毎回のモデル呼び出しは「候補から1つ選ぶ」に限定されています。

モデルに渡している盤面

画像ではなく、ASCII の盤面と数値を渡します。例は、中央1列だけ空いた状態に T 字ブロックが落ちている場面です。

GOAL・FALLING・NEXT・HEIGHTS などの数値と、中央が空いた ASCII 盤面
判断基準は「ライン消去を優先し、穴を少なく、低く平らに積む」。列の高さ・穴・最大高さ・凹凸も一緒に渡しています。
GOAL: clear lines, avoid holes, keep height low and even.
FALLING: T at x=3 y=0 rot=0
NEXT: I
HEIGHTS: 4 4 4 4 0 4 4 4 4 4
HOLES: 0
MAX_HEIGHT: 4
BUMPINESS: 8

....T.....
...TTT....
..........
..........
####.#####
####.#####
####.#####
####.#####

この状態に対し、回転と横位置を変えた最大16個の候補を作り、それぞれの結果も候補説明として渡しています。

代表例では16候補からこの手を選んだ

16個を評価し、drop_r2_x30.735 で最も高くなったので、その手を実行しました。

確率上位5件。drop_r2_x3 が 0.735 で最大
表示は確率上位5件。値は全16候補の中での相対値です。0.735 は「73.5%の確率で正しい」という意味ではありません。

この手は1ラインを消す一方で、穴が3つできます。今回の実験は、落ち物パズルの強さを評価するものではありません。実運用の信頼度として使うには、用途ごとの校正が必要です。

文章を生成しない

モデルに回答文を作らせていません。盤面と候補を入力したあと、生成ループには入らず、その時点の logits から必要な候補だけを読みます。

生成する場合は JSON/文章→パース。今回は1回forward→確率→argmax。生成tokenは0
記録した4手は、すべて生成トークン 0。必要なのは説明文ではなく「次にどの手を選ぶか」です。

手元の RTX 5090 環境での実測

HP OMEN / NVIDIA GeForce RTX 5090 / Qwen3.5-4B / bfloat16 / CUDA GPU 1枚で、4つの盤面を1手ずつ測りました。

1手あたりの合計時間。0.661 / 0.424 / 0.468 / 0.276 秒
合計時間は 0.276〜0.661秒。代表例(中央1列が空いた盤面・T)は 0.424秒。最初の T は起動直後の1手目で、ウォームアップを含みます。4手とも生成トークンは 0。

この数字は今回の PC と実装での実測であり、OpenJev 一般の性能値ではありません。

今回の実装で確認できたこと

確認したかったのは、落ち物パズルで強いかどうかではありません。盤面と候補手を渡して確率を取り、その値をゲームの次の処理へ渡せるかどうかです。

確認できた3点。候補手を確率で返せる、ゲームループに入れられる、生成tokenは0
各ブロックごとに1回だけモデルを呼び、文章生成なしで着手までつなげるループは動きました。短い判断を繰り返す処理では、この使い方は試しやすいです。

ロボティクスで使うなら、こういう位置

落ち物パズルの構成を、そのままロボットへ持ち込めるという話ではありません。使うとすれば、低位のモータ制御ではなく、候補がすでに決まっている短い意味判断です。

観測→候補を作る→OpenJev→しきい値(自動/確認)→次の処理
例:許可判定、証拠の過不足、モジュール振り分け。「このまま続行するか、停止するか」「どの処理へ渡すか」。落ち物パズルは、この処理の形を目で見えるようにした例です。

この実験からは言えないこと

結果を広げすぎないために、3点を分けて書きます。

対象外は Jevと同等の品質、確率=正解率、落ち物パズルが上手い
OpenJev は入出力の形を試す独立実装です。返る確率は候補内の相対値です。代表例でもラインを消す一方で穴が増えており、プレイ品質は評価していません。

言えるのは、公開モデルを使った OpenJev で「盤面 + 候補手 → 候補の確率」を組み、文章を生成せずにゲームを進められたところまでです。

まとめ

  • 候補から1手を選ぶ ― 合法手を列挙し、OpenJev は置き場所だけを選ぶ。操作そのものは JS 側。
  • 生成トークン 0 ― 1回 forward して logits から確率を読む。記録した4手は文章を1トークンも作っていない。
  • 代表例 ― 16候補から drop_r2_x3(0.735)。相対値であり、正解率ではない。
  • 実測 ― RTX 5090 環境で1手 0.276〜0.661秒。一般性能の主張ではない。
  • 位置づけ ― 短い意味判断のデモ。モータ制御の置き換えでも、プレイの上手さの評価でもない。

説明は生成AI、判定は確率。落ち物パズルは、その判定をゲームの1手として見せた例です。デモやご相談を承っています。

この技術や導入について、お気軽にご相談ください。

お問い合わせ・ご相談はこちら
一覧に戻る

CONTACT US

RECRUIT