メルマガ:あゆしゃのC言語プログラミング
タイトル:あゆしゃのC言語プログラミング(Vol.395) AYGO12 思考の修正  2003/09/27


/*========================================================*/
    <<<あゆしゃのC言語プログラミング>>>
/*========================================================*/
 第395回 AYGO12 思考の修正
 発行    2003年9月26日(金曜日)
 発行数   約3100

{magclick}
{magclick}
/*========================================================*/
 はじめに ( 決り文句 )
/*========================================================*/
・このメールマガジンはまぐまぐさんから発行しています。
・ジャンルは、マルチメディアのプログラム、C言語です。
・このメールマガジンは、横60文字で作成しています。
 また、インデントはすべて半角スペース4つで構成しています。
・ここで扱うプログラムは、C言語と半光年以内のものです。
・登録解除は、まぐまぐさんのホームページでお願いします。
・まぐまぐさんのバックナンバー(下欄参照)を活用して下さい。
・ここは私の復習の場です。内容は約1ヶ月内外に私が勉強した
 内容になっています。最新の技術があれば、へたれもあります。
・わかりやすさを優先させる為、たまに嘘があるかもしれません。

/*========================================================*/
 ご挨拶
/*========================================================*/

 こんにちは。あゆしゃです。

 テストの結果は、まだ届きません。待ち遠しいです。

{magclick}
/*========================================================*/
 今回のお題  << AYGO12 思考の修正 >>
/*========================================================*/

 前回の訂正によって、とりあえずAIGOぐらいの力はついたこと
でしょう。

 今回は、AIGOでは処理速度が遅すぎて諦めた、1手先を読む
処理を入れたいと思います。

/*========================================================*/

 思考部分であるthink関数を修正します。

// 修正前
// コンピュータの思考ルーチン
int think( int* px, int* py, int type )
{
    int max_pow = make_power_total() * type;
    *px = -1;
    for( int x = 0; x < num; x++ )
    {
        for( int y = 0; y < num; y++ )
        {
            if( board[ x ][ y ] ) continue; // 石があるので
            if( IsKou( x, y ) ) continue;   // コウなのでス
            // 禁じてである場合にスキップ
            memset( kill_board, 0, sizeof( kill_board ) );
            board[ x ][ y ] = type;
            if( ! check_kill2( x, y, type ) )
            {
                board[ x ][ y ] = 0;
                continue;
            }
            make_power( POWER_BASE );
            int pow = make_power_total() * type;
            board[ x ][ y ] = 0;
            if( max_pow < pow )
            {
                max_pow = pow;
                *px = x;
                *py = y;
            }
        }
    }
    if( *px == -1 ) return 0;       // 打つべきところがない
    return 1;
}

// 修正後
// コンピュータの思考ルーチン
int think_x = 0;        // 思考ルーチンの結果
int think_y = 0;        // 思考ルーチンの結果
int think_type = 1;     // 思考する勢力
// int sx               // 開始X座標
// int sy               // 開始Y座標
// int ex               // 終了X座標+1
// int ey               // 終了Y座標+1
// int deep             // 思考深度
int think( int sx, int sy, int ex, int ey, int deep )
{
    // 現在の最大勢力、最初は最低
    int max_pow = -100;
    int w2 = ( ex - sx ) / 4;
    int h2 = ( ey - sy ) / 4;
    int kou2[ 4 ];
    memcpy( kou2, kou, sizeof( kou2 ) );
    // ボードを保存
    board_t board3;
    memcpy( &board3, cur_board, sizeof( board_t ) );
    // 範囲外の値の修正
    if( sx < 0 ) sx = 0;
    if( sy < 0 ) sy = 0;
    if( ex > num ) ex = num;
    if( ey > num ) ey = num;
    // 範囲をループ
    for( int x = sx; x < ex; x++ )
    {
        for( int y = sy; y < ey; y++ )
        {
if( board[ x ][ y ] ) continue; // 石があるのでスキップ
if( is_kou( x, y ) ) continue;  // コウなのでスキップ
board[ x ][ y ] = think_type;   // ここに石を置く
// 死んでしまう場合は禁じ手なのでスキップする
memset( kill_board, 0, sizeof( kill_board ) );
if( ! check_kill2( x, y, think_type ) )
{
    board[ x ][ y ] = 0;
    continue;
}
// 死に石を除去
int killed = check_kill( x, y );
// パワーを計算する
// パワーは勢力に関係なく正の数にする
make_power( POWER_BASE );
int pow = make_power_total() * think_type;
if( deep > 1 )
{
    think_type = -think_type;
    pow = ( pow - think(
        sx + w2, sy + h2, ex - w2, ey - w2,  deep - 1 ) )/2;
    think_type = -think_type;
}
// ボードを復帰
if( killed ) memcpy( cur_board, &board3, sizeof( board_t ) );
else board[ x ][ y ] = 0;
memcpy( kou, kou2, sizeof( kou2 ) );
if( max_pow < pow )
{
    max_pow = pow;
    if( deep == 1 )
    {
        think_x = x;
        think_y = y;
    }
}
        }
    }
    return max_pow;
}

