進まないな。

30年?前頃は、駒が移動できるかを、只管、こんなコードを書いていた。
先手、後手も別にあったから、当然、自分でも理解出来なくなって、管理不能。

function TPieceList.IsMovableBishop(wx, wy, sx, sy: Integer): Boolean;
var
  i: integer;
  snx: integer;
  sny: integer;
begin
  if Abs(wx-sx) = Abs(wy-sy) then begin
    Result := true;
    if sy<wy then
      sny := -1
    else if sy > wy then
      sny := 1
    else sny := 0;
    if sx<wx then
      snx := -1
    else if sx> wx then
      snx := 1
    else snx := 0;
    for i := 1 to Abs(wx - sx)-1 do begin
      if BoardPiece(sx-snx*i, sy - sny* i) <> nil then begin
        result := false;
        Break;
      end;
    end;
  end
  else Result := false;
end;

この頃書いていた、似たような判定をするコードは、普通駒と、線駒で、似たようなコード一つずつで済む。データは作らなくてならないが。

元ネタは、某ベトナム人が作った xiangqi の コードだ。BigBoardSizeを使い、 OB 判定で楽ができるのだった。

const
  OB = -1;
box169: array[1..BigBoardSize] of integer =
   (OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,
OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,
OB,OB, 1, 2, 3, 4, 5, 6, 7, 8, 9,OB,OB,
OB,OB,10,11,12,13,14,15,16,17,18,OB,OB,
OB,OB,19,20,21,22,23,24,25,26,27,OB,OB,
OB,OB,28,29,30,31,32,33,34,35,36,OB,OB,
OB,OB,37,38,39,40,41,42,43,44,45,OB,OB,
OB,OB,46,47,48,49,50,51,52,53,54,OB,OB,
OB,OB,55,56,57,58,59,60,61,62,63,OB,OB,
OB,OB,64,65,66,67,68,69,70,71,72,OB,OB,
OB,OB,73,74,75,76,77,78,79,80,81,OB,OB,
OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,
OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB,OB);

box81: array[1..BoardSize] of integer =
(29, 30, 31, 32, 33, 34, 35, 36, 37,
42, 43, 44, 45, 46, 47, 48, 49, 50,
55, 56, 57, 58, 59, 60, 61, 62, 63,
68, 69, 70, 71, 72, 73, 74, 75, 76,
81, 82, 83, 84, 85, 86, 87, 88, 89,
94, 95, 96, 97, 98, 99,100,101,102,
107,108,109,110,111,112,113,114,115,
120,121,122,123,124,125,126,127,128,
133,134,135,136,137,138,139,140,141);

      // 単移動
MovabilitySimple: array[spGyoku..spTokin, 1..DIRECTIONMAX] of integer = (
      (-14, -13, -12,  -1,   1,  12,  13,  14),  // 玉
      (  0,   0,   0,   0,   0,   0,   0,   0),  // 飛
      (  0,   0,   0,   0,   0,   0,   0,   0),  // 角
      (-14, -13, -12,  -1,   1,  13,   0,   0),  // 金
      (-14, -13, -12,  12,  14,   0,   0,   0),  // 銀
      (-27, -25,   0,   0,   0,   0,   0,   0),  // 桂
      (  0,   0,   0,   0,   0,   0,   0,   0),  // 香
      (-13,   0,   0,   0,   0,   0,   0,   0),  // 歩
      (-14, -12,  12,  14,   0,   0,   0,   0),  // 龍
      (-13,  -1,   1,  13,   0,   0,   0,   0),  // 馬
      (-14, -13, -12,  -1,   1,  13,   0,   0),  // 成銀
      (-14, -13, -12,  -1,   1,  13,   0,   0),  // 成桂
      (-14, -13, -12,  -1,   1,  13,   0,   0),  // 成香
      (-14, -13, -12,  -1,   1,  13,   0,   0));  // と

      // 複数移動   queen や nightrider の拡張を見込み 8方向
