ミニハンド技術情報

(C) boco_san (ぼこさん) 2006/04/01

  このページからは,次のファイルをダウンロードできます。
     MiniHandTechInfo.zip (33kB)
  この中には,VB (Visual Basic) で書かれた2個のソースプログラム
  納められています。
  これらのプログラムでは,VB を使って
  (1) FTP によりファイルをアップロードする
  (2) ウィンドウをキャプチャーして,ビットマップを読み取る
ための方法を説明しています。

  (3) また,末尾には,ミニハンドを作成した経緯を書き加えました。

 《 使い方 》
  上のファイルをダウンロードして,何か一つのフォルダの中に
  すべて解凍して下さい。
  そして,Upload.vbp, CaptWin.vbp を実行します。
  VB のバージョンは,5.0 または 6.0 に対応しています。
  なお,一緒に入っている実行ファイル Upload.exe, CaptWin.exe は Ver 6.0 でコンパイルされています。

(1) FTP によりファイルをアップロードする

 FTP によるアップロードには,次の3通りの方法があります。
  1. Windows に内蔵されている FTP.exe を使用する。
  2. WinINet の FTP ファンクションを使用する。
  3. WinINet の FTP ファンクションを PASV (Passive mode) で使用する。
  このように3通りの方法がありますが,あなたのプロバイダ(または環境)が FTP 接続を PASV に限定している場合には, 3番目の方法しか使えません(この環境が,多いようです)。
  もしも,この限定がなければ,3つのどの方法も使えます。

  プログラム Upload.vbp を実行し,そのソースプログラムを読むことにより,この手順を理解することができます。 Upload.vbp の実行画面

右側に示すのは,その実行画面 ( の右半分) です。
 アップロードを実行するためには,3つのデータ
 (a) サーバーのアドレス
 (b) ログイン ID(ユーザー名)
 (c) パスワード
を指定する必要があります。これらを,それぞれ,テキストボックスに記入します。
  ここでは,サーバーのアドレスとして,Geocities のアドレスが既に記入されています。したがって, あなたのホームページが Geocities にある場合には,これをそのまま使えます。しかし,Geocities 以外の場合には, これを書き換える必要があります。

  上の3つのデータを記入した後,下のリストボックス内の4個のファイルのどれかを クリックすると,そのファイルがアップロードされます。
  アップロードの方法は,上に説明した3通りがありますが,オプションボタンによりこれを選択できるようになっています。
  なお,FTP.exe によりアップロードして,その実行状況を確認したい場合には,「画面を閉じない」設定にします。そして, DOS 窓に表示される経過を確認した後で,自分で DOS 窓を閉じます(あるいは,“bye”とキー入力します)。

  次に,アップロードできたことを確認してみましょう。
  それには,画面の左側を使います。
  画面の左側には,いくつかの URL がリストボックス内に表示されており,どれかを(シングル)クリックすると,そのサイトが インターネットエクスプローラにより表示されるようになっています(この仕組みも,プログラムを読めば,理解できるでしょう)。
  このリストボックスにあなたのホームページのアドレスを追加するには,最下行のテキストボックスを利用します。テキストボックスに アドレスを記入して,Enter キーを押します。たとえば,Geocities の場合には
   http://www.geocities.jp/ログインID/HandN.htm
のように記入します。Enter キーを押すと,このアドレスがリストボックスに追加されるので,それを早速クリックします。 さきほどアップロードしたファイル HandN.htm をあなたのサイトで無事に見られれば,アップロードが成功したことを確認できます。

リファレンス
  (1) 15 Seconds: Creating an FTP Componet in Visual Basic (Jeff Niblack, 1998/03/12)
  (2) WinInet の API を利用した FTP の実装,VBFTP.exe (Microsoft, 2000/08/15)

(2) ウィンドウをキャプチャーする

  ビッドやスコアを読むには,まず,それぞれのウィンドウをキャプチャーする(画像のまま取り込む)必要があります。
  これには,次の2段階の作業が必要です。
  1. タイトルバーの文字を手がかりにして,ウィンドウのハンドル(32 ビットの整数)を取得する。
  2. ハンドルを指定して,ウィンドウをキャプチャーする。