/*========================================================*/

 ずいぶんと形が変わっていますが、変更したのは次の3点です。

 引き数に、思考範囲を指定する変数を追加しました。

 また、引き数として指定する必要のないものは引き数から
はずしました。

 内部で、ボードの変化を保存・復元する処理を入れました。

 そして、思考深度が残っているときに限り、再起呼び出しに
よって思考を深める処理を追加しました。

/*========================================================*/

 これを、思考深度3で呼び出すと、ひどいことになりました。

 答えが返ってくるまで、2〜5分もかかるのです。

 しかも・・・弱くなっちゃった。

/*========================================================*/

 ボードの型が変わっています。

int board[ NUM ][ NUM ];

 というものを、

struct board_t {
    b[ NUM ][ NUM ];
} main_board, *cur_board;

#define board cur_board->b

 という形に変えました。というのも、


// メインボードの本体
int main_board[ NUM ][ NUM ];

// 現在選択中のボード
int* board[ NUM ] = &main_board[ 0 ];

// 新しいボード
int board2[ NUM ][ NUM ];

// 現在選択中のボードを退避
int* board_back[ NUM ] = board;

// 現在選択中のボードを変更
board = board2;


 という感じのことをしようと思っていたのです。

 boardを本体ではなくポインタとしただけなのです。

 Javaでも同じようなことをやっていたので、そうしようと
思ったのですが、

 ・・・なんか、ポインタ代入時にキャストでエラーが出るの
です。なぜでしょ?

/*========================================================*/
 さいごに
/*========================================================*/

 レンタルビデオで、ドクドクモンスターのパート4とやらを
見ました。

 ・・・昔はまともな映画だったのにねぇ。。。

{magclick}
/*========================================================*/
 次回予告
/*========================================================*/

 次回は9月29日(月曜日)に、第396回を送ります。
 お題は「AYGO13 思考の高速化」

 弱くなったのは、とりあえずおいておきましょう。

 まずは、高速化を考えます。

 お楽しみに!

/*========================================================*/
 最後の決り文句
/*========================================================*/
 このメールマガジンは、まぐまぐさんから発行しています。
 このメールマガジンを解除したい場合は、まぐまぐさんをご利用
ください。このメルマガのまぐまぐアイディーは最後にあります。
 このメールマガジンには広告が挿入されます。
 このメールマガジンの内容に文面の引用はありません。
 めーらっくすの場合はめーらっくすの利用方に従ってください。
 このメールマガジンの内容は、転用、流用、宣伝、リンク、
地震対策 なんて大歓迎です。

{magclick}
/*========================================================*/
 
/*========================================================*/

発行者 あゆしゃ

まぐまぐアイディー
0000020674

まぐまぐバックナンバー
http://jazz.tegami.com/backnumber/frame.cgi?id=0000020674

あゆしゃの世界
http://ayusya.hp.infoseek.co.jp/

登録と解除
http://www.mag2.com/m/0000020674.htm

ご意見・ご感想・ご質問メール
mailto:ayusya@flamenco.plala.or.jp

めーらっくす <<まぐより過去ログが見やすいです>>
http://www.mailux.com/mm_dsp.php?mm_id=MM3E1AEE285AB4F

ブラウザの閉じるボタンで閉じてください。