MovabilityLine: array[spGyoku..spTokin, 1..DIRECTIONMAX] of integer = (
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (-13,  -1,   1,  13,   0,   0,   0,   0),
      (-14, -12,  12,  14,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (-13,   0,   0,   0,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (-13,  -1,   1,  13,   0,   0,   0,   0),
      (-14, -12,  12,  14,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0),
      (  0,   0,   0,   0,   0,   0,   0,   0)
    );

  procedure SetSimpleMove;
  var
    i : integer;
    direction: integer;
  begin
    for i := 1 to DIRECTIONMAX do begin
      direction := MovabilitySimple[sp, i];     //  Simple
      if direction <> 0 then begin
        if ti = tiGote then
          direction :=  0 - direction;
        target169 := ind169 + direction;
        target81 := box169[target169];
        SetTarget(target81, ti);  // 返り値は使わない
      end;
    end;
  end;

  procedure SetLineMove;
  var
    i: integer;
    direction: integer;
    cnt: Boolean;
  begin
    for i := 1 to DIRECTIONMAX do begin
      direction := MovabilityLine[sp, i];    //  Line
      if direction <> 0 then begin
        if ti = tiGote then
          direction :=  0 - direction;
   target169 := ind169 + direction;    // 駒位置から
     target81 := box169[target169];
     cnt := SetTarget(target81, ti);
       while cnt do begin
          target169 := target169 + direction;   // 動いた位置から
          target81 := box169[target169];
          cnt := SetTarget(target81, ti);
        end;
      end;
    end;
  end;
スポンサーサイト



Free Soft の活用

「今昔詰将棋」を作るのに使っている Free Soft を紹介してみよう

大量のフェイルのコピーすることが、間々ある。
エクスプローラーを使っても良いのだが、エクスプローラーは多機能なので、「コピー」するつもりが、「移動」になってしまうことがある。フォルダが見当たらないナーと思っていたら、他のフォルダに潜り込んでいたりする。そのほかにも、「削除」してしまうこともある。どうも、選択してドラッグするという作業に危うさがあるのだった。

Teamwind の File Transporter は、コピーに特化したものであるから、間違いようもない。
20220818-tw.jpg

データは、テキストファイル形式が主なので、作業はエディターでおこなう。 Windows 付属の「メモ帖」でもいいのだが、機能が貧弱で、作業効率が上がらないのだった。
で、ずーっと使っているのは、サクラエディタだ。Html や LaTeX のソースもこれで書いている。
20220818-sk.jpg

「検索」から「Grep」を選ぶと、同一図の検索は簡単に出来る。

20220818-sk-1.jpg

Program を作るのは Delphi の Community Edition。 CPM/86 の時代から turbo Pascal にはお世話になっている。 年間 5,000 ドル以上、作ったプログラムが売れると、正規品を買わなくちゃならないが、そんな心配は無用だ、、。
20220818-dlp.jpg

画面の切り取りは DtCut。 ブラウザや Kindle Unlimited などで表示させている画像を保存することができる。

20220818-dt.jpg

画像を保存するときは、適当な名前を付けているのだが、必要に応じてファイル名を変更するのは、
お~瑠璃ね~む (AllRename)で。 数百というファイル名を変更するにを手作業で行なうのは大変だ。また連番の整理も手軽にできる。

20220818-rn.jpg

画像をみるのは、Microsoft フォト でもいいのだが、最近みつけたのが NeeView。
PDF と JPGが混ざっていても、両方シームレスに見ることができる(PDF を PNGに変換しているらしいのだが、、)。 

20220818-nv.jpg

『ランダム詰将棋』をランダムに解く 続続

GM(仮)はひとまず終了。まだ改良すべき点は山のようにあるのだが他の事が滞ってしまっているので仕方がない。情報ファイルのデータを表示するのと、表紙(0ページ)を添えて雰囲気を出した。

20220619.jpg

GM(仮)は詰将棋の問題(作品)集だけでなく一般に問題と解答がそれぞれ1ページずつになっている画像があれば良い。情報ファイルは以下のような塩梅で作成する。

BookName:  中田章道短編詰将棋集 終盤力と読みを鍛える7手詰~15手詰まで39+1題
SampleName: \ssk\imgs\img2016\sf201607\sf201607_03.jpg
Diagram:  sf201607_00.jpg sf201607_02.jpg
Diagram:   3    1  39
Author:   中田章道
PubDate:  2016-07-01
SMRNumber: 3200
PageOrder: 2
...

基準フォルダと SampleName を組み合わせて、画像が保存してあるフォルダが決定できる。

SampleNameの拡張子から、画像タイプがわかる。

PageOrder が 2 の場合は  01,  02,  03, .... と変化する。 00 が表紙。  
PageOrder が 3 の場合は   001,  002, 003, .... と変化する  000 が表紙。

Diagramを指定するのは、二通りある。
1 ) 問題ファイルと解答ファイルを半角スペースで区切って指定。
なのでファイル名に半角スペースがあると指定不可である。
2)  ページ数 開始問題番号 終了問題番号 
を指定する。1ページに2問表示の場合は
 ページ数 開始問題番号 終了問題番号 2 
