正解判定とか

あとは正解判定をして、正解の時はおめでとうメッセージを表示して終わるとかすれば完成です。
つまり

今回のルール

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

の部分をこしらえて完成!

正誤判定(C言語の人)

後は、1文字ずつ同じかどうか順番に比べちゃえばいいよね。C言語の文字列なんてどうせchar型が1文字ずつ入った配列+'\0'なので。。。
それでもいいんだけど、string.hに便利な関数があります。
strcmp を使えば、引数の2つの文字列が等しいかどうか判別できます。

使い方

int strcmp(const char *s1, const char *s2);

文字列s1 と 文字列s2 を先頭から比較します。

戻り値で結果を判定:

負 (<0)
s1 が辞書順で前
0
完全に一致
正 (>0)
s1 が辞書順で後

これで、入力と問題の文字列が一致していたら、入力ループを抜けて結果表示へ、それ以外であれば、
Hit,Blowの表示の処理へ分岐すれば、ゲームとして完成しそうな気がする。

"正解判定入り入力ループ"
int main()
{
    //実体作っておかないと怒られるよ
    char answer[5];
    char input[255];//入力は、何入れられるかわからんので多めに取っておく
    //配列の初めから4つ取り出してresStrにコピー
    MakeProblem(answer);
    //printf("答えは %s です。\n", resStr); 
    // //デバッグ用に答えを表示(実際のゲームではコメントアウトすること) 
 
    printf("Hit & Blow ゲーム\n");
    printf("ゲーム開始!\n");
    while (1) //C言語でもwhile(true)ぐらいは使ってもいい気もする(おまかせ)
    {
        printf("予想した4桁の整数を入力:");
	scanf("%s", &input);
	if (エラー処理で問題なかったら) {
            if(もし正解だったら)
                break;//どうせ正解したらループ抜けちゃうから、elseと書かなくてすむ
            //HIT数を数えて表示
	    printf(" Hit: %02d\n",  ごにょごにょ);
            //BLOW数を数えて表示
	    printf("Blow: %02d\n", ごにょごにょ);
	}
    }
    //正解した時しかここにたどり着かない。
    //ループの中で処理してもいいけど、今回はこんな感じにしてみました。
    printf("おめでとう、正解は %s でした!\n", resStr);
    printf("ゲーム終了!\n");
    return 0;
}

正誤判定(C++の人)

文字列同士が同じかどうかはどうやったら判定できるっけ?
C言語では、 strcmp関数を使わないと文字列比較ができないですし、そもそも文字列という方がなかったので、文字配列+'\0'なんていう、疲れるものを使っていました。(みんなにも文字配列による文字列表現は教えたけど、C言語のことは知らんよね)
string同士の比較はどうやるかは教えてあると思うのでそれを使ってください。
そうすると、メインのループは以下のようになります。

"正解判定入り入力ループ"
int main()
{
	string answer = "0000"; //正答
	string input = "0000"; //入力用
	srand((unsigned int)(time(nullptr)));
 
	MakeProblem(answer);
 
	cout << "THE HIT AND BLOW GAME" << endl;
	cout << "Let's Play the GAME!!" << endl;
	while (true)
	{
		cout << "予想した4桁の整数を入力:";
		cin >> input;
		if (エラー処理で問題なかったら) {
                        if(もし正解だったら)
                           break;//どうせ正解したらループ抜けちゃうから、elseと書かなくてすむ
                        //HIT数を数えて表示
			cout << " Hit:" << HIT数カウント呼び出し << endl;
                        //BLOW数を数えて表示
			cout << "Blow:" << BLOW数カウント呼び出し << endl;
		}
	}
        //正解した時しかここにたどり着かない。
        //ループの中で処理してもいいけど、今回はこんな感じにしてみました。
	cout << "おめでとう!" << endl;
	cout << "答えは" << answer << "でした" << endl;
	return 0;
}

実行例を載せておくので参考にしてください。
見づらい時は、画像をクリックして拡大してみてね

Fig. 1: 実行例(あんま効率いい解き方じゃないけど

後は、ゲームの追加要素として以下のようなものを考えてみよう!

  1. タイトル、プレイ、結果画面の移行
  2. エラーの種類(何が悪かったのか)を表示してから再入力を促す
  3. 入力メニューと履歴表示の追加
  4. 桁数を変えてみる
  5. ソースとヘッダの分離(関数のプロトタイプ宣言と、定義を別ファイルにする)
  6. Siv3Dによるグラフィック表示

例えば、履歴の表示は以下のようなイメージ
いつも通り見づらい時は(ry

Fig. 2: 履歴の表示
  • game-engineer/classes/2025/something-else/summertime-special-cource/console-6.txt
  • 最終更新: 6カ月前
  • by root