CaptWin.vbp の実行画面

  これらの作業手順は,プログラム CaptWin.vbp を実行し,そのソースプログラムを読むことにより理解できます。

  右側に示すのは,その実行画面(の右半分)です。
  リストボックスの中には,ミニハンドが読み取りたいウィンドウのタイトル名が示されています。 このどれかをクリックすると,そのタイトルを持ったウィンドウが(もしも開いていれば)キャプチャーされます。 もちろん,そういうタイトルを持つウィンドウが開いていなければ,キャプチャーできないので,その場合には
    ウィンドウが見つかりません
というメッセージが表示されます。
  このプログラムでは,実際にキャプチャーされたことを確認するために,ウィンドウの画像をそのまま描いています。 2倍に拡大して描画することもできます。

  ウィンドウをキャプチャーする場合には
  (a) タイトルバーと枠を含むウィンドウ全体をキャプチャーする,
  (b) 内部の領域(クライエント領域)だけをキャプチャーする,
という2通りの選択があります。実際に実行してみると,その違いが分かるでしょう。
  ウィンドウの枠やタイトルバーのサイズは,Windows のバージョンとユーザの設定によりいろいろに変わります。 ミニハンドが読み取る必要があるのは,クライエント領域だけです。

(3) ビットマップを読む

ビットマップの画面   ビットマップを読むには,その構造を知っておく必要があります。 例として,6×5 のビットマップを考えましょう。ここでは,横のピクセル(画素)数が
     iWidth = 6
であり,縦のピクセル数が
     iHeight = 5
です[ このようなサイズの値は,API を利用して知ることができます]。この 30 ピクセルの色が,どの順序で メモリーに納められているかが問題です。
  24 ビットのビットマップによりデータを転送してもらうと,1行 6 ピクセルのデータは,下図のように 与えられます。図から分かるように,各ピクセルは,B, G, R の連続する 3 バイトにより表現されます。そして,1行の 長さ(バイト数)が 4 の倍数になるように,末尾に 0 が詰められます。
  この結果,1行が占めるバイト数 xLength は
    xLength = iWidth * 3
    If xLength Mod 4 Then
     xLength = xLength + (4 − (xLength Mod 4))
    End If
により与えられます。
  ビットマップの読み取りを複雑にしているのは,ビットマップが上下に反転したパターンで メモリーに納められているということです。したがって,右上の図で左上隅と右下隅のピクセル座標をそれぞれ
     (x,y) = (0, 0)
     (x,y) = (iWidth − 1, iHeight − 1)
とすると,一般の位置 (x,y) のピクセルの RGB は
    k = (iHeight − 1 − y) * xLength + x * 3
    R = PxBuf(k + 2)
    G = PxBuf(k + 1)
    B = PxBuf(k)
により得られます。プログラム CaptWin.vbp では,このようにして読み取った RGB値を使って ウィンドウを描画しています。
  なお,配列 PxBuf( ) は,ビットマップのデータを読み込んだ配列であり
    ReDim PxBuf(0 To xLength * iHeight − 1) As Byte
により(再)定義されています。

(4) ビットマップフォントを読み取る

  こうしてビットマップを読めるようになると,次に,「そこから文字情報をどうやって読み取るか」が問題になります。
  それには,キャプチャーして得られたビットマップを調べて,各文字がどういうビットマップフォントで 表現されているかを丹念に収集します。
  たとえば,ヤフー! ブリッジ の 『最後のハンド』 の画面では,“b”という文字が
     00000
     10000
     10000
     10000
     11110
     10001
     10001
     10001
     10001
     01110
     00000
     00000
という 5 列 12 ビットのパターンにより表現されています。この 5 列は,12 ビット 2 進数の並び
   2044, 132, 132, 132, 120
