演習 - if ステートメントを使用して決定ロジックを作成する
ほとんどのアプリケーションには、多数の実行パスが含まれています。 たとえば、あるアプリケーションは、ユーザーが選択するメニュー オプションに基づいて異なる実行パスを実装できます。 開発者は、異なる実行パスを実装するコードを "コード ブランチ" と呼びます。
最も広く使用されている分岐ステートメントは、if
ステートメントです。 if
ステートメントでは、一連のかっこで囲まれたブール式が使用されます。 式が true の場合は、if
ステートメントの後のコードが実行されます。 そうでない場合、.NET ランタイムではコードは無視されて、実行されません。
この演習では、ゲームを作成することで if
ステートメントを記述する練習をします。 まず、ゲームのルールを定義してから、それをコードに実装します。
Random.Next()
メソッドを使用して、6 面のサイコロ 3 個を転がすことをシミュレートします。 出た目を評価してスコアを計算します。 スコアが任意の合計より大きい場合は、ユーザーに勝ちメッセージを表示します。 スコアが基準値を下回っている場合は、ユーザーに負けメッセージを表示します。
- 転がしたサイコロのうちいずれか 2 つが同じ値になると、ダブルのボーナス ポイントとして 2 点与えられます。
- 転がした 3 つのサイコロすべてが同じ値になると、トリプルのボーナス ポイントとして 6 点与えられます。
- 3 つのサイコロの目の合計にボーナス ポイントを加えた値が 15 以上の場合、ゲームはあなたの勝ちになります。 それ以外の場合は、あなたの負けです。
if
ステートメントの詳細を確認しながら、ルールを調整します。
重要
この演習では、System.Random
クラスを広範囲に使用します。 Random.Next()
のしくみを再確認する必要がある場合は、「C# を使用して .NET クラス ライブラリからメソッドを呼び出す」というタイトルの Microsoft Learn モジュールを参照できます。
コーディング環境を準備する
このモジュールには、サンプル コードをビルドして実行するプロセスをガイドするアクティビティが含まれています。 これらのアクティビティを完了するには、開発環境として Visual Studio Code を使用することをお勧めします。 これらのアクティビティに Visual Studio Code を使用すると、世界中のプロフェッショナルが使用する開発環境でコードの記述と実行をより快適に行うことができます。
Visual Studio Code を開きます。
Visual Studio Code は、Windows の [スタート] メニュー (別の OS の場合は同等のリソース) を使用して開くことができます。
Visual Studio Code の [ファイル] メニューで、[フォルダーを開く] を選択します。
[フォルダーを開く] ダイアログで、Windows のデスクトップ フォルダーに移動します。
コード プロジェクトを保持するフォルダーの場所が別にある場合は、代わりにそのフォルダーの場所を使用できます。 このトレーニングでは、見つけやすく覚えやすい場所を用意することが重要です。
[フォルダーを開く] ダイアログで、[フォルダーの選択] を選びます。
作成者を信頼するかどうかを確認するセキュリティ ダイアログが表示された場合は、[はい] を選択します。
Visual Studio Code の [ターミナル] メニューで、[新しいターミナル] を選択します。
[ターミナル] パネルのコマンド プロンプトに、現在のフォルダーのフォルダー パスが表示されることを確認します。 次に例を示します。
C:\Users\someuser\Desktop>
Note
サンドボックスやホスト環境ではなく、自分の PC で作業しており、この C# シリーズの他の Microsoft Learn モジュールを完了している場合は、コード サンプル用のプロジェクト フォルダーが既に作成されている可能性があります。 その場合は、次の手順 (TestProject フォルダーにコンソール アプリを作成するために使用される) をスキップできます。
ターミナルのコマンド プロンプトで、指定したフォルダーに新しいコンソール アプリケーションを作成するには、「dotnet new console -o ./CsharpProjects/TestProject」と入力し、Enter キーを押します。
この .NET CLI コマンドでは、.NET プログラム テンプレートを使用して、指定したフォルダーの場所に新しい C# コンソール アプリケーション プロジェクトを作成します。 このコマンドでは、CsharpProjects および TestProject フォルダーが自動的に作成され、
.csproj
ファイルの名前として TestProject が使用されます。[エクスプローラー] パネルで、CsharpProjects フォルダーを展開します。
[TestProject] フォルダーと、Program.cs という名前の C# プログラム ファイルと、TestProject.csproj という名前の C# プロジェクト ファイルの 2 つが表示されるはずです。
[エクスプローラー] パネルの [エディター] パネルにコード ファイルを表示するには、[Program.cs] を選択します。
既存のコード行を削除します。
この C# コンソール プロジェクトを使用して、このモジュール中のコード サンプルを作成、ビルド、および実行します。
[ターミナル] パネルを閉じます。
3 つの乱数を生成して出力に表示するコードを記述する
Visual Studio Code で空の Program.cs ファイルが開かれていることを確認します。
この演習の最初のコードを作成するには、次を入力します。
Random dice = new Random(); int roll1 = dice.Next(1, 7); int roll2 = dice.Next(1, 7); int roll3 = dice.Next(1, 7); int total = roll1 + roll2 + roll3; Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}");
少し時間を取って、入力したコードを確認します。
まず、
System.Random
クラスの新しいインスタンスを作成し、dice
という名前の変数にオブジェクトへの参照を格納します。 次に、dice
オブジェクトでRandom.Next()
メソッドを 3 回呼び出し、下限と上限の両方を指定して、生成される値を1
から6
の間に制限します (上限の値は含まない)。 3 つの乱数を、それぞれ変数roll1
、roll2
、roll3
に保存します。次に、3 つのサイコロの目を合計し、
total
という名前の整数変数に値を保存します。最後に、
WriteLine()
メソッドを使用して、文字列補間を使用して 3 つの値を表示します。コードを実行すると、次のようなメッセージが表示されます (値は異なります)。
Dice roll: 4 + 5 + 2 = 11
この最初のタスクは設定タスクでした。 ゲームをいっそう面白くするための決定ロジックを、コードに追加できるようになりました。
合計変数の値に基づいて異なるメッセージを表示するための if ステートメントを追加する
Visual Studio Code エディターで、コード ファイルの下部にあるカーソルに移動して、空のコード行を作成します。
最初のゲーム機能を作成するには、次の
if
ステートメントを入力します。if (total > 14) { Console.WriteLine("You win!"); } if (total < 15) { Console.WriteLine("Sorry, you lose."); }
これら 2 つの
if
ステートメントは、勝ちと負けのシナリオを処理するために使用されます。 少し時間を取って、最初のif
ステートメントを確認します。if
ステートメントが、次の 3 つの部分で構成されていることに注目してください。if
キーワード- かっこ
()
の間の "ブール式" - 中かっこ
{ }
で定義された "コード ブロック"
実行時には、ブール式
total > 14
が評価されます。 このステートメントが true の場合 (つまりtotal
の値が14
より大きい場合) は、実行のフローはコード ブロックで定義されているコードに続きます。 つまり、中かっこ内のコードが実行されます。一方、ブール式が false の場合 (つまり
total
の値が14
より大きくない場合) は、実行のフローはコード ブロックをスキップします。 つまり、中かっこ内のコードは実行されません。最後に、2 番目の
if
ステートメントでは、ユーザーが負けた場合のメッセージが制御されます。 次のユニットでは、if
ステートメントのバリエーションを使用して、これらの 2 つのステートメントを 1 つのステートメントに短縮し、意図をより明確に表現します。
ブール式とは
ブール式とは、true
または false
のどちらかのブール値が返される任意のコードです。 最も簡単なブール式は、単なる値 true
および false
です。 または、ブール式は、値 true
または false
を返すメソッドの結果である場合もあります。 たとえば、string.Contains()
メソッドを使用して、ある文字列に別の文字列が含まれているかどうかを評価する簡単なコードの例を次に示します。
string message = "The quick brown fox jumps over the lazy dog.";
bool result = message.Contains("dog");
Console.WriteLine(result);
if (message.Contains("fox"))
{
Console.WriteLine("What does the fox say?");
}
message.Contains("fox")
からは値 true
または false
が返されるため、ブール式として適格であり、if
ステートメントで使用できます。
演算子を使用して 2 つの値を比較することで、他の簡単なブール式を作成できます。 次のような演算子があります。
==
: 等しいかどうかをテストする "等値" 演算子>
: 左辺の値が右辺の値より大きいことをテストする "大なり" 演算子<
: 左辺の値が右辺の値より小さいことをテストする "小なり" 演算子>=
: "以上" 演算子<=
: "以下" 演算子- その他
Note
Microsoft Learn の C# トレーニング シリーズでは、モジュール全体をブール式に充当しています。 ブール式の作成に使用できる演算子は多数ありますが、このモジュールではいくつかの基本的なものについてのみ説明します。 ブール式の詳細については、「C# でブール式を評価して決定する」というタイトルの Microsoft Learn モジュールを参照してください。
この例では、ブール式 total > 14
を評価しました。 ただし、ブール式 total >= 15
を選択することもできました。この場合、これらは同じだからです。 ゲームのルールで、"3 つのサイコロの目とボーナスの合計が 15 以上の場合は、あなたの勝ちです" と指定されていたら、>= 15
式を実装する方が望ましいと考えられます。 その変更は、演習の次のステップで行います。
コード ブロックとは
コード ブロックとは、開始と終了の中かっこ記号 { }
で定義された 1 行以上のコードのコレクションです。 ソフトウェア システムでの 1 つの目的を持つコードの完全なユニットを表します。 この例では、実行時に、ブール式が true の場合、コード ブロック内のすべてのコード行が実行されます。 逆に、ブール式が false の場合は、コード ブロック内のすべてのコード行が無視されます。
コード ブロックに他のコード ブロックを含められることもわかるはずです。 実際には、アプリケーション内の別のコード ブロック内に 1 つのコード ブロックが "入れ子にされる" のが一般的です。 このモジュールの後半で、別のコード ブロック内に if
ステートメントを作成するときに、独自のコード ブロックの入れ子を開始します。
Note
Microsoft Learn の C# トレーニング シリーズでは、モジュール全体をコード ブロックの理解に充当しています。 コード ブロックは、コードの編成と構造を理解するときの中心的な要素であり、変数のスコープの境界が定義されています。 モジュール [Control variable scope and logic using code blocks in C#](TBD)
を参照してください。
別の if ステートメントを追加してダブル ボーナスを実装する
ここでは、"転がしたサイコロのうちいずれか 2 つが同じ値になった場合、ダブルのボーナス ポイントとして 2 点を与える" というルールを実装することができます。 次のコード リストと一致するように、前のステップのコードを変更します。
Visual Studio Code エディターで、最初の
if
ステートメントの上にある空白のコード行にカーソルを置きます。"ダブル" のゲーム機能を作成するには、次の
if
ステートメントを入力します。if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)) { Console.WriteLine("You rolled doubles! +2 bonus to total!"); total += 2; }
ここでは、3 つのブール式を結合して、1 行のコードで 1 つの複合ブール式を作成します。 これは、"複合条件" と呼ばれることがあります。 2 つのパイプ文字で区切られた内側の 3 つのかっこのセットを結合する、外側の 1 つのかっこのセットを作成します。
二重のパイプ文字
||
は論理 OR 演算子です。基本的に、"ブール式全体が true になるためには、左側の式または右側の式が true である必要がある" という意味です。 両方のブール式が false の場合、ブール式全体が false になります。 3 番目のブール式まで評価を拡張できるように、2 つの論理 OR 演算子を使用します。最初に、
(roll1 == roll2)
を評価します。 それが true の場合、式全体が true になります。 それが false の場合、(roll2 == roll3)
を評価します。 それが true の場合、式全体が true になります。 それが false の場合、(roll1 == roll3)
を評価します。 それが true の場合、式全体が true になります。 それが false の場合、式全体が false になります。複合ブール式が true の場合は、次のコード ブロックを実行します。 今度は、2 行のコードがあります。 1 行目のコードでは、ユーザーに対するメッセージを出力します。 2 行目のコードでは、
total
の値を2
だけインクリメントします。コードの読みやすくするには、2 番目の
if
ステートメントを次のように更新します。if (total >= 15)
勝ちの評価に使用される式で
>=
演算子を使用していることに注目してください。>=
演算子は "以上" を意味します。 その結果、total
を、14
ではなく15
の値と比較できます。 これらの変更により、勝ちの評価のために使用する式が、負けを評価する式と近くなります。 これで、コードが理解しやすく (読みやすく) なります。 整数値を扱っているため、新しい式(total >= 15)
は前に(total > 14)
を記述した式と同じように機能します。少し時間を取ってコードを確認してください。
コードは以下と一致するようになります。
Random dice = new Random(); int roll1 = dice.Next(1, 7); int roll2 = dice.Next(1, 7); int roll3 = dice.Next(1, 7); int total = roll1 + roll2 + roll3; Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}"); if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)) { Console.WriteLine("You rolled doubles! +2 bonus to total!"); total += 2; } if (total >= 15) { Console.WriteLine("You win!"); } if (total < 15) { Console.WriteLine("Sorry, you lose."); }
勝ちと負けの評価に使用される式の配置が改善されていることに注目してください。
別の if ステートメントを追加してトリプル ボーナスを実装する
ここでは、"転がした 3 つのサイコロすべてが同じ値になった場合、トリプルのボーナス ポイントとして 6 点を与える" というルールを実装します。次のコード リストと一致するように、前のステップのコードを変更します。
Visual Studio Code エディターで、"ダブル" の
if
ステートメントのコード ブロックの下に空白のコード行を作成します。"トリプル" のゲーム機能を作成するには、次の
if
ステートメントを入力します。if ((roll1 == roll2) && (roll2 == roll3)) { Console.WriteLine("You rolled triples! +6 bonus to total!"); total += 6; }
ここでは、2 つのブール式を結合して、1 行のコードで 1 つの複合ブール式を作成します。 2 つのアンパサンド文字で区切られた内側の 2 つのかっこのセットを結合する、外側の 1 つのかっこのセットを作成します。
二重のアンパサンド文字
&&
は論理 AND 演算子です。基本的に、"両方の式が true の場合にのみ、式全体が true になる" という意味です。 この場合、roll1
がroll2
と等しく、roll2
がroll3
と等しい場合、推論によってroll1
はroll3
と等しくなるはずで、ユーザーはトリプルを出しました。Visual Studio Code [ファイル] メニューの [保存] をクリックします。
少し時間を取ってコードを確認してください。
コードが以下と一致していることを確かめます。
Random dice = new Random(); int roll1 = dice.Next(1, 7); int roll2 = dice.Next(1, 7); int roll3 = dice.Next(1, 7); int total = roll1 + roll2 + roll3; Console.WriteLine($"Dice roll: {roll1} + {roll2} + {roll3} = {total}"); if ((roll1 == roll2) || (roll2 == roll3) || (roll1 == roll3)) { Console.WriteLine("You rolled doubles! +2 bonus to total!"); total += 2; } if ((roll1 == roll2) && (roll2 == roll3)) { Console.WriteLine("You rolled triples! +6 bonus to total!"); total += 6; } if (total >= 15) { Console.WriteLine("You win!"); } if (total < 15) { Console.WriteLine("Sorry, you lose."); }
[エクスプローラー] パネルで、TestProject フォルダーの場所にあるターミナルを開くには、TestProject を右クリックし、[統合ターミナルで開く] を選択します。
ターミナル パネルが開き、ターミナルが TestProject フォルダーの場所に対して開かれていることを示すコマンド プロンプトが含まれているはずです。
コードを実行するには、ターミナルのコマンド プロンプトで、「dotnet run」と入力し、Enter キーを押します。
Note
"実行するプロジェクトが見つかりませんでした" というメッセージが表示された場合は、ターミナルのコマンド プロンプトに、予期されている TestProject フォルダーの場所が表示されていることを確かめます。 例:
C:\Users\someuser\Desktop\csharpprojects\TestProject>
次のいずれかの結果のような出力が表示されるはずです。
Dice roll: 3 + 6 + 1 = 10 Sorry, you lose.
または、次のようになることがあります。
Dice roll: 1 + 4 + 4 = 9 You rolled doubles! +2 bonus to total! Sorry, you lose.
または、次のようになることがあります。
Dice roll: 5 + 6 + 4 = 15 You win!
または、運が良ければ、次のように表示されます。
Dice roll: 6 + 6 + 6 = 18 You rolled doubles! +2 bonus to total! You rolled triples! +6 bonus to total! You win!
でも待ってください。本当に、トリプル ボーナスとダブル ボーナスの両方をプレーヤーに与える必要があるのでしょうか。 結局のところ、トリプルの目が出た場合は、ダブルの目も出たことになります。 ボーナスは "重複" しないことが理想的です。 2 つの個別のボーナス条件が必要です。 このロジックのバグは、修正する必要があります。
ロジックでの問題、そしてコードを改善する機会
出だしとしてはうまくいっており、if
ステートメント、ブール式、コード ブロック、論理 OR 演算子、論理 AND 演算子などについて多くのことを学びましたが、改善できることがたくさんあります。 それは次のユニットで行います。
まとめ
- コードのロジックを分岐させるには、
if
ステートメントを使用します。if
決定ステートメントでは、そのブール式が true に等しい場合、コード ブロック内のコードが実行されます。 それ以外の場合、コード ブロックはスキップされて、コード ブロックの後にある次のコード行に進みます。 - ブール式は、ブール値を返す任意の式です。
- ブール演算子では、左側と右側の 2 つの値が等しいかどうかなどの比較が行われます。
- コード ブロックは中かっこ
{ }
によって定義されます。 1 つのユニットとして処理する必要があるコード行の集合です。 - 論理 AND 演算子
&&
によって 2 つの式が結合されている場合、式全体が true であるためには、両方の部分式が true である必要があります。 - 論理 OR 演算子
||
によって 2 つの式が結合されている場合、式全体が true であるためには、少なくともどちらか一方の部分式が true である必要があります。