分岐の入力

分岐手順を入力します。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. 分岐手順の入力は、棋譜ツリーに直接登録しないで、一旦 m_Copy に手順を記録することにします。
    入力終了はマウスを右クリックするのですが、このとき分岐手順を登録するか否かを問い合わせます。
    入力した手順は m_Copy に保存されているので、後からメニュー選択で分岐手順(基本手順)として登録することが出来ます。
    m_wp は m_Copy に手順をリンクするための作業領域です。
        CELL        m_Copy;                     // 棋譜のコピー領域
        CELL        m_wp;                       // 作業用(m_Copyの入力)
        short       m_Ishi = 0;                 // 黒&白
          
        //★ Mouse Click
        private void OnMyMouseDown(object sender, MouseEventArgs e)
        {   Point   pos = new Point(e.X, e.Y);
            CELL    wp;
    
            ClickPos(ref pos);
            if (e.Button == MouseButtons.Right)
            {
                cdr_Link();
                return;
            }
            if (pos.X < 0)  break;
            wp = new CELL(m_Num++); // 基本セルを生成
            wp.pos = pos;
            wp.teban = m_Ishi;
            m_wp.car = wp;
            m_wp = wp;
            m_Ban[pos.X, pos.Y] = m_Ishi;
            m_Ishi = (short)(0 - m_Ishi);
            break;
            Invalidate();
        }
    
  2. cdr_Link(); が m_Copy に記録した分岐手順を棋譜ツリーに登録する関数です。
    分岐手順の登録には、次の二通りがあります。
    ①今まで分岐していなかった局面に分岐を設定する場合。
    ②既に分岐が設定されている局面に分岐を追加する場合。
    分岐手順は SGF の形式で説明したように、分岐レベルが設定されます。
    従って新たに分岐を設定する場合には、レベルを調整しなければなりません。
    また既に分岐が設定されている局面に追加する場合は「分岐レベルを合わせて既に登録されている分岐の最後」に追加します。
        // m_PT から分岐手順の追加
        private void cdr_Link()
        {
            DialogResult rc;
            CELL wp;
    
            if (m_PT == null) return;
            rc = MessageBox.Show("分岐手順として追加しますか", "選択",
                MessageBoxButtons.YesNo, MessageBoxIcon.Question);
            if (rc == DialogResult.No)  return;
    
            // 分岐が無いとき、分岐の開始を作成
            if (m_PT.cdr==null)
            {   // 基本手順→分岐選択(level アップ)
                m_PT.cdr = m_PT.car;
                m_PT.car = null;
                m_PT = m_PT.cdr; 
                CELL.UpLevel(m_PT, 1);
                CELL.UpLevel(m_Copy, m_PT.level-m_Copy.level);
            }
            // 分岐があるとき
            else
            {   if (m_PT.level < m_PT.cdr.level)
                {   CELL.UpLevel(m_Copy, m_PT.cdr.level-m_Copy.level);
                }
                // 選択A(cdr)を level アップ
                else
                {   wp = m_PT.cdr;
                    m_PT.cdr = m_PT.car;
                    m_PT.car = null;
                    m_PT = m_PT.cdr; 
                    CELL.UpLevel(m_PT, 1);
                    CELL.UpLevel(m_Copy, m_PT.level-m_Copy.level);
                    m_Copy.car.cdr = wp;
                }
            }       
            // 分岐手順の追加
            for(; m_PT.cdr!=null; m_PT=m_PT.cdr);
            m_PT.cdr = m_Copy.car;
            m_PT.next = m_Copy.car;
            m_PT = m_Copy.car;
        }
    
  3. 分岐レベルを調整する UpLevel() 関数です。
    pt から car, cdr をたどってセルのレベルを調整します。
    lv が調整する値で、負のときは level が小さくなります。
        // level をアップ(ダウン)
        static public void UpLevel(CELL pt, int lv)
        {   if (pt==null)   return;
            pt.level = pt.level + lv;
            UpLevel(pt.car, lv);
            UpLevel(pt.cdr, lv);
            return;
        }
    

[Next Chapter ↓] RadioButton
[Previous Chapter ↑] 棋譜の入力

超初心者のプログラム入門(C# Frame Work)