に置き換えることができます。したがって,12 ビットごとに一つの数に置き換えて,左から順に1列ずつビットマップを スキャンしていき,この 5 個の数字の列に出会ったら,“b”が見つかったと判定します。
  ヤフー! ブリッジ/スペード の場合には,111 個の文字のビットマップフォント (漢字を含む) を集めることが必要になります。
  ただし,JRE までサポートすると,フォントの個数は増えて,全部で 298 個になります。JRE 対応では, カーニング(隣接する複数個の文字の喰い込み,融合)を読み取る必要があるので, この作業は複雑です。
  これに加えて,各プレイヤーがどこに座っているかを自動判別するために,太い文字のプレイヤー名も 大画面から読み取る必要があります。 画面から分かるように,これらの太文字では,かなりのカーニングが発生します。 とても面倒な作業であり,サポートしきれないので,Ver 2.0 からは,この読み取りを止めました。 そして,代りに,ニックネームを INI ファイルに登録していただくように変更しました。
  また,最後のトリック などのボタンの位置を探すために, 漢字フォントが必要ですし,欧州語では,Última mano, Enchères du bridge なども読みます。
  以上のほかに,スペードでは 52 枚のカードのビットマップ 104 個(縦と横で 2 倍になる)を読み取ります。

  これらのビットマップフォントは,ソースファイル MiniHand.lzh の中のフォルダ Font に納められています。 ブリッジ,スペード以外にも ( たとえば,大富豪,ハーツ用の ) ソフトウェアを作るのにも役に立つでしょう。

 最後に,RGB の値から,ビットの On / Off をどう判定するかに触れておきます。
 読み取る文字が黒であれば,R, G, B のどれを使っても同じです。たとえば

    If R < 128 Then
     Bit = 1
    Else
     Bit = 0
    Endif
とすれば十分です。ところが,太い文字のプレイヤー名では,赤と青が使われています。 このため,上のようにすると,赤で表示されたプレイヤーの名前が 読み取れません。さいわい,緑色で表示される名前は無いようなので,R の代りに G を(共通に)使えば, 問題は無いようです。
JRE のカーニングについて

  JRE では,フォントをきれいに表示するために,カーニングがなされています。カーニング (kerning) とは, たとえば,“f w”を表示するときに,“f ”の庇 (ひさし) の下に“w”を食い込ませて,“fw”と表示する方法です。極端な場合には, “Duffy”のように 連続してカーニングが発生します。
  ミニハンドは,このようなカーニングも精一杯読み取ります。

  なお,上では 24 ビットのビットマップを説明しましたが,現在のバージョンのミニハンドでは, メモリー節約のため,16 ビットのビットマップによりキャプチャを行っています。 この場合,3 色は それぞれ 5 ビット(0〜31)で表現されます。


《 ミニハンド作成のいきさつ 》

  ミニハンドを開発した経緯を,ここに書き留めておきたいと思います。
  2001〜2006年の間,ヤフー! ブリッジの交流ラウンジで,初級者のための ブリッジ教室のアドバイザを,毎週 1〜2 回,務めていました。そこでのいろいろな質問とハンド記録から生まれたのが, このホームページです。
  ところが,ブリッジ教室には,ポストモーテム(Post-Mortem,局後検討)が欠かせません。 それには,終ったばかりのディールについて,各人がハンド記録を持っている必要があります。
  そのために作成したソフトウェアが,ミニハンド (MiniHand, Ver 1.47) です。
ミニハンドは,今終ったばかりのディールの記録を,私のホームページへ 即座に自動アップロードする機能を備えています。これにより,丁寧なポストモーテムが 可能になりました。また,この記録を振り返ることが,私自身にとっても勉強になりました。
  そして,2006年 2月の初頭には,スペード愛好家の ふぁ(fa) さんから,「ミニハンドをスペードでも使えないか」 というお話が舞い込みました。 それがきっかけで,スペード用ミニハンド (MiniHandS, Ver 1.33) を作りました。
  その後,ブリッジ教室を続けられなくなり,ミニハンドの開発も中断しました。
  再開発を始めたのは,2009 年です。
  2009 年 5 月には,ほぼ完成したので,世界中の人にお使いいただくため, すべての Yahoo! サイトに 7 ヶ国語で ( スペードは 5 ヶ国語しかない) 対応し, 国外のサイトにも登録しました。
  Ver 2.0 のミニハンドは,ブリッジ用もスペード用も, (当初は思いもつかなかったほど) みごとな仕上がりです。ほとんど 空気のような感じで ( 使っていることを意識せずに ) 使えます。

(C) boco_san (ぼこさん)