勝敗の判断のため、盤上の石の個数を数え上げる関数を作る。
練習問題3:関数 count_stone を作れ。
解答解説
それでは,これまでに作成した関数を用いて,人間対人間でオセロゲームを行えるプログラムを完成させよう。
ゲームを1回だけ行うための関数 game を作る。
おおまかな流れは,次のようになる
ゲームの進行は,プレーヤーを交代しながら,盤の状況表示と手の入力とを行えばよいだろう。 ここで,プレーヤーに合法的な手がなければ,パスをして,プレーヤーを交代することも忘れてはならない。
では,最終局面であることは,何でもって判断すれば良いだろうか?
「すべてのマス目が石で埋まれば終了する」
この判断方法は,浅はかであろう。なぜなら,すべてのマス目が石で埋まらなくとも,ゲームが終了することがあるからだ。正確には,次のように判 断する。
「プレーヤーの双方に合法的な手がなくなったら,終了する」
どちらかのプレーヤーの石がすべて裏返された場合も,この終了条件に適合することに注意しよう。
したがって,ゲームの終了判断も含めたゲームの進行の部分は,次のようになる。
これを繰り返すのだが、繰り返しの終了、すなわちゲームの終了が、繰り返しの部分の深いところで判断されている。このような場合は、ループの 反復条件を本来書くべきところに書くのではなくて、ループ中で break 文を用いてループを止めるようにした方がよい。
以上のことをふまえて、 game を作ってみよう。
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
五目並べをするプログラムを作れ.ルールは...インターネットなどで調べること.