入力の受け付けとチェック処理

問題ができたら今度は、ユーザーの入力を作って、出題の数字列と比べる部分を作っていきます。
(っていうか、ほとんどそれでゲーム出来上がっちゃうよね笑い)

今回のルール(おさらい)

  • 被らない4桁の数字がランダムで生成され出題される
  • プレイヤーは毎ターン4桁の数字を入力する
  • コンピュータの応答として、入力した数字を答えと比べ以下を返す
    • ヒット:位置も数字も答えと一致している桁数
    • ブロー:数字はあっているけれども位置が違う数字の数
  • ヒット=4の時は入力=出題なので、正解のメッセージを表示
  • それ以外は、もう一度入力を促す。
  • 正解するまでこれを繰り返す。

入力ループは、通常のゲームでいうゲームループみたいなもんになります。

  1. 入力メッセージ(プロンプト)表示
  2. 入力待ち
  3. (ユーザーの入力)
  4. コンピュータの応答
  5. 入力メッセージの表示に戻る

この流れを作っていきます。
とりあえず、無限ループで入力された4桁の数字(string input)を表示し続ける処理を書いてみます。
ここは特に工夫もいらんと思うので、そのまま提示します。

"無限入力待ち処理(C++の人)"
int main() {
	srand((unsigned int)(time(nullptr)));
	//早速作った関数で問題の変数を初期化
	string answer;
        MakeProblem(answer);
	string input;
 
	while(true){
		cout << "予想した4桁の整数を入力:";
		cin >> input;
		//入力エラー処理をして、エラーがなかったら
		//答え合わせをここでする。
                cout << input << endl;
                //デバッグのため、入力をそのまま表示
                //=入力した数字が文字列として変数化されそのまま表示されればOKってこと
	}
}
"無限入力待ち処理(C言語の人)"
int main() {
	srand((unsigned int)(time(nullptr)));
	//早速作った関数で問題の変数を初期化
	char answer[5];
 
	char input[100];
 
        MakeProblem(answer);
	while(1){
		printf("予想した4桁の整数を入力:");
		scanf("%s", input);
		//入力エラー処理をして、エラーがなかったら
		//答え合わせをここでする。
                printf("%s", input);
                //デバッグのため、入力をそのまま表示
                //=入力した数字が文字列として変数化されそのまま表示されればOKってこと
	}
}

これで入力できたんだから、後正解のチェックすればいいじゃん!
と思ったかもですが、そうはいきません。
ユーザーってやつは何するか分からないものです。
ゲームでもそうですが、こちらで規定された入力以外ははじいてやる必要があります。
(ここでも、データ型をstringにしておいた恩恵があるよ(C++の人だけ))
じゃぁ、考えられる入力エラーを何個かリストアップしてみましょう。

  • '0'~'9'の数字以外の文字を入力しただろ!なエラー
  • 4桁って言ってんのに4桁に足りないだろ!なエラー
  • 4桁って言ってんのに4桁以上あるだろ!なエラー
  • 被らん数字って言ってんのに数字がかぶってるだろ!なエラー

簡単なものを考えると大体この4つに分類されるかなと思います。
後で使うかもしれないので、エラーに番号を付けます。(使わないかもだけど)

  • 0: エラーなし
  • 1: 桁数エラー(多いのも少ないのも)
  • 2: 数字以外が混じっている
  • 3: 数字がかぶっているものがある

入力された数列を調べて、エラーがあればその番号を返す関数を作ります。
(エラーが複数重なった時は先に検出した方を返します(2個返すとかめんどいもの))

関数への入力と出力(引数と戻り値の型)はどうなるでしょうか?

戻り値の型: エラー番号なので整数
   引数: ユーザーの入力した数列の文字列
なので、以下のような関数を作ります。

