一筆書きのパズル(中編)

こんにちは、きうちです。

今回は前回の一筆書きのパズル(前編)の続きをお届けします。

前回までで、自機を動かすとその足跡が残り、何もないところを足跡で埋め尽くすとクリア、というところまでできました。

しかし前回はステージが1つだけでしたので、今回はステージを増やしてみたいと思います!

あとすいません、前編、ちょっと抜けがありました。

フォームの背景色を黒にするのと、再描画のちらつきを抑えるためにフォームの DoubleBuffered を true にします、というのが抜けていました。

ここで補足させていただきます。

★ ★ ★

ステージを増やすために、ステージ定義用のクラスを用意します。

名前はMapとします。

その中にstaticなフィールドを用意して、そこに定義します。

こんな感じです。

    internal class Map
    {
        internal static string[][] Stages =
        {
            new string[]
            {
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
                "22222000000000022222",
                "22222000000000022222",
                "22222000000000022222",
                "22222000000000022222",
                "222220000M0000022222",
                "22222000000000022222",
                "22222000000000022222",
                "22222000000000022222",
                "22222000000000022222",
                "22222000000000022222",
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
            },
            new string[]
            {
                "22222222222222222222",
                "22222222222222222222",
                "22M00222222222222222",
                "22220002222222222222",
                "22222200022222222222",
                "22222222000222222222",
                "22222222220002222222",
                "22222222222200022222",
                "22222222222222000222",
                "22222222222222220002",
                "22222222222222220002",
                "22222222222222000222",
                "22222222222200022222",
                "22222222220002222222",
                "22222222000222222222",
                "22222200022222222222",
                "22220002222222222222",
                "22000222222222222222",
                "22222222222222222222",
                "22222222222222222222",
            },
            new string[]
            {
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
                "22200000000000000222",
                "22200000000000000222",
                "22200000000000000222",
                "22200000000000000222",
                "222000000000M0000222",
                "22200022222222000222",
                "22200022222222000222",
                "22200022222222000222",
                "22200022222222000222",
                "22200022222222000222",
                "22200022222222000222",
                "22200000000000000222",
                "22200000000000000222",
                "22200000000000000222",
                "22222222222222222222",
                "22222222222222222222",
                "22222222222222222222",
            },
        };
    }

全3ステージ用意してみました。

本当はもっと用意できたら…と思うんですけど、意外と大変なんですよねこれ。

つくるの。

あと、この記事が縦に長くなってしまってダレそうなので3ステージでご勘弁を^^;

なお、この定義の中で0が何もない場所、2が壁、Mが自機の最初の位置です。

そしたら、今度は ステージ番号を示すフィールドを追加するのと、Init メソッドをこんな風に変えます。

前に書いていたInitメソッドはコメントアウトするか、別な名前に変えてしまいましょう。

    private int stage = 0; // ステージ番号

    private void Init() // セル初期化
    {
        // マップデータ
        for (int y = 0; y < Map.Stages[stage].Length; y++)
        {
            for (int x = 0; x < Map.Stages[stage][y].Length; x++)
            {
                var s = Map.Stages[stage][y].Substring(x, 1);
                if (s == "M")
                {
                    mx = x;
                    my = y;
                }
                else
                {
                    cells[x, y] = int.Parse(s);
                }
            }
        }


        // 最初に自機がいる箇所に軌跡を置く
        cells[mx, my] = 1;
    }

「判定とおめでとうメッセージ」のところをこんな風に変えます。

    if (IsOver()) // 判定とおめでとうメッセージの追加
    {
        MessageBox.Show("おめでとう!");
        stage++;
        if (stage >= Map.Stages.Length)
        {
            stage = 0;
        }
        Init();
        Refresh();
    }

    private bool IsOver() // クリアしたか判定する
    {
        bool result = true;

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                if (cells[x, y] == 0) // 何もないセルが存在したら
                {
                    result = false; // まだ終わっていないものとする
                    break;
                }
            }
        }

        return result;
    }

これで実行してみると…

前回と同じステージが表示されます。

クリアすると…

別なステージが表示されます。

3面をクリアすると…

1面に戻ります。

もし、2面からやってみたい、という場合は

private int stage = 0; // ステージ番号

となっているところを1にすればいいです。

ステージを追加したい場合はMapクラスのStagesに追加してあげてください。

★ ★ ★

…しかしまあ、ステージを作り足すのめんどくさいですね!

自動化できないかな!?

…この「面倒くさいから自動化したい」っての、ITエンジニアリングのコアですよね(笑)

次回は自動的にステージを作る方法を考えてみたいと思います。

ではまた!