以下の内容はhttps://lipoyang.hatenablog.com/entry/2026/02/13/195607より取得しました。


組込み屋でもアプリがしたい!【形四】 第9局

いよいよWebアプリ版の形四アプリを作っていきます。

基本設計メモ

  • 仕様はすでにある C#版アプリ(KCSharp) と同等とする。
  • 画面表示、UI、ファイル入力の処理は JavaScript で記述する。
  • 局面データ、思考エンジン等の内部ロジックは Rust で記述して WebAssembly にコンパイルする。
  • すでにあるC#版のソースを JavaScript と Rust に移植する。
  • UIの見映えを良くするため、フレームワークに Bootstrap を利用する。
  • PC等の横画面とスマホ等の縦画面でレイアウトを切り替える。
    (横画面なら左に盤、右にボタン類。縦画面なら上に盤、下にボタン類。)

詳細設計メモ (1) UIのデザイン

  • HTML, CSS で記述する。(index.html と webkc.css に記述する)
  • Bootstrap を利用してボタン等を見映えの良いスタイルにする。
  • スマホでも適切に表示されるように下記を head に記述する。
  <meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
  • 画面を盤面部とフォーム部(ボタンやセレクト類)に分け、各々をdisplay: flex なdiv要素とする。
  • 横長画面であれば、盤面部とフォーム部は flex-direction: row (横並び) とする。
  • 縦長画面であれば、盤面部とフォーム部は flex-direction: column (縦並び) とする。
  • 盤面部とフォーム部が画面内に収まり、かつPCの画面で盤が大きすぎないように盤の大きさを調整する。
  • これらのレイアウト制御は、後述のJavaScriptにて、document の DOMContentLoaded イベント、および window の resize イベントの際に実行する。

詳細設計メモ (2) UIのロジック

  • JavaScriptで記述する。
  • C#版の FormMain.cs と Kifu.cs から移植する。
  • FormMain.cs (フォームのクラス) から UIの処理を webkc.js に移植する。
  • Kifu.cs (棋譜クラス, 初期局面クラス) を kifu.js に移植する。
  • C#版では、思考エンジンは Task.Run( ) を用いて別スレッドで実行している。
  • JavaScriptは基本的にはシングルスレッドだが、Web Workerを用いれば別スレッドで実行できる。
  • ワーカースレッド側の処理は work.js に記述する。
  • メインスレッドとワーカースレッド間のやりとりは postMessage( ) でおこなう。
  • Rustの構造体は下記のようにして取り込んで使用する。
import init, {Position, Move, Board, DaiPunch} from "./pkg/webkc_rust.js";
  • Rustの構造体は、init() の完了を待ってから使用すること。(new することも含む)
  • Rustの構造体はpostMessage( )で送ることができない。
  • Rust側でシリアライズ / デシリアライズ するのがエレガントぽいが、
    今回は通常のオブジェクトに値を積み替えて送ることにする。
  • Rustの構造体のコピーには、Rust側で定義した clone_js() を用いる。(後述)
  • 盤面の canvas のイベントは、マウスとタッチに両対応するため、pointerdown イベントを受ける。
  • C# の MessageBox の移植には、alert() は見栄えがあまり良くないので、Bootstrap の div class="modal fade" を使用する。
  • div class="modal fade" は index.html の body の末尾あたりに記述し、JavaScript で show() する。

詳細設計メモ (3) 内部ロジック

  • Rustで記述してWebAssembly (WASM) にコンパイルする。
  • JavaScript側から呼び出すためのラッパ ./pkg/webkc_rust.js が生成される。
  • Board.cs (位置構造体, 着手構造体, 盤面構造体, 大パンチ判定クラス) を board.rs に移植する。
  • Engine.cs, Engine_AB_SKR.cs (思考エンジンクラス) をengine.rs に移植する。
  • JavaScript側に公開する構造体には #[wasm_bindgen] を指定する。
  • 位置構造体, 着手構造体には、Clone, Copy, PartialEq, Eq をderiveする。
  • 盤面構造体には、Clone, Copy をderiveする。
  • clone() はJavaScript側には公開されないので、clone_js() でラップして公開する。
  • JavaScriptからオブジェクトを引数で渡すときは参照渡しとする。
  • JavaScript側には公開できないが Rust側では pub にしたいメソッドは、implブロックを分ける。
  • Rustの構造体の関連定数 (pub const で定義される、クラス定数のようなもの) は、
    JavaScriptに対応する概念がないので、JavaScript側に公開する構造体には持たせられない。
  • 必要であれば、Rust側で定数として定義して、関数を経由してJavaScript側に取得させる。
  • C#版では、再帰関数内でListを生成するコストを避けるため、静的に確保した配列をSpanで切り出して渡している。
  • Rustで同様の記述をすると、自己借用 (self の二重可変借用) のためコンパイルエラーとなる。
  • ひとまず、構造を大きく変えずに対応するため、ローカルで配列を定義する形に変更する。
  • C#版では、EngineクラスをEngine_AB_SKRクラスが継承している。
  • Rustでは、ひとまず一体物のEngine構造体として実装する。(Rustには継承がないので。)
  • C#版では着手の変数名を move としているが、Rust では move は予約語であることに注意。

Rustの開発環境について

Rust / WebAssembly の開発環境については下記の記事を参照。

wasm-packのインストール
cargo install wasm-pack
プロジェクトの作成
cargo new --lib プロジェクト名
コンパイル
wasm-pack build --target web
クレートの追加

例えば乱数発生器のクレート rand をプロジェクトに追加するには、

cargo add rand

これにより Cargo.toml の [dependencies] に記述が追加される。




以上の内容はhttps://lipoyang.hatenablog.com/entry/2026/02/13/195607より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14