ゲームを作っていくぅ
まず、いつもの通りプロジェクトを作ります。
今回はコンソールアプリなので、Visual Studioでも、Replitでも、paiza.ioでも実行できます。
(もう何も見ないでプロジェクトを作れない人はいないよね……?)
今回のルール
* 重複しない4桁の数字がランダムに生成される * プレイヤーは、毎ターン4桁の数字を入力する * コンピュータは、入力された数字と正解を比較して、次の結果を返す
- ヒット:数字も位置も正解と一致している桁数
- ブロー:数字は正解に含まれているが、位置が違う桁数
* ヒットが4になった場合は、入力した数字が正解なので、正解メッセージを表示する * ヒットが4未満の場合は、もう一度入力を促す * 正解するまで、これを繰り返す
これらのルールを踏まえて、ゲームを組み立てていきましょう。
入力方法を考える
「4桁の整数を入力してください」と言われたら、コンソールプログラムではどのように書くでしょうか。
#include <stdio.h> int main() { int number; ``` printf("4桁の整数を入力してください: "); scanf("%d", &number); printf("入力された数は: %d\n", number); return 0; ``` }
おそらく、最初はこのように書くと思います。
では、問題です。
このプログラムをHit & Blowゲームの入力処理として使った場合、どのような問題があるでしょうか?
このようなことを考えるのは、プログラムを作り始める前の設計段階でとても大切です。
考えられる問題には、次のようなものがあります。
* 入力を4桁に限定できていない
- 3桁以下でも入力できる
- 5桁以上でも入力できる
* 0から始まる4桁の数字を扱うことができない
- 例えば「0123」を整数として入力すると「123」として扱われる
次の実行結果を確認してください。
図1 整数として入力した場合の実行結果
文字列として入力する
では、どのように入力すればよいでしょうか。
長い文章や、数字と文字が混ざったデータを処理するときには、一度すべての入力を文字列として受け取る方法がよく使われます。
文字列として受け取ったあとで、必要な部分を解析し、それぞれのデータとして取り出します。
今回は、入力された内容を文字列として受け取り、文字数が4文字であるかを確認します。
#define _CRT_SECURE_NO_WARNINGS #include <cstdio> #include <cstring> int main() { char str[255] = ""; ``` printf("4桁の数字を入力してください: "); scanf("%254s", str); if (strlen(str) == 4) { printf("入力された数字は: %s\n", str); } else { printf("4桁ではありません。\n"); } return 0; ``` }
`scanf`の`%254s`は、配列の大きさを超えて文字が入力されないようにするための指定です。
このプログラムでは、入力された文字列の長さを`strlen`関数で調べています。
* 入力された文字数が4文字なら、入力内容を表示する * 4文字でなければ、エラーメッセージを表示する
図2 文字列として入力した場合の実行結果
入力された文字を1桁ずつ調べる
文字列として入力すると、それぞれの桁を配列の要素として扱えます。
例えば、次のように入力されたとします。
0123
この文字列は、配列の中では次のように保存されています。
| 配列の添え字 | 保存されている文字 |
|---|---|
| 0 | '0' |
| 1 | '1' |
| 2 | '2' |
| 3 | '3' |
この仕組みを利用すると、次の2つの情報を扱えます。
* 桁の位置
- 配列の添え字で判断する
* その桁にある数字
- 配列に保存されている文字で判断する
入力された文字列と、正解として作成した文字列を比較すれば、ヒットとブローを判定できます。
* 配列の添え字も文字も同じ
- ヒット
* 文字は正解の中にあるが、配列の添え字が違う
- ブロー
例えば、正解が「1234」で、入力が「1325」だった場合は次のようになります。
| 桁 | 正解 | 入力 | 判定 |
|---|---|---|---|
| 1桁目 | 1 | 1 | ヒット |
| 2桁目 | 2 | 3 | ブロー |
| 3桁目 | 3 | 2 | ブロー |
| 4桁目 | 4 | 5 | 該当なし |
この場合の結果は、次のようになります。
1 Hit 2 Blow