C言語によるじゃんけんゲーム作成

じゃんけんゲーム作成にあたって

今回はじゃんけんゲームを作る。特にこれといって作る動機はないのだが理由としては作るのが簡単そうだったからである。
本記事ではゲームの流れを考えその通りに書き最後にそのコードの問題点を挙げる。

ゲームの流れ

  1. じゃんけんの掛け声をする
  2. じゃんけんの手を出す
  3. 判定
    1. if(両者同じ手) 掛け声に戻る
    2. else 勝敗判定
  4. 勝敗表示
  5. 続けるか選択
  6. 判定
    1. if(入力がyes) 最初に戻る
    2. else 終了する

流れのコード化の構想

まずはじゃんけんを一回行えるプログラムを書いてみる。ここではじゃんけんの手は配列でもって置き、入力される数字(0,1,2)にじゃんけんの手を対応させる。また、じゃんけんの手の強弱関係は相子の時はif文で"=="で結べばいいが相子以外の時は手の組み合わせが複数あり、これをすべてif文で書くのは疲れるし何より汚い。そこで手の三すくみ関係を利用し、手と対応する数字に1を足し3のmodをとり、それが相手の手と同じになるかどうかを調べる。同じになれば勝ち、違えば負けとなる(ノートに書いて一度考えてみよう)。ほかに相子の時に追加の手の入力を促すがここで最初の変数に入力を入れてしまうと、今回は相子の条件をif(自分==相手)でとっているので相子用の入力変数が必要になる。(相手の手にはランダム関数を用いる)
それではコードを見ていこう

じゃんけんの手と強弱関係

    char ja[3][5]={"gu","chi","pa"};    //手の配列
    if((buf+1)%3==num) printf("あなたの勝ち!\n");    //勝敗判定
    else printf("あなたの負け!\n");

そのまんま
正直ここ以外のコードを抜き出して表示するほどの難しさではないので他は割愛(単にめんd(ry)

難点

自分が作っていてよくわからないところをメモ書き程度に書いておく

  • scanf後のenterキーが居残りして次のscanfが飛ばされる(かもしれない)。
    • 今回は回収用の変数を用いて回収している。
  • int型変数に文字列を入力してしまうと何も入力を受け付けない無限ループに陥ってしまう。
    • 今回は解決できていない。Javaなんかでは例外処理でtry-catchで難なく処理できるのだがcだとよくわからない。アドバイスいただいたのは「scanfで入力を文字列で受け取ればいい」とのことだったが、試してみたところむーんという感じ。改行まで前に入力されたものを流すやり方もあるみたいだが、こちらもうーんという感じ。これからどうにかします。

コード

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

int main(void){
    int flag;   //あいこになったかどうかの判定
    int num;    //com側の手
    char yn='y';    //続けるかどうかの判定
    char wakaran;   //enterkey回収(どうするのこれ)
    char ja[3][5]={"gu","chi","pa"};    //手の配列

    srand((unsigned int)time(NULL));    //乱数のシード値を現在の時刻で初期化

    while(yn=='y'){ //続けるを選ばれたならばループ
        flag = 1;   //初期化
        int buf = -1;   //入力された手

        while(buf<0 || 2<buf){ //入力がじゃんけんの手になっているか
            printf("最初はぐー\n");
            printf("じゃんけんポン!(数値で入力0.gu/1.chi/2.pa)>");
            scanf("%d",&buf);   /************文字列が入力されるとエラー*********/
            num = rand()%3; //comの手を生成

            if(buf<0 || 2<buf){    //じゃんけんの手でない
                printf("じゃんけんの手を入力してください\n");
            }else if(num==buf){   //あいこ
                flag = 0;   //あいこ判定
                printf("com:%s\nあなた:%s\n",ja[num],ja[buf]);

                while(num==buf){    //要改善点
                    int buf2=-1;
                    printf("あいこで しょ!(数値で入力0.gu/1.chi/2.pa)>");
                    scanf("%d",&buf2);

                    if(buf2<0 || 2<buf2){    //じゃんけんの手でない
                        printf("じゃんけんの手を入力してください\n");
                    }else{
                        num = rand()%3;
                        buf=buf2;
                        printf("com:%s\nあなた:%s\n",ja[num],ja[buf]);
                    }
                }
            }
        }
        if(flag) printf("com:%s\nあなた:%s\n",ja[num],ja[buf]); //あいこに一度もならなければ表示

        /************勝敗判定*************/
        if((buf+1)%3==num) printf("あなたの勝ち!\n");
        else printf("あなたの負け!\n");

        scanf("%c",&wakaran);   //enter回収

        printf("もう一度...する?(続けるならyをやめるならそれ以外を入力)>");
        scanf("%c",&yn);
    }

    printf("またね!\n");
    return 0;
}

おわりに

これから暇なときに改善していきます。
次の記事は今作っているオセロになるのかなぁ.