LoginSignup
7
6

More than 5 years have passed since last update.

「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム(C#で挑戦)

Last updated at Posted at 2015-07-16

「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるClojure
「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム
「進捗・どう・です・か」をHaskellで書いてみた
golang の進捗どうですか

おもしろそうだったのでC#で挑戦してみました。

うまい人が書くと、もっとシンプルになるんでしょうけど、まぁ。
(思いつくままに書いたコメントとかテスト用コードとかそのままです)

Program.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Word = System.Int32;

namespace ShinchokuDoudesuka
{
    class Program
    {
        static readonly string[] SDDK_WORDS = new string[] { "進捗", "どう", "です", "か" };

        static void Main()
        {
#if DEBUG
            Console.WriteLine("デバッグモードです");
            // テストデータ文字列(最後は必ず0123で終わること)
            string tstDatStr = "0002030100130120012101221230123";

            // テストデータを変換(文字列→数値配列)
            int x = 0;
            int[] tstDat = tstDatStr.Select(s => int.Parse(s.ToString())).ToArray<int>();

            Console.WriteLine("テストデータ確認");
            foreach (int ts in tstDat)
            {
                Console.Write(ts);
            }
            Console.WriteLine("");
#endif
            Random rnd = new Random();

            bool aoriFlg = false;   // 煽るか? t⇒煽る f⇒煽らない
            int tryCnt = 0;         // 試行回数
            bool asyStcFlg = false; // 文を組み立て中か? t⇒組み立て進行中 f⇒組み立ててない
            Word befW = 0;          // 1つ前の単語(比較用)
            #region 文が完成する(煽る)までの間、文を生成し続ける
            while (!aoriFlg)
            {
                //「進捗・どう・です・か」をランダムに取得し、表示する
                Word w = rnd.Next(SDDK_WORDS.Length);
#if DEBUG
                //乱数の代わりにテストデータを順に渡す
                w = tstDat[x++];
                Debug.Write(w);
#endif
                Console.Write(SDDK_WORDS[w]);

                #region 文が完成したか判定する
                if (asyStcFlg)
                {
                    #region 文を組み立て中の場合
                    if (w == (befW + 1))  // w == ++befWでも良いかも?
                    {
                        #region 単語が連続している場合
                        if (w == SDDK_WORDS.Length - 1)
                        {
                            // 文が完成した場合、煽る
                            tryCnt++;
                            aoriFlg = true;
                        }
                        else
                        {
                            // 組み立てが進行
                            befW = w;   // w == ++befWだったら、ここ削れる?
                        }
                        #endregion 単語が連続している場合
                    }
                    else
                    {
                        // 組み立てが失敗
                        asyStcFlg = false;
                        tryCnt++;
                    }
                    #endregion 文を組み立て中の場合
                }
                else
                {
                    #region 文を組み立ててない場合
                    if (w == 0)
                    {
                        // 組み立て開始
                        asyStcFlg = true;
                        befW = w;
                    }
                    else
                    {
                        // 失敗
                        tryCnt++;
                    }
                    #endregion 文を組み立ててない場合
                }
                #endregion 文が完成したか判定する
            }
            #endregion 文が完成する(煽る)までの間、文を生成し続ける

            Console.WriteLine("");
            Console.WriteLine("_人人人人人人人_");
            Console.WriteLine(">進捗どうですか<");
            Console.WriteLine(" ̄Y^Y^Y^Y^Y^Y^Y ̄");
            Console.WriteLine(string.Format("{0}回で煽られました", tryCnt));
        }
    }
}

2015/07/22 追記
「進捗・どう・です・か」をランダムに表示し「進捗どうですか」が完成したら煽ってくるプログラム(C#/LINQ)
に感銘を受け、書き直してみた。

しかし……あんまり進歩してない。

とりあえず、クラスに詰め込んでみた。
クラス設計、未だによく分からない。

ネストは減らせた。
ifまわりまだ整理できそうだけど、前より改善されたから良しとする。

Program.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
//using Word = System.Int32;

namespace ShinchokuDoudesuka
{
    class Program
    {
        public class Shinchoku
        {
            #region 定数&変数
            readonly string[] SDDK_WORDS = { "進捗", "どう", "です", "か" };   // 正解を文字列配列で定義
            readonly string SDDK_RLT_STR;                                      // 正解を文字列で定義

            List<string> words;                                                // LINQ用リスト(HashSetの方が速かった気がするけど、使い慣れたListで)。
            Random rnd;                                                        // 擬似乱数用変数
            int tryCnt;                                                        // 試行回数

            /// <summary>
            /// コンストラクタ
            /// </summary>
            public Shinchoku()
            {
                SDDK_RLT_STR = string.Join("", SDDK_WORDS);
                words = new List<string>();
                rnd = new Random();
                tryCnt = 0;
            }
            #endregion 定数&変数

            /// <summary>
            /// 完成したら煽る関数
            /// </summary>
            public void Aoru()
            {
                // 完成するまで表示を続ける
                while (!TryMakeWords())
                {
                    //必要なら復活しても良い
                    //Thread.Sleep(1);
                }

                Console.WriteLine("");
                Console.WriteLine("_人人人人人人人_");
                Console.WriteLine(">進捗どうですか<");
                Console.WriteLine(" ̄Y^Y^Y^Y^Y^Y^Y ̄");
                Console.WriteLine(string.Format("{0}回で煽られました", tryCnt));
            }

            /// <summary>
            /// 「進捗・どう・です・か」を1回だけ組み立ててみる
            /// </summary>
            /// <returns>完成したか? true⇒完成、false⇒未完成</returns>
            private bool TryMakeWords()
            {
                bool ret = false;

                // 1つの単語を追加する
                words.Add(SDDK_WORDS[rnd.Next(SDDK_WORDS.Length)]);

                // ここまでに作ったものmakingWordsと正解checkStrとを比べる
                string makingWords = string.Join("", words);
                string checkStr = string.Join("", SDDK_WORDS.Where((e, i) => i < words.Count));

                if (makingWords == checkStr)
                {
                    // 正解と完全一致したら完成
                    if (makingWords == SDDK_RLT_STR)
                    {
                        Console.Write(makingWords);
                        tryCnt++;
                        ret = true;
                    }
                }
                else
                {
                    // 不一致
                    Console.Write(makingWords);
                    tryCnt++;
                    words.Clear();
                }

                return ret;
            }
        }

        static void Main()
        {
            Shinchoku s = new Shinchoku();
            s.Aoru();
        }
    }
}
7
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
6