見出し画像

プログラミングの実戦課題 - テキストベースのロールプレイングゲームを創る ②「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;

           }
       }
   }
}

要望対応する前とした後のプログラムをよく見比べてみましょう。

今回は以上です。

この記事が気に入ったらサポートをしてみませんか?