1.3 返した石を元に戻す処理

前回は、石を返す処理について説明しました。
今回は、返した石を元に戻す処理について説明します。

返した石を元に戻すためには、まず返した石の位置を記憶しておく必要があります。
今回は、スタックと呼ばれるデータ構造を使います。
スタックは、最後に記憶したデータを最初に取り出せる(後入れ先出しと呼ぶ)データ構造のことを言います。
スタックにデータを入れることをpush、取り出すことをpopと呼びます。

具体的には、スタックをあらわす配列と、スタックに入っているデータの数を表す変数を用意します。
そしてスタックにデータを出し入れするときは次のようにします。

int stack[STACK_NUM];
int sp;

/* スタックにデータを入れる */
void push(int i){
    stack[sp++]=i;
}

/* スタックからデータを取り出す */
int pop(){
    return stack[--sp];
}

変数spはあらかじめ初期化しておく必要があります。
またデータの数が配列の要素数を超えないように注意が必要です。


スタックのイメージ
スタックのイメージ

返した石のデータをスタックに入れるために、前回紹介した関数を次のように変更します。 (太字が変更した場所)

int stack[1000];
int sp;

/* 黒番で石を返す処理 flip_black(マスのインデックス)
返り値は返した石の数 */
int flip_black(int m)
{
    int n=0;
    
    n+=flip_line_black(m, -10);
    n+=flip_line_black(m,  -9);
    n+=flip_line_black(m,  -8);
    n+=flip_line_black(m,  -1);
    n+=flip_line_black(m,   1);
    n+=flip_line_black(m,   8);
    n+=flip_line_black(m,   9);
    n+=flip_line_black(m,  10);

    if(n>0){
        ban[m]=BLACK;
        stack[sp++]=m;
        stack[sp++]=n;
    }
    

    return n;
}

/* 黒番で1方向の石を返す処理 flip_line_black(マスのインデックス, 返す方向)
返り値は返した石の数 */
int flip_line_black(int m, int dir)
{
    int i=0, n=m+dir;

    while(ban[n]==WHITE)
        n+=dir;

    if(ban[n]!=BLACK)
        return 0;

    n-=dir;
    while(n!=m){
        ban[n]=BLACK;
        stack[sp++]=n;
	n-=dir;
        i++;
    }

    return i;
}

これで、石を返すたびに返した石の数と位置がスタックに記憶されます。
石を元に戻す処理は次のようになります。

/* 黒番で返した石を元に戻す */
undo_black()
{
    int n;

    n=stack[--sp];
    ban[stack[--sp]]=BLANK;

    while(n-->0)
        ban[stack[--sp]]=WHITE;
}

トップに戻る
1.2 石を返す処理
1.4