ゲームの進行

オセロのページに戻る

石の個数の数え上げ

勝敗の判断のため、盤上の石の個数を数え上げる関数を作る。

void count_stone(int borad[B][B], int *c1, int *c2) の関数仕様
board& で表されたゲーム盤の状況において、プレーヤー1の石の個数とプレーヤー2の石の個数とを数えて *c1, *c2 に返す。

練習問題3:関数 count_stone を作れ。
解答解説

ゲームを行う関数

それでは,これまでに作成した関数を用いて,人間対人間でオセロゲームを行えるプログラムを完成させよう。

ゲームを1回だけ行うための関数 game を作る。

流れの概略

おおまかな流れは,次のようになる

  1. ゲーム盤の初期化
  2. ゲームの進行
    1. ゲーム状況の表示
    2. ゲームの終了判断
    3. 指し手入力
    4. ゲーム状況を変化させる
    5. プレーヤー交代
  3. ゲームの最終局面の判断

ゲームの進行は,プレーヤーを交代しながら,盤の状況表示と手の入力とを行えばよいだろう。 ここで,プレーヤーに合法的な手がなければ,パスをして,プレーヤーを交代することも忘れてはならない。

終了判断

では,最終局面であることは,何でもって判断すれば良いだろうか?

「すべてのマス目が石で埋まれば終了する」

この判断方法は,浅はかであろう。なぜなら,すべてのマス目が石で埋まらなくとも,ゲームが終了することがあるからだ。正確には,次のように判 断する。

「プレーヤーの双方に合法的な手がなくなったら,終了する」

どちらかのプレーヤーの石がすべて裏返された場合も,この終了条件に適合することに注意しよう。

ゲーム進行の概略

したがって,ゲームの終了判断も含めたゲームの進行の部分は,次のようになる。

  1. ゲーム状況の表示
  2. ゲームの終了判断
  3. 指し手入力
  4. ゲーム状況を変化させる
  5. プレーヤー交代

これを繰り返すのだが、繰り返しの終了、すなわちゲームの終了が、繰り返しの部分の深いところで判断されている。このような場合は、ループの 反復条件を本来書くべきところに書くのではなくて、ループ中で break 文を用いてループを止めるようにした方がよい。

関数 game

以上のことをふまえて、 game を作ってみよう。

int game() の関数仕様
オセロゲームを1回だけ行う。
戻り値は,終了局面における「プレーヤー1の石の数」ー「プレーヤー2の石の数」を返すものとする。したがって,戻 り値の,正,0,負,が,プレーヤー1の勝ち,引き分け,プレーヤー2の勝ちを意味している。
int game()
{
    int p, q, player, c1, c2;
    int board[B][B];
	
    init_board(board);
    player = 1;
    while (1) {
        print_board(board);
        if (!exist_legal_move(board, player)) {
            printf("Player %d has no legal moves > pass\n", player);
            player = aite(player);
            if (!exist_legal_move(board, player)) {
                printf("Player %d has no legal moves > pass\n", player);
                break;
            }
        }
        get_move(board, player, &p, &q);
        set_and_turn_over(board, player, p, q);
        player = aite(player);
    }
    count_stone(board, &c1, &c2);
    printf("Game Over\nPlayer 1 : %d\nPlayer 2 : %d\n", c1, c2);
    return c1 - c2;
}

プログラムの完成

あとは, main を作って,動かすだけである。

main()
{
    char buf[100];
    printf("Let's play Othello!\n");
    do {
        game();
        printf("again? (y/n) > ");
        scanf("%s", buf);
    } while (buf[0] == 'y');
    return 0;
}

レポート問題 Othello-4
プレイヤーの名前を入力してそれを表示したり, 繰り返してゲームをするときに勝敗表を表示したり, 工夫したものにせよ.

レポート問題 Othello-5
五目並べをするプログラムを作れ.ルールは...インターネットなどで調べること.

オセロのページに戻る