Download : sample-001.c ( SJIS 版 )
/* * 2014/11/14 sample-001.c */ /* * 色々な if 文 : if 文の基本 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-001.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ「正でない」と出力する関数 */ void isPositive ( int value ) { if ( value > 0 ) { /* value が 0 より大きい場合.. */ printf ( "正\n" ); } else { /* そうでない場合 */ printf ( "正でない\n" ); } } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 「正でない」と出るはず */ isPositive ( 0 ); /* 「正でない」と出るはず */ return 0; }
C:\usr\c>sample-001 正 正でない 正でない C:\usr\c>
Download : sample-002.c ( SJIS 版 )
/* * 2014/11/14 sample-002.c */ /* * 色々な if 文 : else 節の内容が何もない場合 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ何もしない */ void isPositive ( int value ) { if ( value > 0 ) { /* value が 0 より大きい場合.. */ printf ( "正\n" ); } else { /* そうでない場合 */ /* 何もしなくてよいので、中身は空っぽ */ } } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 何もでない */ isPositive ( 0 ); /* 何もでない */ return 0; }
C:\usr\c>sample-002 正 C:\usr\c>
Download : sample-003.c ( SJIS 版 )
/* * 2014/11/14 sample-003.c */ /* * 色々な if 文 : else 節の省略 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-003.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ何もしない */ void isPositive ( int value ) { if ( value > 0 ) { /* value が 0 より大きい場合.. */ printf ( "正\n" ); } /* 条件が不成立の時の文が何もなければ else 以下(else 節)を省略可能 */ } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 何もでない */ isPositive ( 0 ); /* 何もでない */ return 0; }
C:\usr\c>sample-003 正 C:\usr\c>
Download : sample-004.c ( SJIS 版 )
/* * 2014/11/14 sample-004.c */ /* * 色々な if 文 : 単文の場合 「{」,「}」も省略可能 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-004.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ何もしない */ void isPositive ( int value ) { if ( value > 0 ) printf ( "正\n" ); /* 単文の場合は、 「{」,「}」が省略可能 */ /* 注意 : 省略は *絶対に* お勧めしない !! * if 文では常に「{」,「}」を付ける習慣を身に付ける(「行儀」の問題) * ただし、「行儀の悪い人」もいるので、「知っている」必要がある。 */ } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 何もでない */ isPositive ( 0 ); /* 何もでない */ return 0; }
C:\usr\c>sample-004 正 C:\usr\c>
Download : sample-005.c ( SJIS 版 )
/* * 2014/11/14 sample-005.c */ /* * オセロ盤プログラム (version 8 : 2014/11/07) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了時は 'Z' を入力する ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 */ char tate; /* 縦の記号 */ char color; /* 色の記号 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ /* 'Z' で終了するために、ココから.. */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } /* ココまでを追加した (2014/11/14 版) */ tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ /* そこにコマがおけるかどうか (右方向しか考えない) */ /* 新規 v *ooo OK o NG * NG * NG o NG NG まず、自分の置く場所は空である必要がある 次に自分の左は相手のコマである必要がある 更に次の左以降は、相手のコマであるあいだは次ぎを見る そうでなければ、自分のコマなら OK それいがいは NG */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* 置く場所が空白なので、おけそう */ int yy; yy = yoko - 1; /* 左を見る */ if ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 左が相手コマなので、挟めそう..*/ yy = yy - 1; while ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 自分のコマがくるまで眺める */ yy = yy -1; /* 盤端の処理をしていない */ } if ( get_board ( board, yy, tate ) == color ) { /* 自分のコマを発見 -> 挟めた */ int yyy; /* はさんだコマをひっくりかえす(自分の色にする) */ for ( yyy = yy + 1; yyy < yoko; yyy++ ) { put_board ( board, yyy, tate, color ); } /* 自分のコマを置く */ put_board ( board, yoko, tate, color ); } } } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
F5* F4o Z
C:\usr\c>sample-005< sample-005.in A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃●┃●┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃◯┃◯┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃●┃●┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> プログラムを終了します... C:\usr\c>
Download : sample-006.c ( SJIS 版 )
/* * 2014/11/14 sample-006.c */ /* * オセロ盤プログラム (version 9 : 2014/11/14) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は強制終了 Ctrl-C ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える * * 右方向の着手チェック * */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } /* * check_sandwich_right_direct_sub ( char board[8][8], char yoko, char tate, \ char color, char ocolor ) * * Q : P で利用する補助関数 * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor ) { yoko = yoko + 1; /* 一つ右をみる */ if ( yoko <= 'F' ) { /* 盤外でない事を確認する */ if ( get_board ( board, yoko, tate ) == color ) { /* 味方のコマがいた : 挟めた !! */ return 1; /* 「挟めた」場合は「真(0 以外)」を値として返す } else if ( get_board ( board, yoko, tate ) == ocolor ) { /* 敵のコマがいた : まだ、挟める可能性がある */ return check_sandwich_right_direct_sub ( board, yoko, tate, color, \ ocolor ); /* 更に右を確認 */ } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } /* * check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) { /* 「置ける」条件 */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* まず、そこに他のコマがない事を確認 */ yoko = yoko + 1; /* 一つ右に注目する */ if ( yoko <= 'F' ) { /* 盤外でない事を確認 */ char ocolor = oposit ( color ); /* 相手の色を入手 */ if ( get_board ( board, yoko, tate ) == ocolor ) { /* 一つ右が相手の色である事を確認 */ return check_sandwich_right_direct_sub ( board, yoko, tate, color, \ ocolor ); /* 後は Q に任せる */ } } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 'A' 〜 'F' */ char tate; /* 縦の記号 '1' 〜 '8' */ char color; /* 色の記号 '*' : 黒 / 'o' : 白 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ printf ( "着手 (%c,%c) %c ", tate, yoko, color ); if ( check_sandwich_right_direct ( board, yoko, tate, color ) ) { printf ( "置く事ができます。\n" ); } else { printf ( "置く事ができません。\n" ); } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
C4* C4o C5* C5o F4* F4o F5* F5o Z
C:\usr\c>sample-006< sample-006.in A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (4,C) * 置く事ができます。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (4,C) o 置く事ができません。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (5,C) * 置く事ができません。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (5,C) o 置く事ができます。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (4,F) * 置く事ができません。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (4,F) o 置く事ができません。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (5,F) * 置く事ができません。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> 着手 (5,F) o 置く事ができません。 A B C D E F G H ┏━┳━┳━┳━┳━┳━┳━┳━┓ 1 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 2 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 3 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 4 ┃ ┃ ┃ ┃◯┃●┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 5 ┃ ┃ ┃ ┃●┃◯┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 6 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 7 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┣━╋━╋━╋━╋━╋━╋━╋━┫ 8 ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┃ ┗━┻━┻━┻━┻━┻━┻━┻━┛ 次の一手> プログラムを終了します... C:\usr\c>
/* * 2014/11/14 sample-005.c */ /* * オセロ盤プログラム (version 8 : 2014/11/07) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は強制終了 Ctrl-C ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 */ char tate; /* 縦の記号 */ char color; /* 色の記号 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { /* 無限に繰り返す ( 0 < 1 は常に真 ) */ printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } /* 先週のプログラム v8.c に、追加部分 */ tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ /* そこにコマがおけるかどうか (左方向しか考えない) */ /* 新規 v *ooo OK o NG * NG * NG o NG NG まず、自分の置く場所は空である必要がある 次に自分の左は相手のコマである必要がある 更に次の左以降は、相手のコマであるあいだは次ぎを見る そうでなければ、自分のコマなら OK それいがいは NG */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* 置く場所が空白なので、おけそう */ int yy; yy = yoko - 1; /* 左を見る */ if ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 左が相手コマなので、挟めそう..*/ yy = yy - 1; while ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 自分のコマがくるまで眺める */ yy = yy -1; /* 盤端の処理をしていない */ } if ( get_board ( board, yy, tate ) == color ) { /* 自分のコマを発見 -> 挟めた */ int yyy; /* はさんだコマをひっくりかえす(自分の色にする) */ for ( yyy = yy + 1; yyy < yoko; yyy++ ) { put_board ( board, yyy, tate, color ); } /* 自分のコマを置く */ put_board ( board, yoko, tate, color ); } } } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
/* * 2014/11/14 sample-001.c */ /* * 色々な if 文 : else 節の内容が何もない場合 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ何もしない */ void isPositive ( int value ) { if ( value > 0 ) { /* value が 0 より大きい場合.. */ printf ( "正\n" ); } else { /* そうでない場合 */ printf ( "正でない\n" ); } } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 「正でない」と出るはず */ isPositive ( 0 ); /* 「正でない」と出るはず */ return 0; }
/* * 2014/11/14 sample-002.c */ /* * 色々な if 文 : else 節の内容が何もない場合 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-002.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ何もしない */ void isPositive ( int value ) { if ( value > 0 ) { /* value が 0 より大きい場合.. */ printf ( "正\n" ); } else {} } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 何もでない */ isPositive ( 0 ); /* 何もでない */ return 0; }
/* * 2014/11/14 sample-003.c */ /* * 色々な if 文 : else 節の省略 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-003.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ何もしない */ void isPositive ( int value ) { if ( value > 0 ) { /* value が 0 より大きい場合.. */ printf ( "正\n" ); } /* else {} */ /* 条件が不成立の時の文が何もなければ else 以下(else 節)を省略可能 */ } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 何もでない */ isPositive ( 0 ); /* 何もでない */ return 0; }
/* * 2014/11/14 sample-004.c */ /* * 色々な if 文 : 単文の場合 「{」,「}」も省略可能 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-004.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、そうでなければ何もしない */ void isPositive ( int value ) { if ( value > 0 ) printf ( "正\n" ); /* 単文の場合は、 「{」,「}」が省略可能 */ /* 注意 : 省略は *絶対に* お勧めしない !! * if 文では常に「{」,「}」を付ける習慣を身に付ける(「行儀」の問題) * ただし、「行儀の悪い人」もいるので、「知っている」必要がある。 */ } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 何もでない */ isPositive ( 0 ); /* 何もでない */ return 0; }
/* * 2014/11/14 sample-004.c */ /* * 色々な if 文 : 単文の場合 「{」,「}」も省略可能 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-004.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、 * value が負なら「負」と出力し、 * value が零なら「零」と出力する。 */ void isPositive ( int value ) { if ( value > 0 ) { printf ( "正\n" ); } else { if ( value < 0 ) { printf ( "負\n" ); } else /* if ( value == 0 ) */ { printf ( "零\n" ); } } /* 単文の場合は、 「{」,「}」が省略可能 */ /* 注意 : 省略は *絶対に* お勧めしない !! * if 文では常に「{」,「}」を付ける習慣を身に付ける(「行儀」の問題) * ただし、「行儀の悪い人」もいるので、「知っている」必要がある。 */ } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 「負」と出るはず */ isPositive ( 0 ); /* 「零」と出るはず */ return 0; }
/* * 2014/11/14 sample-004.c */ /* * 色々な if 文 : 単文の場合 「{」,「}」も省略可能 * * 利用方法 * コンパイル * cc -Ic:\usr\c\include -o BASENAME.exe sample-004.c * 実行 * BASENAME */ #include <stdio.h> /* * void isPositive ( int value ) * * value が正なら「正」と出力し、 * value が負なら「負」と出力し、 * value が零なら「零」と出力する。 */ void isPositive ( int value ) { if ( 条件 1 ) if ( 条件 2 ) なにか 1 else なにか 2 if ( 条件 1 ) { if ( 条件 2 ) { なにか 1 } else { なにか 2 } } if ( 条件 1 ) { if ( 条件 2 ) { なにか 1 } } else { なにか 2 } /* if ( value > 0 ) ; 空文を表す printf ( "正\n" ); if ( value > 0 ) { ; 空文を表す } printf ( "正\n" ); */ /* else if ( value < 0 ); printf ( "負\n" ); else printf ( "零\n" ); */ /* 単文の場合は、 「{」,「}」が省略可能 */ /* 注意 : 省略は *絶対に* お勧めしない !! * if 文では常に「{」,「}」を付ける習慣を身に付ける(「行儀」の問題) * ただし、「行儀の悪い人」もいるので、「知っている」必要がある。 */ } /* * main * */ int main( int argc, char *argv[] ) { isPositive ( 3 ); /* 「正」と出るはず */ isPositive ( -5 ); /* 「負」と出るはず */ isPositive ( 0 ); /* 「零」と出るはず */ return 0; }
/* * 2014/11/14 sample-006.c */ /* * オセロ盤プログラム (version 9 : 2014/11/14) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は強制終了 Ctrl-C ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える * * 右方向の着手チェック * */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } /* * check_sandwich_right_direct_sub ( char board[8][8], char yoko, char tate, \ char color, char ocolor ) * * Q : P で利用する補助関数 * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor ) { yoko = yoko + 1; /* 一つ右をみる */ if ( yoko <= 'F' ) { /* 盤外でない事を確認する */ if ( get_board ( board, yoko, tate ) == color ) { /* 味方のコマがいた : 挟めた !! */ return 1; /* 「挟めた」場合は「真(0 以外)」を値として返す } else if ( get_board ( board, yoko, tate ) == ocolor ) { /* 敵のコマがいた : まだ、挟める可能性がある */ return check_sandwich_right_direct_sub ( board, yoko, tate, color, \ ocolor ); /* 更に右を確認 */ } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } /* * check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) { /* 「置ける」条件 */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* まず、そこに他のコマがない事を確認 */ yoko = yoko + 1; /* 一つ「右:yoko を一つ増やす」に注目する */ if ( yoko <= 'F' ) { /* 盤外でない事を確認 : F は横の最大値 */ char ocolor = oposit ( color ); /* 相手の色を入手 */ /* color == 'o' -> '*', color == '*' -> 'o' */ if ( get_board ( board, yoko, tate ) == ocolor ) { /* 一つ右が相手の色である事を確認 */ return check_sandwich_right_direct_sub ( board, yoko, tate, color, \ ocolor ); /* 後は Q に任せる */ } } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 'A' 〜 'F' */ char tate; /* 縦の記号 '1' 〜 '8' */ char color; /* 色の記号 '*' : 黒 / 'o' : 白 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ printf ( "着手 (%c,%c) %c ", yoko, tate, color ); if ( check_sandwich_right_direct ( board, yoko, tate, color ) ) { printf ( "置く事ができます。\n" ); } else { printf ( "置く事ができません。\n" ); } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
/* * 2014/11/14 sample-006.c */ /* * オセロ盤プログラム (version 9 : 2014/11/14) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は強制終了 Ctrl-C ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える * * 右方向の着手チェック * */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } /* * check_sandwich_right_direct_sub ( char board[8][8], char yoko, char tate, \ char color, char ocolor ) * * Q : P で利用する補助関数 * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor ) { yoko = yoko + 1; /* 一つ右をみる */ if ( yoko <= 'F' ) { /* 盤外でない事を確認する */ if ( get_board ( board, yoko, tate ) == color ) { /* 味方のコマがいた : 挟めた !! */ return 1; /* 「挟めた」場合は「真(0 以外)」を値として返す } else if ( get_board ( board, yoko, tate ) == ocolor ) { /* 敵のコマがいた : まだ、挟める可能性がある */ return check_sandwich_right_direct_sub ( board, yoko, tate, color, \ ocolor ); /* 更に右を確認 */ } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } /* * check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) { /* 「置ける」条件 */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* まず、そこに他のコマがない事を確認 */ yoko = yoko + 1; /* 一つ「右:yoko を一つ増やす」に注目する */ if ( yoko <= 'F' ) { /* 盤外でない事を確認 : F は横の最大値 */ char ocolor = oposit ( color ); /* 相手の色を入手 */ /* color == 'o' -> '*', color == '*' -> 'o' */ if ( get_board ( board, yoko, tate ) == ocolor ) { /* 一つ右が相手の色である事を確認 */ return check_sandwich_right_direct_sub ( board, yoko, tate, color, \ ocolor ); /* 後は Q に任せる */ } } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 'A' 〜 'F' */ char tate; /* 縦の記号 '1' 〜 '8' */ char color; /* 色の記号 '*' : 黒 / 'o' : 白 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ printf ( "着手 (%c,%c) %c ", yoko, tate, color ); if ( check_sandwich_right_direct ( board, yoko, tate, color ) ) { printf ( "置く事ができます。\n" ); } else { printf ( "置く事ができません。\n" ); } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
/* * 2014/11/14 sample-006.c */ /* * オセロ盤プログラム (version 9 : 2014/11/14) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は 'Z' を入れる ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える * * 右方向の着手チェック * */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } /* 横方向のチェックを行う */ int check_yoko ( char yoko ) { if ( yoko <= 'F' ) { if ( 'A' <= yoko ) { return 1; /* 'A' <= yoko <= 'F' なので OK */ } } return 0; /* その他の場合は、駄目 */ } int check_sandwich_yoko_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor, int direction ) { yoko = yoko + direction; if ( check_yoko ( yoko ) ) { /*右も左両方*/ if ( get_board ( board, yoko, tate ) == color ) { return 1; } else if ( get_board ( board, yoko, tate ) == ocolor ) { return check_sandwich_yoko_direct_sub ( board, yoko, tate, color, \ ocolor, direction ); } } return 0; } /* * check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_yoko_direct ( char board[8][8], char yoko, char tate, \ char color, int direction ) { /* 「置ける」条件 */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* まず、そこに他のコマがない事を確認 */ yoko = yoko + direction; /* 一つ横にずらす */ if ( check_yoko ( yoko ) ) { /* 盤外でない事を確認 */ char ocolor = oposit ( color ); /* 相手の色を入手 */ /* color == 'o' -> '*', color == '*' -> 'o' */ if ( get_board ( board, yoko, tate ) == ocolor ) { /* 一つ右が相手の色である事を確認 */ return check_sandwich_yoko_direct_sub ( board, yoko, tate, color, \ ocolor, direction ); /* 後は Q に任せる */ } } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } /* * check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) { return check_sandwich_yoko_direct ( board, yoko, tate, color, 1 ); } /* * check_sandwich_left_direct ( char board[8][8], char yoko, char tate, char \ color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_left_direct ( char board[8][8], char yoko, char tate, \ char color ) { return check_sandwich_yoko_direct ( board, yoko, tate, color, -1 ); } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 'A' 〜 'F' */ char tate; /* 縦の記号 '1' 〜 '8' */ char color; /* 色の記号 '*' : 黒 / 'o' : 白 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ printf ( "着手 (%c,%c) %c ", yoko, tate, color ); if ( check_sandwich_right_direct ( board, yoko, tate, color ) ) { printf ( "置く事ができます。\n" ); } else if ( check_sandwich_left_direct ( board, yoko, tate, color ) ) { printf ( "置く事ができます。\n" ); } else { printf ( "置く事ができません。\n" ); } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
/* * 2014/11/14 sample-006.c */ /* * オセロ盤プログラム (version 9 : 2014/11/14) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は 'Z' を入れる ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える * * 右方向の着手チェック * */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } /* 横方向のチェックを行う */ int check_yoko ( char yoko ) { if ( yoko <= 'F' ) { if ( 'A' <= yoko ) { return 1; /* 'A' <= yoko <= 'F' なので OK */ } } return 0; /* その他の場合は、駄目 */ } /* 横方向のチェックを行う */ int check_tate ( char tate ) { if ( tate <= '8' ) { if ( '1' <= tate ) { return 1; /* '1' <= tate <= '8' なので OK */ } } return 0; /* その他の場合は、駄目 */ } int check_play ( char yoko, char tate ) { if ( check_yoko ( yoko ) ) { if ( check_tate ( tate ) ) { return 1; } } return 0; } int check_sandwich_play_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor, int ydir, int tdir ) { yoko = yoko + ydir; tate = tate + tdir; if ( check_play ( yoko, tate ) ) { /*右も左両方*/ if ( get_board ( board, yoko, tate ) == color ) { return 1; } else if ( get_board ( board, yoko, tate ) == ocolor ) { return check_sandwich_play_direct_sub ( board, yoko, tate, color, \ ocolor, ydir, tdir ); } } return 0; } /* * check_sandwich_play_direct ( char board[8][8], char yoko, char tate, char \ color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_play_direct ( char board[8][8], char yoko, char tate, \ char color, int ydir, int tdir ) { /* 「置ける」条件 */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* まず、そこに他のコマがない事を確認 */ yoko = yoko + ydir; /* 一つ横にずらす */ tate = tate + tdir; /* 一つ横にずらす */ if ( check_play ( yoko, tate ) ) { /* 盤外でない事を確認 */ char ocolor = oposit ( color ); /* 相手の色を入手 */ /* color == 'o' -> '*', color == '*' -> 'o' */ if ( get_board ( board, yoko, tate ) == ocolor ) { /* 一つ右が相手の色である事を確認 */ return check_sandwich_play_direct_sub ( board, yoko, tate, color, \ ocolor, ydir, tdir ); /* 後は Q に任せる */ } } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } /* * check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_right_direct ( char board[8][8], char yoko, char tate, \ char color ) { return check_sandwich_play_direct ( board, yoko, tate, color, 1, 0 ); } /* * check_sandwich_left_direct ( char board[8][8], char yoko, char tate, char \ color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_left_direct ( char board[8][8], char yoko, char tate, \ char color ) { return check_sandwich_play_direct ( board, yoko, tate, color, -1, 0 ); } /* * check_sandwich_up_direct ( char board[8][8], char yoko, char tate, char \ color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_up_direct ( char board[8][8], char yoko, char tate, char \ color ) { return check_sandwich_play_direct ( board, yoko, tate, color, 0, -1 ); } int check_sandwich_down_direct ( char board[8][8], char yoko, char tate, \ char color ) { return check_sandwich_play_direct ( board, yoko, tate, color, 0, 1 ); } int check_sandwich_upleft_direct ( char board[8][8], char yoko, char tate, \ char color ) { return check_sandwich_play_direct ( board, yoko, tate, color, -1, -1 ); } int check_sandwich_all_direct ( char board[8][8], char yoko, char tate, \ char color ) { if ( check_sandwich_right_direct ( board, yoko, tate, color ) ) { return 1; } else if ( check_sandwich_left_direct ( board, yoko, tate, color ) ) { return 1; } else if ( check_sandwich_up_direct ( board, yoko, tate, color ) ) { return 1; } else if ( check_sandwich_down_direct ( board, yoko, tate, color ) ) { return 1; } else if ( check_sandwich_upleft_direct ( board, yoko, tate, color ) ) { return 1; } } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 'A' 〜 'F' */ char tate; /* 縦の記号 '1' 〜 '8' */ char color; /* 色の記号 '*' : 黒 / 'o' : 白 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ printf ( "着手 (%c,%c) %c ", yoko, tate, color ); if ( check_sandwich_all_direct ( board, yoko, tate, color ) ) { printf ( "置く事ができます。\n" ); } else { printf ( "置く事ができません。\n" ); } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
/* * 2014/11/14 sample-006.c */ /* * オセロ盤プログラム (version 9 : 2014/11/14) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は 'Z' を入れる ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える * * 右方向の着手チェック * */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 1 0 +----> 2 1 | 3 2 v 4 3 5 4 6 5 7 6 8 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } /* 横方向のチェックを行う */ int check_yoko ( char yoko ) { if ( yoko <= 'F' ) { if ( 'A' <= yoko ) { return 1; /* 'A' <= yoko <= 'F' なので OK */ } } return 0; /* その他の場合は、駄目 */ } /* 横方向のチェックを行う */ int check_tate ( char tate ) { if ( tate <= '8' ) { if ( '1' <= tate ) { return 1; /* '1' <= tate <= '8' なので OK */ } } return 0; /* その他の場合は、駄目 */ } int check_play ( char yoko, char tate ) { if ( check_yoko ( yoko ) ) { if ( check_tate ( tate ) ) { return 1; } } return 0; } int check_sandwich_play_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor, int ydir, int tdir ) { yoko = yoko + ydir; tate = tate + tdir; if ( check_play ( yoko, tate ) ) { /*右も左両方*/ if ( get_board ( board, yoko, tate ) == color ) { return 1; } else if ( get_board ( board, yoko, tate ) == ocolor ) { return check_sandwich_play_direct_sub ( board, yoko, tate, color, \ ocolor, ydir, tdir ); } } return 0; } /* * check_sandwich_play_direct ( char board[8][8], char yoko, char tate, char \ color ) * * P : 現在のゲーム盤 (board) の状態で、(yoko,tate) に color のコマが置けるかどうか ? * 置けたら 1 (0 以外 : C 言語の「真」) / 置けない場合は 0 (C 言語の「偽」) */ int check_sandwich_play_direct ( char board[8][8], char yoko, char tate, \ char color, int ydir, int tdir ) { /* 「置ける」条件 */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* まず、そこに他のコマがない事を確認 */ yoko = yoko + ydir; /* 一つ横にずらす */ tate = tate + tdir; /* 一つ横にずらす */ if ( check_play ( yoko, tate ) ) { /* 盤外でない事を確認 */ char ocolor = oposit ( color ); /* 相手の色を入手 */ /* color == 'o' -> '*', color == '*' -> 'o' */ if ( get_board ( board, yoko, tate ) == ocolor ) { /* 一つ右が相手の色である事を確認 */ return check_sandwich_play_direct_sub ( board, yoko, tate, color, \ ocolor, ydir, tdir ); /* 後は Q に任せる */ } } } return 0; /* どれかの条件が不成立なら、全体として不成立 (偽:0) を返す */ } int check_sandwich_all_direct ( char board[8][8], char yoko, char tate, \ char color ) { int ydir; int tdir; for ( ydir = -1; ydir <= 1; ydir++ ) { for ( tdir = -1; tdir <= 1; tdir++ ) { if ( tate * tate + yoko * yoko != 0 ) { /* tate = yoko = 0 の時だけ不成立 */ if ( check_sandwich_play_direct ( board, yoko, tate, color, ydir, tdir ) \ ) { return 1; } } } } return 0; } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 'A' 〜 'F' */ char tate; /* 縦の記号 '1' 〜 '8' */ char color; /* 色の記号 '*' : 黒 / 'o' : 白 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ if ( yoko == 'Z' ) { /* 'Z' が入ったら.. */ printf ( "プログラムを終了します...\n" ); return 0; /* プログラムを終了 */ } tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ printf ( "着手 (%c,%c) %c ", yoko, tate, color ); if ( check_sandwich_all_direct ( board, yoko, tate, color ) ) { printf ( "置く事ができます。\n" ); } else { printf ( "置く事ができません。\n" ); } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
/* * オセロ盤プログラム (version 8 : 2014/11/07) * * 機能 * 初期化の部分 * 表示の部分 : 位置を表す記号 1 〜 8, A 〜 F * 入力の部分(コマを置いてみたい..) * 入力の指示はキーボード * ゲームをしてみたい * 繰返し入力をする * 繰返しは while で実現できるが * いつまで繰り返すか ? * -> ルールでは、両方パスするまで * とりあえず、サボって * 無限に繰り返す事にする * ( 終了は強制終了 Ctrl-C ) * v8 に向けて * 着手禁止の所にはうてないようにしたい * 「着手禁止の所」 * 既にコマがある * 相手のコマをひっくりかえせない * 挟んだコマを自動的にコマをひっくりかえして欲い * -> * コマを引っくり返す * 自分のコマで、相手のコマを挟む * イメージ : 黒で白を挟む * *oooo* -> ****** * ^ ^ * 元々 打つ手 * 上記の例は打つ手の左の状況 * この他に全部で 8 方向あるので、 * 他の 7 方向も考える * 取り敢えず、右横方向だけを考える */ #include <stdio.h> /* 表示の部分 */ /* print_board : 与えらたボードデータを表示する <<ポイント>> 配列の引数には特殊事情がある : 後回し */ void print_board ( char board[8][8] ) { int tate; /* 縦の添字 */ /* 追加(Copy) */ int yoko; /* 横の添字 */ /* 表示機能 (移動) */ /* ボードの内容を出力する */ /* 8x8 の内容を全て出力(標準出力)すればよい */ /* 配列の出力 -> for 文でやればよい */ /* 二次元配列なので、二重ループになる */ /* A B C D E F G H \yoko 0 1 2 3 4 5 6 7 tate 0 -----> 1 | 2 v 3 4 5 6 7 */ printf ( " A B C D E F G H\n" ); printf ( " ┏━┳━┳━┳━┳━┳━┳━┳━┓\n" ); for ( tate = 0; tate < 8; tate++ ) { printf ( "%d ┃", tate + 1 ); /* 左の、この行の枠 */ for ( yoko = 0; yoko < 8; yoko++ ) { if ( board[tate][yoko] == ' ') { /* 空き */ printf ( " " ); } else if ( board[tate][yoko] == 'o') { /* 白 */ printf ( "◯" ); } else /* if board[tate][yoko] == 'x') */ { /* 黒 */ printf ( "●" ); } printf ( "┃" ); /* コマとコマの間の枠 */ } printf ( "\n" ); /* 改行 */ if ( tate < 8 - 1 ) { /* 最後は、これを使わない */ printf ( " ┣━╋━╋━╋━╋━╋━╋━╋━┫\n" ); } else { /* 最後の行に使うのはこれ */ printf ( " ┗━┻━┻━┻━┻━┻━┻━┻━┛\n" ); } } } /* * 初期化 */ void init_board( char board[8][8] ) { int tate; /* 縦の添字 */ int yoko; /* 横の添字 */ /* ゲーム盤の初期化 */ /* とりあえず、全部 ' ' にして、後から真ん中の4つを置く */ /* とりあえず、全部空白 */ for ( tate = 0; tate < 8; tate++ ) { for ( yoko = 0; yoko < 8; yoko++ ) { board[tate][yoko] = ' '; /* 全ての場所を空白に */ } } /* 真ん中の 4 つだけ特別処理 */ board[3][3] = 'o'; /* D4 なので白 */ board[4][4] = 'o'; /* E5 なので白 */ board[3][4] = '*'; /* D5 なので黒 */ board[4][3] = '*'; /* E4 なので黒 */ } /* ボードを作る */ /* ボードは、8x8 の要素からなる */ /* ボードの一つの要素には 空、黒、白のいずかが入る */ /* 空 ' ' , 白 'o', 黒 '*' -> 一文字 */ /* 'A2' に黒 -> put_board_black ( 'A', '2' ) -> board[1][0] = '*'; */ char get_board ( char board[8][8], char yoko, char tate ) { return board[tate-'1'][yoko-'A']; } void put_board ( char board[8][8], char yoko, char tate, char color ) { board[tate-'1'][yoko-'A'] = color; /* 本当は、ここで tate, yoko, color が正しい値かを チェックする必要がある (後回し) */ } void put_board_black ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, '*' ); /* put_board_black ( 'A', '2' ) -> board['2'-'1']['A'-'A'] = '*'; -> board[1][0] = '*'; */ } void put_board_white ( char board[8][8], char yoko, char tate ) { put_board ( board, yoko, tate, 'o' ); } /* * oposit ( char color ) * 自分の色を指定して、相手の色を返す * '*' -> 'o' * 'o' -> '*' */ char oposit ( char color ) { /* if ( color == '*' ) { return 'o'; } else if ( color == 'o' ) { return '*'; } */ return 'o' + '*' - color; } int main(int argc, char *argv[]) { char board[8][8]; /* ゲームボード */ char yoko; /* 横の記号 */ char tate; /* 縦の記号 */ char color; /* 色の記号 */ init_board ( board ); /* 引数に配列名しか指定しない */ print_board ( board ); /* 引数に配列名しか指定しない */ while ( 0 < 1 ) { printf ( "次の一手> " ); /* ここで入力をする */ /* キーボードから 「A2*<改行>」とされた事を想定 */ yoko = getchar(); /* 横の指定の一文字 'A' を入力 */ tate = getchar(); /* 縦の指定の一文字 '2' を入力 */ color = getchar(); /* 色の記号 '*' を入力 */ getchar(); /* 改行を読み飛ばす */ /* そこにコマがおけるかどうか (右方向しか考えない) */ /* 新規 v *ooo OK o NG * NG * NG o NG NG まず、自分の置く場所は空である必要がある 次に自分の左は相手のコマである必要がある 更に次の左以降は、相手のコマであるあいだは次ぎを見る そうでなければ、自分のコマなら OK それいがいは NG */ if ( get_board ( board, yoko, tate ) == ' ' ) { /* 置く場所が空白なので、おけそう */ int yy; yy = yoko - 1; /* 左を見る */ if ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 左が相手コマなので、挟めそう..*/ yy = yy - 1; while ( get_board ( board, yy, tate ) == oposit ( color ) ) { /* 自分のコマがくるまで眺める */ yy = yy -1; /* 盤端の処理をしていない */ } if ( get_board ( board, yy, tate ) == color ) { /* 自分のコマを発見 -> 挟めた */ int yyy; /* はさんだコマをひっくりかえす(自分の色にする) */ for ( yyy = yy + 1; yyy < yoko; yyy++ ) { put_board ( board, yyy, tate, color ); } /* 自分のコマを置く */ put_board ( board, yoko, tate, color ); } } } /* その結果が反映されているかどうかを確認する */ print_board ( board ); } return 0; }
if 文 if 文の構文 if ( 「条件」) 「成立時の命令」[ else 「不成立時の命令」 ] # ここで [ 〜 ] の部分は、省略可能 # 「成立時の命令」、 「不成立時の命令」の所は、 # { と } で囲む必要はない == Q : *, o*, oo*, ... Q = * | 一番左が o で、かつ、残りが Q である Q : * o*, oo*, ... o { *, o*, .. } o Q == 右チェックができたので、次は、左チェック まずは、右チェックのプログラム(関数)を Copy 名前の変更 : right -> left 右に移動 -> 左に移動 : yoko + 1 -> yoko - 1 右盤端 -> 左盤端 : ( yoko <= 'F' ) -> ( 'A' <= yoko ) ※ up/down も作れる -> leftup, righdown 等.. 斜めも... 斜めの場合は tate, yoko を両方変更 チェックも tate, yoko 両方やる必要がある == int check_sandwich_right_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor ) { yoko = yoko + 1; /*※*/ if ( yoko <= 'F' ) { /*※*/ if ( get_board ( board, yoko, tate ) == color ) { return 1; } else if ( get_board ( board, yoko, tate ) == ocolor ) { return check_sandwich_right_direct_sub ( board, yoko, tate, color, \ ocolor ); /*※*/ } } return 0; } int check_sandwich_left_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor ) { yoko = yoko - 1; /*※*/ if ( 'A' <= yoko ) { /*※*/ if ( get_board ( board, yoko, tate ) == color ) { return 1; } else if ( get_board ( board, yoko, tate ) == ocolor ) { return check_sandwich_left_direct_sub ( board, yoko, tate, color, ocolor \ ); /*※*/ } } return 0; } /* 横方向のチェックを行う */ int check_yoko ( char yoko ) { if ( yoko <= 'F' ) { if ( 'A' <= yoko ) { return 1; /* 'A' <= yoko <= 'F' なので OK */ } } return 0; /* その他の場合は、駄目 */ } == int check_sandwich_yoko_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor, int direction ) { yoko = yoko + direction; if ( check_yoko ( yoko ) ) { /*右も左両方*/ if ( get_board ( board, yoko, tate ) == color ) { return 1; } else if ( get_board ( board, yoko, tate ) == ocolor ) { return check_sandwich_yoko_direct_sub ( board, yoko, tate, color, ocolor \ ); /*※*/ } } return 0; } == int check_sandwich_tate_direct_sub ( char board[8][8], char yoko, char \ tate, char color, char ocolor, int direction ) { tate = tate + tateDirection; /* 縦 */ yoko = yoko + yokoDirection; /* 横 */ if ( check ( yoko, tate ) ) { /*横も縦も全部*/ if ( get_board ( board, tate, tate ) == color ) { return 1; } else if ( get_board ( board, tate, tate ) == ocolor ) { return check_sandwich_tate_direct_sub ( board, tate, tate, color, ocolor \ ); /*※*/ } } return 0; } == 1) 右方向のプログラム 2) 1) を利用して、左方向のプログラム Copy & Modify 3) 1), 2) まとめる関数をつくった (リファクタリング) 3-1) 同じような記述が沢山現れるのを防ぐ事ができた 3-2) 3) によって、横だけじゃなくて、縦も対応できるようになった 3-3) 3-2) から斜めが自動的的にできてしまった 4) 個々に関数をつくっていたが、もう引数の違いになってしまった -> プログラムの並びが、ループになった <ポイント> いきなり、全部は作らない 簡単な、一例だけを試しに作ってみる ( プロトタイピング ) 最初の実装は、Copy で良い 後(動く事を確認して..)から、リファクタリングを行う 考え方(設計)のチェックと、プログラム(コーディング)のチェックは別に行え == ファイルの分割 今迄プログラムは、一つのファイルで全部つくってきました p-012.c これを、分割して、複数のファイルにする とりあえず、二つに分ける main.c othello.c コンパイルの作業が増えてしまう -> makefile を作って、make コマンドで、サボる 今週の課題は 1 のみ 少なくても右だけでなく左のチェックもサポートしている者 # ひっくりかえす必要ない。チェックのみ