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 のみ
少なくても右だけでなく左のチェックもサポートしている者
# ひっくりかえす必要ない。チェックのみ