テキスト碁盤入出力機能作成方法  (2000-10-21)
棋譜管理などに便利なテキスト碁盤入出力機能作成方法を解説します。
トップに戻る  その他講座(未整理)に戻る
これはNIFTY FIGOM (ふぃご村) 【囲碁ソフト作成者情報交換】会議室に掲載したものです。

  【局面保存】

 // 石のコードがこのように定義されているとする
 #define KUU  0
 #define KURO 1
 #define SIRO 2
 #define KABE 3

 // 出力のベースとなるテキスト盤面
 char  textban[][42] =
 {
   "  ABCDEFGHJKLMNOPQRST",
   "1・−−−−−−−−−−−−−−−−−・",
   "2|+++++++++++++++++|",
   "3|+++++++++++++++++|",
   "4|++・+++++・+++++・++|",
   "5|+++++++++++++++++|",
   "6|+++++++++++++++++|",
   "7|+++++++++++++++++|",
   "8|+++++++++++++++++|",
   "9|+++++++++++++++++|",
   "10|++・+++++・+++++・++|",
   "11|+++++++++++++++++|",
   "12|+++++++++++++++++|",
   "13|+++++++++++++++++|",
   "14|+++++++++++++++++|",
   "15|+++++++++++++++++|",
   "16|++・+++++・+++++・++|",
   "17|+++++++++++++++++|",
   "18|+++++++++++++++++|",
   "19・−−−−−−−−−−−−−−−−−・",
   "",
 };

 // テキスト盤面上に配置する文字列
 char* textisi[] = { "", "●", "○", "", }

 // 盤面データが入っているものとする
 BYTE  ban[21][21];

 // テキスト出力関数
 void textbanout(BYTE* ban, int type)
 {
   int   data;
   char  textbanbuffer[21][42];

   memcpy(&textbanbuffer[0][0], &textban[0][0], 20 * 42 + 1);
   for (y = 1; y <= 19; y++)
   {
     for (x = 1; x <= 19; x++)
     {
       data = *(ban + y * 21 + x);
       if ((data == KURO) || (data == SIRO))
         *(short *)(&textbanbuffer[y][x * 2]) = *(short *)(&textisi[data][0]);
     }
   }

   // ここでファイル出力またはクリップボードにコピーすればよい
   // まとめることもできるけど別々のほうが判りやすいかも。
   if (type == 0)
   {
     // ファイルの場合は
     // ファイルをオープンして
     for (y = 0; y <= 19; y++)
       // &textbanbuffer[y][0] が文字列なのでそのままファイルに出力
     // ファイルをクローズ
   }
   else
   {
     // クリップボードの場合は
     // クリップボードを CF_TEXT 形式で確保するなどして
     for (y = 0; y <= 19; y++)
     {
       textbanbuffer[y][40] = '\r';
       textbanbuffer[y][41] = '\n';
     }
     // &textbanbuffer[0][0] をコピー処理する
     // クリップボードを解放するなどする
   }
 }


  【局面読み込み】

 // すこしややこしいかもしれませんので説明だけ。

 1 読み込んだ行の先頭からの半角空白、全角空白をすべてカット。

      これでこの行の先頭には半角空白、全角空白はなくなる。

 2 1の処理後、その行の次の2文字または1文字を下記のような文字列と比
    較してY座標を求める。
    "10"  "j" なら Y = 10
    "11"  "k" なら Y = 11
    "12"  "l" なら Y = 12
    "13"  "m" なら Y = 13
    "14"  "n" なら Y = 14
    "15"  "o" なら Y = 15
    "16"  "p" なら Y = 16
    "17"  "q" なら Y = 17
    "18"  "r" なら Y = 18
    "19"  "s" なら Y = 19
    "1"  "01"  "1"  "a" なら Y = 1
    "2"  "02"  "2"  "b" なら Y = 2
    "3"  "03"  "3"  "c" なら Y = 3
    "4"  "04"  "4"  "d" なら Y = 4
    "5"  "05"  "5"  "e" なら Y = 5
    "6"  "06"  "6"  "f" なら Y = 6
    "7"  "07"  "7"  "g" なら Y = 7
    "8"  "08"  "8"  "h" なら Y = 8
    "9"  "09"  "9"  "i" なら Y = 9
    その他の場合は行を無視して次の行の処理に移る 1へ

      10行目分からチェックするのがミソです。これで正しい盤面データ
      なら正しいY座標を返す。2行目からでもいいかな・・・

 3 2の処理後、その行の次から2文字ずつ見ていく。19回かまたは文字列
    がなくなるまで。終われば 1へ
    '●'  '◆' なら黒石
    '○'  '◇' なら白石
    盤に石を上書きしていく。

    ゴミは無視する。足りなければ上書きされないまで。

       ゴミとは "・−|+" の類です。"123あいう" なども無視します。
       罫線使用テキスト盤面も大丈夫です。
       ゴミでもX座標はインクリメントしてください。
       万一、後ろが切れていて足りないときはその行の処理をそのまま終
       わらせる。

    Y座標のカウンタをもっておいて、そのカウンタより小さいときは無視
    する。あるいは読み込みの処理終了。

       これはテキストに2つ目の盤面が有った場合に、それを上書きしない
       ようにするためです。
       読み込みデータの終了かまたはカウンタが19を超えたとき終了する
       のでもよい。

 どちらの処理もなにをすれば良いかが判れば自分にとって書きやすいコード
 にして組み込んでみてください。

 データのチェックやその他高度な技をさせる場合は、それなりに高度な処理
 が必要になります。すこしずつ工夫して改造していくのがお薦めです。
現在手の局面をテキスト出力することによって、メール碁への活用とか、掲示板への掲載などに活用できる機能となります。また、読み込み機能があれば、思考ルーチンのデバッグなどにも便利です。
トップに戻る  その他講座(未整理)に戻る