読者です 読者をやめる 読者になる 読者になる

六帖のかたすみ

DVを受けていた男性。家を脱出して二周目の人生を生きています。自閉症スペクトラム(受動型)です。http://rokujo.org/ に引っ越しました。

詰碁印刷3 碁盤と碁石と手順の描画、javascriptで配列の簡単なシャローコピーの作り方

プログラミング

詰碁印刷2 - 六帖のかたすみ
の続きです。

ソースはこちら
kickzone/SGFPrint · GitHub

f:id:happyholiday:20150628111339p:plain

碁盤と手順を表示できるようになりました。使っている技術は大したことはなく、easeljsでゴリゴリ碁盤や碁石を描いているだけです。
一番苦労したのはノードの全分岐をゲットする処理です。これは先週大まかにできていましたが動作はさせておらず、今週デバッグに時間がかかりました。
詰碁用のSGFファイルは正解図を表示させるだけではありません。この手ならここがだめ、じゃあ少し戻ってここはこう打つ…と分岐がいくつも存在するファイルがありますので、すべてのパターンについて出力が必要となります。スタックと配列のコピーで実装できました。

SGFElement.prototype = {
  //全てのノード組み合わせ(=すべての分岐)をゲット
  getAllBranch: function(){
    var retArr = [];
    var nodeStack = [];
    var terminals = [];
    nodeStack.push(this.root);
    while(nodeStack.length){
      var currentNode = nodeStack[nodeStack.length-1];
      //子ノードがなければ終端とみなし、nodeStackの内容をretArrにコピー
      if(currentNode.childNodes.length == 0){
        terminals.push(currentNode);
        retArr.push([].concat(nodeStack)); //配列をシャローコピーするちょっと変わった書き方
        nodeStack.pop();
      }
      else{
        //terminalsに入っていない子ノードをスタックに入れる
        //一つもなければ、探索が終了したものとして終端一覧に入れ、自分自身をpop
        var findChild = false;
        for(i in currentNode.childNodes){
          var node = currentNode.childNodes[i];
          if(terminals.indexOf(node) == -1){
            findChild = true;
            nodeStack.push(node);
            break;
          }
        }
        if(!findChild){
          terminals.push(currentNode);
          nodeStack.pop();
        }
      }
    }
    return retArr;
  }
}

配列のシャローコピーはとても簡単な方法があります。

var newArr = [].concat(oldArr);

と書くだけでよいです。空の配列に古い配列をコピーした結果がnewArrに返ってきます。

残りの作業は、SGFファイルに書かれているコメントの出力と、大詰めのCSSによるページ設定です。これができれば一通り完了です。