check関数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
klang

check関数について

#1

投稿記事 by klang » 10年前

http://idehideout.fc2web.com/p/rev/00.html
をみながら、オセロを作っているのですが、
疑問に思ったことが新たにでてきたため、質問させていただきました。

疑問:なぜ、このプログラムのcheck関数が必要なのでしょうか?
   最初は必要だと思っていたのですが、
   put関数がでてきて必要性がわからなくなってしまいました。
   どなたか解説お願いします。
    p.s. http://dixq.net/forum/viewtopic.php?f=3&t=14155
       できればこちらもお願いします。

コード:

#include < stdio.h >
 
//盤面の大きさ
#define BOARDSIZE 8
 
//状態を定義
#define NONE 0
#define BLACK 1
#define WHITE 2
 
//盤面
char board[BOARDSIZE][BOARDSIZE];
 
//向きごとの移動量
vec_y[] = {-1,-1,0,1,1,1,0,-1};
vec_x[] = {0,1,1,1,0,-1,-1,-1};
 
//初期化関数
void setBoard(void)
{
    int i;
    
    for(i = 0 ; i < BOARDSIZE*BOARDSIZE ; ++i){
        board[i/BOARDSIZE][i%BOARDSIZE] = NONE;
    }
    board[BOARDSIZE/2 - 1][BOARDSIZE/2] = BLACK;
    board[BOARDSIZE/2][BOARDSIZE/2 - 1] = BLACK;
    board[BOARDSIZE/2][BOARDSIZE/2] = WHITE;
    board[BOARDSIZE/2 - 1][BOARDSIZE/2 - 1] = WHITE;
    
}
 
//盤面表示関数
void disp(void){
    int i,j;
    printf(" ");
    for(i = 0 ; i < BOARDSIZE ; ++i) printf("%2d",i + 1);
    printf("\n");
    
    for(i = 0 ; i < BOARDSIZE ; ++i){
        printf("%d",(i + 1) * 10);
        for(j=0 ; j < BOARDSIZE ; ++j){
            switch(board[i][j]){
            case NONE:
                printf("・");
                break;
            case BLACK:
                printf("○");
                break;
            case WHITE:
                printf("●");
                break;
            default:
                printf("er");
                break;
            }
        }
        printf("\n");
    }
    
}
 
//vecで指定された向きについてひっくり返るコマがあるか確認する
int checkFlip(int y,int x,int turn,int vec)
{
    int flag = 0;
    while(1){
        y += vec_y[vec];
        x += vec_x[vec];
        
        //盤面の外に出ていたら終了
        if( x < 0 || y < 0 || x > BOARDSIZE-1 || y > BOARDSIZE-1) return 0;
        
        //空きマスだったら終了
        if(board[y][x] == NONE) return 0;
        
        //相手のコマがあったらフラグを立てる
        if(board[y][x] == (turn ? BLACK : WHITE)){
            flag = 1;
            continue;
        }
        
        //もしフラグがたっていればループ脱出。いなければ終了
        if(flag == 1) break;
        return 0;
    }
    return 1;
}
 
//その場所に置くことができるかを確認する関数
int check(int y,int x,int turn)
{
    int vec;
    
    //どれか一方向でもひっくり返るか確認
    for(vec = 0 ; vec < 8 ; ++vec){
        if(checkFlip(y,x,turn,vec) == 1) return 1;
    }
    
    return 0;
}
 
//実際に裏返す関数
void flip(int y,int x,int turn,int vec){
    while(1){
        y += vec_y[vec];
        x += vec_x[vec];
        
        //自分のコマがあったら終了
        if(board[y][x] == (turn ? WHITE : BLACK)) break;
        
        //それ以外なら自分のコマで塗りつぶす
        board[y][x] = (turn ? WHITE : BLACK);
    }
}
 
//入力を受けて裏返せるか確かめる関数
int put(int y,int x,int turn){
    int vec,flag=0;
    
    //空白でなければ終了
    if(board[y][x] != NONE) return 0;
    
    //全方向について確認
    for(vec=0 ; vec < 8 ; ++vec){
        if(checkFlip(y,x,turn,vec) == 1){
            //裏返す
            flip(y,x,turn,vec);
            flag = 1;
        }
    }
    if(flag == 1){
        //この場所にコマを置く
        board[y][x] = (turn ? WHITE : BLACK);
        return 1;
    }
    
    return 0;
}
 
//入力関数
void input(int turn)
{
    int place = 0,y,x;
    while(1){
        //入力する
        printf(">");
        if(scanf("%d",&place) == 0){
            //数値がとれなかったらバッファをクリアする
            scanf("%*[^\n]%*c");
            printf("input error\n");
            continue;
        }
        
        //数値が範囲内か確認
        if(place < 11 || place > 88){
            printf("input[%d]:error\n",place);
            place = 0;
            continue;
        }
        y = place / 10;
        x = place % 10;
        
        //もう少し詳しく確認
        if( x < 1 || y < 1 || x > 8 || y > 8){
        printf("input[%d]:error\n",place);
            place = 0;
            continue;
        }
        
        if(put(y-1,x-1,turn) == 1) break;
        else printf("input[%d]:can't flip\n",place);
        place = 0;
    }
}
 
int main(){
    int turn = 0;
    setBoard();
    disp();
    input(turn);
    disp();
    return 0;
    
}
勝敗についてはカット。

box
記事: 2002
登録日時: 13年前

Re: check関数について

#2

投稿記事 by box » 10年前

klang さんが書きました: 疑問:なぜ、このプログラムのcheck関数が必要なのでしょうか?
不要だと思います。
理由:その関数を呼び出している箇所が見当たらないからです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
沖 滉均
記事: 237
登録日時: 13年前
住所: K県F市

Re: check関数について

#3

投稿記事 by 沖 滉均 » 10年前

今は第六課を読んでいるんでしょうかね。
その時点ではboxさんのおっしゃっているように
box さんが書きました:不要だと思います。
理由:その関数を呼び出している箇所が見当たらないからです。
というわけで不要ですね。

ただし、あとの課で再び出てきますので残しておいて良いのではないでしょうか。
There is no royal road to learning.
codeタグで指定できる言語
画像

klang

Re: check関数について

#4

投稿記事 by klang » 10年前

最後までいくと必要になっていました。
回答ありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る