この記事では、C言語で「ジャンケン」ゲームを作る方法を初心者にも分かりやすく解説していきます。
今回は、一気にジャンケンゲームを作るのではなく、ステップアップ方式で1つずつ解説していきます。
ジャンケンの入力を受け付ける
まずは、ジャンケンの手の入力を受け付けるプログラムを作りましょう。
今回は、
- 1・・・グー
 - 2・・・パー
 - 3・・・チョキ
 - それ以外・・・ジャンケンできない
 
を入力したら、それぞれの手がコンピュータに読み込ませるようにします。
具体的なコードは以下の通りです。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, void **argv) {
    int hand;
    printf("じゃんけん。。。。n");
    printf("グー: 1 パー: 2 チョキ: 3n");
    scanf("%d", &hand);
    if(hand == 1) {
        printf("あなたはグーを入力しましたn");
    } else if(hand == 2) {
        printf("あなたはパーを入力しましたn");
    } else if(hand == 3) {
        printf("あなたはチョキを入力しましたn");
    } else {
        printf("ジャンケンできませんでした...n");
        exit(1);
    }
    return 0;
}
上のコードのポイントはscanf("%d", &hand)ですね。
scanfは標準入力(黒い画面、ターミナルからの文字入力)から文字を取得して、その文字を変数に与える役割があります。
また、入力した文字が1,2,3でない場合,はexit()関数を読んでプログラムを終了するようにしています。
2, コンピュータ側の手を乱数(ランダム)で生成する
次にコンピュータ側のジャンケンの手を乱数(ランダム)で生成するようにします。
そのためにsrand()とrand()と言う関数を使っていきます。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, void **argv) {
    int hand;
    printf("じゃんけん。。。。n");
    printf("グー: 1 パー: 2 チョキ: 3n");
    scanf("%d", &hand);
    // 乱数の偏りをなくすため
    srand(time(0));
    // computerの手を生成するため
    int com_hand = (rand() % 3) + 1;
    if(hand[0] == 1) {
        printf("あなたはグーを入力しましたn");
    } else if(hand[0] == 2) {
        printf("あなたはパーを入力しましたn");
    } else if(hand[0] == 3) {
        printf("あなたはチョキを入力しましたn");
    } else {
        printf("ジャンケンできませんでした...n");
        exit(1);
    }
    return 0;
}
C言語ではrand()を使う事で乱数を作ることができます。
乱数とはランダムの数字のことで、例えば、以下の様な数字を作ることができます。
132871214  954719899  1109440734  1867339593
しかし、単純にrand()を使うだけでは乱数として偏りが出てくるため、rand()の前にsrand(time())を使って乱数の偏りを無くすと、良い感じに乱数が生成されます。
srand()の引数は何でも良いですが、現在の時刻を整数で返してくれるtime()関数を使った方が、より質の高い乱数を返してくれます。
int com_hand = (rand() % 3) + 1;
実際にrand()を使った計算式には上記のコードを使います。
(rand() % 3)の部分ではrand()で生成された整数を3で割った余りを計算しています。
つまり、0,1,2のどれかが結果として返されます。
今回のジャンケンゲームでは1,2,3の数字に対応しているので、最後に1を足すようにしています。
ジャンケンの勝敗を決定する
次にジャンケンの勝敗を決定しましょう。
とは言っても仕組みはシンプルで、あなたの手とコンピュータの手を比べることで結果を買えればOKです。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, void **argv) {
    int hand;
    printf("じゃんけん。。。。n");
    printf("グー: 1 パー: 2 チョキ: 3n");
    scanf("%d", &hand);
    // 乱数の偏りをなくすため
    srand(time(0));
    // computerの手を生成するため
    int com_hand = (rand() % 3) + 1;
    if(hand == 1 && com_hand == 1) {
        printf("あなたはグー、COMもグー。 あいこn");
    } else if(hand == 2 && com_hand == 2) {
        printf("あなたはチョキ、COMもチョキ。 あいこn");
    } else if(hand == 3 && com_hand == 3) {
        printf("あなたはパー、COMもパー。 あいこn");
    } else if(hand == 1 && com_hand == 3) {
        printf("あなたはグー、COMはパー。 COMの勝ちn");
    } else if(hand == 2 && com_hand == 1) {
        printf("あなたはチョキ、COMはグー。 COMの勝ちn");
    } else if(hand == 3 && com_hand == 2) {
        printf("あなたはパー、COMはチョキ。 COMの勝ちn");
    } else if(hand == 1 && com_hand == 2) {
        printf("あなたはグー、COMはチョキ。 あなたの勝ちn");
    } else if(hand == 2 && com_hand == 3) {
        printf("あなたはチョキ、COMはパー。 あなたの勝ちn");
    } else if(hand == 3 && com_hand == 1) {
        printf("あなたはパー、COMはグー。 あなたの勝ちn");
    } else {
        printf("ジャンケンできませんでした...n");
        exit(1);
    }
    return 0;
}
大分長いif文ができてしまいましたが、コードを読んでいくと、やっていること自体はシンプルです。
if文の中には&&を使っていますが、これはアンドアンドではなく「論理積」と呼ばれるもので、A && Bと言う形であれば「AとBが両方正しければ」と言う意味になります。
hand == 1 && com_hand == 1
つまり、上記のコードであれば、handが1でかつcom_handが1の場合、と言うことになります。
あいこだったら繰り返すジャンケンをする
次にあいこの場合は繰り返しジャンケンを行う様にしましょう。
そのためにはwhile文とbreakを上手く使うと勝負が付くまでジャンケンをしてくれます。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, void **argv) {
    int hand;
    while(1) {
        printf("じゃんけん。。。。n");
        printf("グー: 1 パー: 2 チョキ: 3n");
        scanf("%d", &hand);
        // 乱数の偏りをなくすため
        srand(time(0));
        // computerの手を生成するため
        int com_hand = (rand() % 3) + 1;
        if(hand == 1 && com_hand == 1) {
            printf("あなたはグー、COMもグー。 あいこn");
        } else if(hand == 2 && com_hand == 2) {
            printf("あなたはチョキ、COMもチョキ。 あいこn");
        } else if(hand == 3 && com_hand == 3) {
            printf("あなたはパー、COMもパー。 あいこn");
        } else if(hand == 1 && com_hand == 3) {
            printf("あなたはグー、COMはパー。 COMの勝ちn");
            break;
        } else if(hand == 2 && com_hand == 1) {
            printf("あなたはチョキ、COMはグー。 COMの勝ちn");
            break;
        } else if(hand == 3 && com_hand == 2) {
            printf("あなたはパー、COMはチョキ。 COMの勝ちn");
            break;
        } else if(hand == 1 && com_hand == 2) {
            printf("あなたはグー、COMはチョキ。 あなたの勝ちn");
            break;
        } else if(hand == 2 && com_hand == 3) {
            printf("あなたはチョキ、COMはパー。 あなたの勝ちn");
            break;
        } else if(hand == 3 && com_hand == 1) {
            printf("あなたはパー、COMはグー。 あなたの勝ちn");
            break;
        } else {
            printf("ジャンケンできませんでした...n");
            exit(1);
        }
    }
    return 0;
}
ジャンケンゲームのコードを関数を使って整理する
ここまで来ると、シンプルなジャンケンゲームでも結構なコード量になってきました。
特にジャンケンの結果を表示するif文のコードが結構な割合を占めています。
なので、ここを関数でくくり出すようにしましょう。
ジャンケンの結果はzyanken_resultと言う関数にくくり出すようにしました。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/**
 * ジャンケンの結果を返す
 * 0: あいこ
 * 1: comの勝ち
 * 2: あなたの勝ち
 */
