|
/*========================================================*/ <<<あゆしゃの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 |