/*
    C/C++の宿題片付けます 161代目
    http://t...content-available-to-author-only...h.net/test/read.cgi/tech/1354070278/75
        [1] 授業単元：c言語
        [2] 問題文(含コード&amp;リンク)：三目並べの作成
        ・先手を○、後手を×として交互に3×3の盤上に印をつけていく
        ・縦横斜めのいずれかに同じ印が並ぶと終了し、その印の方を勝ちとする
        ・9箇所すべての箇所に印がついており、勝敗がついていない場合は引き分けとする
        ・無効な位置が入力されたら再入力させる
        http://c...content-available-to-author-only...d.org/2e5lVtcO
        mainの関数はできているのでそのほかの関数の作成をお願いいたします
        関数の説明はリンク先に書いてあります
        [3] 環境
          [3.1] OS： Linux
          [3.2] コンパイラ名とバージョン： gcc
          [3.3] 言語： C
        [4] 期限:12/4
        よろしくお願いいたします 
*/

#include<stdio.h>
#include<stdlib.h>

void print_board(int board[3][3]);
int judge(int board[3][3]);
void mark_board(int board[3][3], int turn);
void print_message(int result);

int main(void)
{
    int board[3][3] = { };
    int turn = 1;               /*1=maru,-1=batsu */
    int result;

    do {
        print_board(board);
        mark_board(board, turn);
        turn *= -1;
    } while ((result = judge(board)) == 0);
    print_board(board);
    print_message(result);

    return 0;
}

void print_board(int board[3][3])
{
    /*引数で受け取った盤のデータ(board)を縦線(|)や○や×を使い画面に表示する */
    /* | | |
       | | |
       | | |
       盤はこの様な形でお願いします */
    int x, y;
    for (y = 0; y < 3; y++) {
        printf("|");
        for (x = 0; x < 3; x++) {
            switch (board[y][x]) {
            case 1:
                printf("○ |");
                break;
            case -1:
                printf("× |");
                break;
            default:
                printf("  |");
                break;
            }
        }
        printf("\n");
    }
}

int judge(int board[3][3])
{
    /*引数boardの内容をチェックし、○が勝ちなら1を、×が勝ちなら2を、
       引き分けなら3を、まだ勝敗が決まっていないときは0を返す */
    int x, y;
    int ml, bl;                 // 揃っているライン数
    int mc, bc;                 // 1ライン数える用
    int fSp;                    //空白あるか？フラグ

    //
    fSp = ml = bl = 0;
    // 行
    for (y = 0; y < 3; y++) {
        mc = bc = 0;
        for (x = 0; x < 3; x++) {
            switch (board[y][x]) {
            case 1:
                mc++;
                break;
            case -1:
                bc++;
                break;
            default:
                fSp = 1;
                break;
            }
        }
        if (mc == 3) {
            ml++;
        }
        if (bc == 3) {
            bl++;
        }
    }

    // 列
    for (x = 0; x < 3; x++) {
        mc = bc = 0;
        for (y = 0; y < 3; y++) {
            switch (board[y][x]) {
            case 1:
                mc++;
                break;
            case -1:
                bc++;
                break;
            default:
                fSp = 1;
                break;
            }
        }
        if (mc == 3) {
            ml++;
        }
        if (bc == 3) {
            bl++;
        }
    }

    // 斜め (y = x)
    mc = bc = 0;
    for (x = 0; x < 3; x++) {
        switch (board[x][x]) {
        case 1:
            mc++;
            break;
        case -1:
            bc++;
            break;
        }
        if (mc == 3) {
            ml++;
        }
        if (bc == 3) {
            bl++;
        }
    }

    // 斜め (y = 2-x)
    mc = bc = 0;
    for (x = 0; x < 3; x++) {
        switch (board[2 - x][x]) {
        case 1:
            mc++;
            break;
        case -1:
            bc++;
            break;
        }
        if (mc == 3) {
            ml++;
        }
        if (bc == 3) {
            bl++;
        }
    }

    // 揃っているラインの比較
    if (ml > bl) {
        return 1;
    } else if (ml < bl) {
        return 2;
    }
    // 空白があるか
    if (fSp) {
        return 0;
    } else {
        return 3;
    }
}

void mark_board(int board[3][3], int turn)
{
    /*盤の縦横の位置の入力を促すメッセージを表示し、キーボードから数値を読み込み,
       board配列へturnの値を代入する */
    int x, y;
    switch (turn) {
    case 1:
        printf("「○ 」を置く場所を1～3で指定してください\n");
        break;
    case -1:
        printf("「× 」を置く場所を1～3で指定してください\n");
        break;
    default:
        printf("プログラムエラー\n  " __FILE__ " (%d)\n", __LINE__);
        exit(1);
    }
    while (1) {
        while (1) {
            printf("x = ");
            scanf("%d", &x);
            if (x < 1 || 3 < x) {
                printf("1～3を入力してください\n");
            } else {
                break;
            }
        }
        while (1) {
            printf("y = ");
            scanf("%d", &y);
            if (y < 1 || 3 < y) {
                printf("1～3を入力してください\n");
            } else {
                break;
            }
        }
        x--;
        y--;
        if (board[y][x]) {
            printf("(%d,%d)には既に何かあります。再度入力してください\n", x + 1, y + 1);
        } else {
            board[y][x] = turn;
            return;
        }
    }
}

void print_message(int result)
{
    /*resultの値に従って勝敗のメッセージを表示する */
    switch (result) {
    case 0:
        printf("勝負中\n");
        break;
    case 1:
        printf("○ が勝ち\n");
        break;
    case 2:
        printf("× が勝ち\n");
        break;
    case 3:
        printf("引き分け\n");
        break;
    default:
        break;
    }
}

//