int zyanken_result(int hand, int com_hand) {
    if(hand == 1 && com_hand == 1) {
        printf("あなたはグー、COMもグー。 あいこn");
        return 0;
    } else if(hand == 2 && com_hand == 2) {
        printf("あなたはチョキ、COMもチョキ。 あいこn");
        return 0;
    } else if(hand == 3 && com_hand == 3) {
        printf("あなたはパー、COMもパー。 あいこn");
        return 0;
    } else if(hand == 1 && com_hand == 3) {
        printf("あなたはグー、COMはパー。 COMの勝ちn");
        return 1;
    } else if(hand == 2 && com_hand == 1) {
        printf("あなたはチョキ、COMはグー。 COMの勝ちn");
        return 1;
    } else if(hand == 3 && com_hand == 2) {
        printf("あなたはパー、COMはチョキ。 COMの勝ちn");
        return 1;
    } else if(hand == 1 && com_hand == 2) {
        printf("あなたはグー、COMはチョキ。 あなたの勝ちn");
        return 2;
    } else if(hand == 2 && com_hand == 3) {
        printf("あなたはチョキ、COMはパー。 あなたの勝ちn");
        return 2;
    } else if(hand == 3 && com_hand == 1) {
        printf("あなたはパー、COMはグー。 あなたの勝ちn");
        return 2;
    } else {
        printf("ジャンケンできませんでした...n");
        exit(1);
    }
}
int main(int argc, void **argv) {
    int hand;
    while(1) {
        printf("じゃんけん。。。。n");
        printf("グー: 1 パー: 2 チョキ: 3n");
        scanf("%d", &hand);
        // 乱数の偏りをなくすため
        srand(time(0));
        // computerの手を生成するため
        int com_hand = (rand() % 3) + 1;
        int result = zyanken_result(hand, com_hand);
        if(result != 0) {
            break;
        }
    }
    return 0;
}
前のコードと変わった部分は、zyanken_resultの中身ですね。
前のコードではwhile文の中にbreakを使っていましたが、
代わりにreturn文を使う事でジャンケンの結果を返すようにしています。
今回は、
- 0・・引き分け
 - 1・・COMの勝ち
 - 2・・あなたの勝ち
 
と言う風にしています。
関数を使ったことで全体のコード量は増えましたが、main関数自体はかなりシンプルなコードになりますたね。
今回の解説は以上になりますが、この要領でジャンケンゲームを拡張していけば、OKです。
  
  
  
  