と指定する。

『ランダム詰将棋』をランダムに解く 続

 GM(仮)を Aさんに送った。動いたようだった。

で、送ったあとに、ページ数が二桁表示のファイル名になっているときにファイルを読み込めないことに気がついた。また、2問/頁 の場合もおかしくなるのだった。

そんなこんなで、今週は Program ばっかり、ようやく修正と History の追加ができたのだった。一度開いた情報ファイルを覚えておく事にしたので、ぐっと使い勝手がよくなった。右のStringGrid の Info File をクリックするだけ、情報ファイルと書名の対応を覚えていなくてもいいのだった。
画像のサムネイルも付けたかったが力不足の為断念。

20220617.jpg


『ランダム詰将棋』(など)をランダムに解くことは可能となったが、やはり問題以外も見たい、表紙から、ということもある。それは Vector などにある 画像ビューワーが便利だろう。このごろみつけたのが、 NeeView というもので、サクサクうごくのだった。

20220617_2.jpg

今昔詰将棋の会員(?)で、 GM(仮)を試してみたい奇特な御仁が居られたら連絡を。



『ランダム詰将棋』をランダムに解く

そろそろ、本の処分を考えるようになった。

詰将棋本はスキャンをしてから処分の予定で最初は PDF にしていた。纏まっていいのだが検索など後々のことを考えると1頁毎にしておいた方が使いやすいのだった。

画像Fileの有効活用として、HTML を作りブラウザで閲覧可能にすることはできたが、なにせハンドアッセンブル。HTMLを作るのが追いつかない。将棋世界の付録のようにフォーマットが決まっていれば、ファイル名の一部を置換すればいい。だが単行本はそうもいかない。

で、ここ数日作っていた、プログラムがようやっと動くようになった。

情報File を読み込んだ後はこんな具合

20220613_1.jpg

情報File の主要部分は、、

BookName: 1・3・5手ランダム詰将棋
SampleName: \smr\imgs\img2021\smr3371\smr3371_011.jpg
Diagram:   9    1   50
Diagram: 111   51  100
Diagram: 213  101  150
Diagram: 315  151  200
....

である。数行で済む。

基準Folder とサンプル名と Diagram行から、画像ファイル名(保存場所)が作れるのだった。

実行画面は以下の如し (駒は一部非表示)、program 名は GM(仮) となっている

20220613.jpg

上部のボタンを押してもイイのだが、画面をクリックしても移動が可能としている。
画面を3×3に区切り

WEST は 次  解答非表示
EAST  は 前 解答非表示
CENTER は ランダム 解答非表示

SOUTHWEST は 次  解答表示
SOUTHEAST  は 前  解答表示
SOUTH は ランダム  解答表示

NORTH は  解答表示

HTML では、前、次、一覧、などができていたが、ランダムを追加したので、たとえば、、

『ランダム詰将棋』をランダム!に解くということも手軽に出来るようになった。