戻り値の型
エラー番号(整数)
引数
入力文字列
例(C++)
int CheckAnswerError(const string& input);
例(C言語)
int CheckAnswerError(char input[5]);
"エラー処理関数を作る!(C++版)"
int CheckAnswerError(string input)
{
        //0:エラーなし, 1:桁数エラー 2:数字以外が混じっている 3:数字がかぶっているものがある
	//複数エラーの時はどうしようね?(今んところ1から見て行って見つかった時点でエラー番号返して終わるよ
        //桁数エラーのチェック
	if (桁数おかしいかな?のチェック){
        //C++では、inputのサイズか長さを調べればいいよ
        //C言語では、strlenという関数で調べられるよ(使い方はググろう!)
		return 1;
        }
        //数字以外が混じっていないかチェック
        //C言語の人は0~3までの4文字しかないからそれでループしちゃえばいいよね
        //(それ以外の文字数の時はすでに上の処理で弾いてるはず!)
	for (int i=0;i< _input.length();i++) //input中の各文字を1文字ずつチェックしていく
	{
         //下の解説を参照(isdigit)
		if (文字以外が入っていたら)
			return(2);
	}
	//数字のかぶりをチェック
	for (int i = 0; i < _input.length(); i++)
	{
		for (int j = i + 1; j < _input.length(); j++)
		{
			if (数字が同じかチェック)
				return 3;
		}
	}
        //これらをかいくぐってエラーなしでここまでたどり着いたら何を返せばいいかな?
	return xxxxxx;
}
"エラー処理関数を作る!(C言語版)"
int CheckAnswerError(char input[5])
{
    //入力が4桁の数字であることを確認
    if (桁数がおかしい?) {
        return 1; //桁数エラー
    }
 
    //数字以外が混じっていないか確認
    if (数字以外が混じっている) {
        return 2; //数字以外が混じっている
    }
 
    //数字がかぶっていないか確認
    if(数字がかぶっていたら){
        return 3; //数字がかぶっている
    }
 
    return 0; //エラーなし
}

int std::isdigit(char c)

入力した文字が、数字以外かどうかの判別は、引数のchar型の変数が数字の文字か、そうじゃないかを判別する関数があるのでそれを使う。
#include <cctype> または、#include <ctype.h> が必要)

C++
int std::isdigit(char c)
C言語
int isdigit(char c)

使い方:

    int c = '4';
 
    if(isdigit(c))  //'4'は数字なのでtrueが返る、 'a'や'+'など数字以外の時はfalseが返る。
        cout << "数字です" << endl;
    else
        cout << "数字以外の文字です" << endl;

さっきの入力ループを使ってできた関数をチェックしていくぅ!
ここは、CでもC++でも変わらん感じかな。自分で考えてみようね!

"入力ループとエラーチェック用(C++)"
int main() {
	srand((unsigned int)(time(nullptr)));
	//早速作った関数で問題の変数を初期化
	string answer;
        MakeProblem(answer);
	string input;
 
	while(true){
		cout << "予想した4桁の整数を入力:";
		cin >> input;
		cout << CheckAnswer(input) << endl;
                //返ってきたエラー番号を表示するよ
		//答え合わせをここでする。
	}
}
"入力ループとエラーチェック用(C言語)"
int main() {
    srand((unsigned int)(time(nullptr)));
 
    //実体作っておかないと怒られるよ
    char resStr[5];
    char input[255];//入力は、何入れられるかわからんので多めに取っておく
    //配列の初めから4つ取り出してresStrにコピー
    MakeProblem(resStr);
    //出来上がった4桁のかぶらない数列を表示(stringだからそのまま送ると表示できる)
    //printf("NUMBER: %s", resStr);
    while (1)
    {
	printf("予想した4桁の整数を入力:");
        scanf("%s", &input);
        //入力エラー処理をして、エラーがなかったら
        //答え合わせをここでする。
        printf("%d\n", CheckAnswerError(input));
        //入力エラーチェックの戻り値をそのまま表示
    }
}

エラー検出の結果がこんな感じになればちゃんとエラー検出できている。
(見づらい時は、画像をクリックして、大きい画像で表示してみてね)

Fig. 1: 入力エラーの検出
  • game-engineer/classes/2025/something-else/summertime-special-cource/console-4.txt
  • 最終更新: 6カ月前
  • by root