プログラミングの実戦課題 - テキストベースのロールプレイングゲームを創る ②「switch-case バージョン」
こんばんは。九条です。
今回の記事は次の記事の続編となります。
今回は if-else if-else 文を switch-case 文に書き換える手法を勉強します。
仕様
今回は次の仕様で作ります。
①.貴方は荒野にいる。北へ行くなら1を、東へ行くなら2を、南へ行くなら3を、西へ行くなら4を、入力してください。
②.1または3の場合(北または南の場合)、「宝物を見つけた!あなたはこのゲームをクリアした。」
③.2または4の場合(西または東の場合)、「魔王に遭遇して殺害された、Game Over!」
④.それ以外が入力された場合、「突然現れた次元の狭間に吸い込まれた、Game Over!」
今回の課題で学べること
今回は、まず if-else if-else 文だけを使い、仕様を実現します。その後、「||」演算子(ショートサーキット効果付きOR演算子)を使ってプログラムを書き換えます。その後、更に if-else if-else 文を switch-case 文に書き換えることで、 if-else if-else 文が色々な形に書き換えできることを勉強します。
回答1
では作ってみましょう。
正解は次のようになります。
using System;
namespace RPG2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("貴方は荒野にいる。北へ行くなら1を、東へ行くなら2を、南へ行くなら3を、西へ行くなら4を、入力してください。");
string input = Console.ReadLine();
if (input == "1")
{
Console.WriteLine("宝物を見つけた!あなたはこのゲームをクリアした。");
}
else if (input == "2")
{
Console.WriteLine("魔王に遭遇して殺害された、Game Over!");
}
else if (input == "3")
{
Console.WriteLine("宝物を見つけた!あなたはこのゲームをクリアした。");
}
else if (input == "4")
{
Console.WriteLine("魔王に遭遇して殺害された、Game Over!");
}
else
{
Console.WriteLine("突然現れた次元の狭間に吸い込まれた、Game Over!");
}
}
}
}
解説1
このままでも十分に仕様を満たしますが、このプログラムには、次の問題があります。
(問題点①)次の行が2度も登場しています。
Console.WriteLine("宝物を見つけた!あなたはこのゲームをクリアした。");
(問題点②)次の行が2度も登場しています。
Console.WriteLine("魔王に遭遇して殺害された、Game Over!");
もう一度、仕様を見てみましょう。仕様の中に「または」という言葉が登場しています。
仕様に「または」と言う言葉がある場合は、「||」演算子を使って、重複をまとめてひとつにすることができます。
回答2
「||」演算子を使ってプログラムを書き換えると次のようになります。
using System;
namespace RPG2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("貴方は荒野にいる。北へ行くなら1を、東へ行くなら2を、南へ行くなら3を、西へ行くなら4を、入力してください。");
string input = Console.ReadLine();
if (input == "1" || input == "3")
{
Console.WriteLine("宝物を見つけた!あなたはこのゲームをクリアした。");
}
else if (input == "2" || input == "4")
{
Console.WriteLine("魔王に遭遇して殺害された、Game Over!");
}
else
{
Console.WriteLine("突然現れた次元の狭間に吸い込まれた、Game Over!");
}
}
}
}
プログラムの重複が無くなり、だいぶ見やすくなりました。
しかし、これはこれで別の問題があります。
例えば次のような要望が付いたらどうでしょう。
要望
3の場合(南の場合)だけ、「落とし穴に堕ちて死んでしまった、Game Over!」に変更する。
解説2
プログラムは省略しますが、この場合、else-if 文をもうひとつ追加する必要がある上に、既存の if 文の条件まで変更する必要があります。これは変更に失敗しやすいパターンであり、この程度のプログラムであればまだいいですが、複雑なプログラムの場合は、変更するのが怖くなってしまいます。
※変更するのが怖いというのは、既に動作しているものが動作しなくなった場合は、プロとしては著しく信用を失うからです。変更によって、既に動作しているものが動作しなくなることをデグレード(デグレ)と言います。怖いとしても、その変更をしなければならない場合は、テストに投資することでデグレを防ぎます。
このような要望を想定するなら「||」演算子を使わない回答1のバージョンが望ましいかもしれません。
そこで、switch-case 文の出番です。
最初に述べたように、if-else if-else 文は switch-case 文に書き換えることができる場合があります。
では、書き換えてみましょう。
回答3
switch-case 文を使ってプログラムを書き換えると次のようになります。
using System;
namespace RPG2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("貴方は荒野にいる。北へ行くなら1を、東へ行くなら2を、南へ行くなら3を、西へ行くなら4を、入力してください。");
string input = Console.ReadLine();
switch (input)
{
case "1":
case "3":
Console.WriteLine("宝物を見つけた!あなたはこのゲームをクリアした。");
break;
case "2":
case "4":
Console.WriteLine("魔王に遭遇して殺害された、Game Over!");
break;
default:
Console.WriteLine("突然現れた次元の狭間に吸い込まれた、Game Over!");
break;
}
}
}
}
これであれば、非常にプログラムが見やすい上に、要望対応もしやすくなりました。
要望対応したプログラムも記載しておきます。
using System;
namespace RPG2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("貴方は荒野にいる。北へ行くなら1を、東へ行くなら2を、南へ行くなら3を、西へ行くなら4を、入力してください。");
string input = Console.ReadLine();
switch (input)
{
case "1":
Console.WriteLine("宝物を見つけた!あなたはこのゲームをクリアした。");
break;
case "3":
Console.WriteLine("落とし穴に堕ちて死んでしまった、Game Over!");
break;
case "2":
case "4":
Console.WriteLine("魔王に遭遇して殺害された、Game Over!");
break;
default:
Console.WriteLine("突然現れた次元の狭間に吸い込まれた、Game Over!");
break;
}
}
}
}
要望対応する前とした後のプログラムをよく見比べてみましょう。
今回は以上です。