授業/C言語基礎/じゃんけんゲーム のバックアップ(No.2)


じゃんけんゲーム

これまでに勉強したことを使って、次のような簡単なじゃんけんゲームを作ります。

プレイヤーがコンピューターと勝負がつくまでじゃんけんをします。

実行結果をイメージする

数当てゲームのところでも書いたように、プログラムを作り始める前に、まず、プログラムの実行結果をイメージします。

じゃんけんでは、グーかチョキかパーを出しますが、プレイヤーが選ぶときには、グーを1、チョキを2、パーを3として入力させることにしましょう。

プレイヤーが入力した後にコンピューターが自分の手を選ぶのはズルいので、プレイヤーに入力を要求する前にコンピューターが自分の手を選ぶことにしましょう。 とりあえず、グーを選んだとして話を進めます。

プレイヤーに入力を要求するメッセージは、じゃんけんらしく、次のような感じにしましょう。

じゃんけんぽん!(1: グー、2: チョキ、3: パー):

プレイヤーが手を選んで入力すると、プレイヤーが選んだ手とコンピューターが選んだ手を出力します。 ここでは、プレイヤーがパーを選んだとします。

じゃんけんぽん! (1: グー、2: チョキ、3: パー):
3
あなた: 3、コンピューター: 1(1: グー、2: チョキ、3: パー)

プレイヤーがパーを選んだ場合は、プレイヤーの勝ちなので、「あなたの勝ち」というメッセージを表示し、プログラムを終了します。

じゃんけんぽん! (1: グー、2: チョキ、3: パー):
3
あなた: 3、コンピューター: 1(1: グー、2: チョキ、3: パー)
あなたの勝ち!

プレイヤーがチョキを選んで2と入力したとすると、プレイヤーの負けなので、「あなたの負け」というメッセージを表示し、プログラムを終了します。

じゃんけんぽん! (1: グー、2: チョキ、3: パー):
2
あなた: 2、コンピューター: 1(1: グー、2: チョキ、3: パー)
あなたの負け!

プレイヤーがグーを選んで1と入力したとすると、あいこなので、もう一度コンピューターが自分の手を選び、プレイヤーに入力を要求するメッセージを表示します。

じゃんけんぽん! (1: グー、2: チョキ、3: パー):
1
あなた: 1、コンピューター: 1(1: グー、2: チョキ、3: パー)
あいこでしょ! (1: グー、2: チョキ、3: パー):

これを、勝負がつくまで繰り返します。

このように、実行結果をイメージすることで、プログラムの中で、どんな処理が行われるのか、どんな処理が繰り返されるのかが、ある程度わかります。

フローチャートを作る

次に、イメージした実行結果になるように、プログラムのフローチャート(またはアルゴリズム)を考えます。

このプログラムも、数当てゲームと同じように、二つの部分に分けることができます。

  1. コンピューターが自分の手を選ぶ
  2. プレイヤーが自分の手を選ぶ

ただし、数当てゲームとは違って、1と2の両方を(勝負がつくまで)繰り返し実行します。

プレイヤーの手はキーボードから入力してもらうので、繰り返し行われる処理は次のようになります。

  1. 「じゃんけんぽん」と出力する
  2. rand関数で自分の手を選ぶ
  3. scanf関数でキーボードから入力する
    • 引き分けなら、「あいこでしょ」と出力し、2へ戻る
    • そうでないなら、結果を出力し、プログラムを終了する

この流れを、そのままフローチャートにすると、次のようになります(フローチャート1)。

janken1.png

繰り返し条件の前置判定を行う方がwhile文を作りやすいので、これを次のように書き換えます(フローチャート2)。

janken2.png

ただし、こうすると、繰り返し処理の前に重複する処理ができてしまいます。

プログラムを作る

フローチャートができたら、プログラムを作ります。

無限ループとbreak文の組み合わせ

まず初めに、「じゃんけんぽん」と出力して、無限ループを用意します。

#include <stdio.h>

int main(void) {
  printf("じゃんけんぽん!(1: グー、2: チョキ、3: パー):\n");
  while (1) {

  }


  return 0;
}

無限ループに入ると、乱数を使って自分の手を選びます。

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

int main(void) {
  int r;

  srand((unsigned int) time(NULL));  // 乱数のシード

  printf("じゃんけんぽん!(1: グー、2: チョキ、3: パー):\n");
  while (1) {
    r = rand() % 3 + 1;

  }


  return 0;
}

ここでは、1から3までの整数を乱数で生成し、1ならグー、2ならチョキ、3ならパーとします。 rand関数、srand関数、time関数の使い方については、計算ゲームを復習しましょう。

その次に、キーボードから入力する部分を加えます。

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

int main(void) {
  int r, h;

  srand((unsigned int) time(NULL));  // 乱数のシード

  printf("じゃんけんぽん!(1: グー、2: チョキ、3: パー):\n");
  while (1) {
    r = rand() % 3 + 1;
    scanf("%d", &h);
    printf("あなた: %d、コンピューター: %d(1: グー、2: チョキ、3: パー)\n", h, r);

  }


  return 0;
}

ここで、h はプレイヤーが入力した数を記憶しておくための変数です。 (同時に、新しく登場した変数 a の宣言も追加しています。) また、入力された手とコンピューターが選んだ手を画面に出力しています。

ここで、引き分けでない場合は、無限ループを中断します。 そうでない場合(引き分けの場合)は、「あいこでしょ」と出力して、無限ループの先頭に戻ります。

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

int main(void) {
  int r, h;

  srand((unsigned int) time(NULL));  // 乱数のシード

  printf("じゃんけんぽん!(1: グー、2: チョキ、3: パー):\n");
  while (1) {
    r = rand() % 3 + 1;
    scanf("%d", &h);
    printf("あなた: %d、コンピューター: %d(1: グー、2: チョキ、3: パー)\n", h, r);
    if (h != r) { break; }
    printf("あいこでしょ!(1: グー、2: チョキ、3: パー):\n");
  }


  return 0;
}

無限ループが中断されたら(勝負がついたら)、結果を判定して、出力します。

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

int main(void) {
  int r, h;

  srand((unsigned int) time(NULL));  // 乱数のシード

  printf("じゃんけんぽん!(1: グー、2: チョキ、3: パー):\n");
  while (1) {
    r = rand() % 3 + 1;
    scanf("%d", &h);
    printf("あなた: %d、コンピューター: %d(1: グー、2: チョキ、3: パー)\n", h, r);
    if (h != r) { break; }
    printf("あいこでしょ!(1: グー、2: チョキ、3: パー):\n");
  }

  if (r == 1 && h == 3 || r == 2 && h == 1 || r == 3 && h == 2) {
    printf("あなたの勝ち!\n");
  } else {
    printf("あなたの負け!\n");
  }

  return 0;
}

結果を判定するif文の条件は、勝ちのパターン3通りをすべて列挙して論理和 || でつないでも作ることができます。

これで完成です(プログラム1)。

演習1

プログラム1を作成し、実行結果を確認せよ。

前置判定while文

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS