*で囲まれた中を塗りつぶす

//  "....:....1....:....2....:....3....:....4....:....5....:....6",
{   "************************************************************",  //1
    "******   ******************************************  *******",  //2
    "*****    *****************************************    ******",  //3
    "*****   ******                         ************    *****",  //4
    "****  *******                               *******     ****",  //5
    "******                                     *********    ****",
    "***                                 ***************     ****",
    "***                                    **********       ****",
    "**************                                   **    *****",
    "******  ***************    ************* ***********  ******",  //10
    "*****     ***********   ***************    *****************",
    "****       ************   **********     *******************",
    "***          ************ **************   *****************",
    "*****       ************* **************** *****************",
    "*******    **************        ********   ****************",  //15
    "********   ***********                *****    *************",
    "*********  ****                **************   ************",
    "*******      ********                    *****  ************",
    "********    ****************        ************************",
    "************************************************************"   //20
};
//  "....:....1....:....2....:....3....:....4....:....5....:....6",
*で囲まれた中を塗りつぶす「C# 再起関数」のプログラムです。

前田稔(Maeda Minoru)の超初心者のプログラム入門

プログラムの説明

  1. フォルダーに次のファイルを格納して下さい。
    /************************************/
    /*★ 内部を塗りつぶす     前田 稔 ★*/
    /************************************/
    using System;
    
    class Prog
    {
        static string[] st =
    //  "....:....1....:....2....:....3....:....4....:....5....:....6",
    {   "************************************************************",  //1
        "******   ******************************************  *******",  //2
        "*****    *****************************************    ******",  //3
        "*****   ******                         ************    *****",  //4
        "****  *******                               *******     ****",  //5
        "******                                     *********    ****",
        "***                                 ***************     ****",
        "***                                    **********       ****",
        "**************                                   **    *****",
        "******  ***************    ************* ***********  ******",  //10
        "*****     ***********   ***************    *****************",
        "****       ************   **********     *******************",
        "***          ************ **************   *****************",
        "*****       ************* **************** *****************",
        "*******    **************        ********   ****************",  //15
        "********   ***********                *****    *************",
        "*********  ****                **************   ************",
        "*******      ********                    *****  ************",
        "********    ****************        ************************",
        "************************************************************"   //20
    };
    //  "....:....1....:....2....:....3....:....4....:....5....:....6",
        static char[,]  t = new char[20,60];
        //★Main() 関数
        public static void Main()
        {
            int x,y;
    
            //string[] st を char[,] t に格納
            for (y = 0; y < 20; y++)
                for (x = 0; x < 60; x++)    t[y, x] = st[y][x];
            //最初の状態を表示
            for (y = 0; y < 20; y++)
            {   for (x = 0; x < 60; x++)    Console.Write("{0}",t[y,x]);
                Console.WriteLine("");
            }
            Console.WriteLine("");
            paint(20,5);
            //塗りつぶした結果を表示
            for (y = 0; y < 20; y++)
            {   for (x = 0; x < 60; x++)    Console.Write("{0}",t[y,x]);
                Console.WriteLine("");
            }
            Console.ReadLine();
        }
        //★内部を塗りつぶす
        static void  paint(int x,int y)
        {
            if (t[y,x]=='*')   return;
            t[y,x]= '*';
            paint(x+1,y);
            paint(x-1,y);
            paint(x,y+1);
            paint(x,y-1);
        }
    }
    
  2. 図形ツールの塗りつぶしのように「*で囲まれた中の空白を、全て*に置き換える」プログラムを作成します。
    ペイントツールを使っていて、生徒からの「塗りつぶしのプログラムはどうなっているの」と言う質問がきっかけで作成しました。
    元のデータは二次元の文字列で定義していますが、単純な矩形ならともかくページ先頭のように細かく入り組んだ 図形ではループしようにも方法がありません。
    このような時に威力を発揮するのが「再起関数」で、完成したプログラムは驚くほどスマートに仕上がります。 (^_^;
  3. 塗りつぶす元のデータの定義です。
    記述が容易なように string を使っています。
    static string[] st =
    //  "....:....1....:....2....:....3....:....4....:....5....:....6",
    {   "************************************************************",  //1
        "******   ******************************************  *******",  //2
                    :
                    :
        "************************************************************"   //20
    };
    //  "....:....1....:....2....:....3....:....4....:....5....:....6",
    
  4. 二次元文字列を参照するだけならインデクサが使えるのですが、今回のように置き換えることは出来ません。
    そこで string から二次元 char に格納して、操作することにしました。
    static char[,] t = new char[20,60];
  5. main() 関数では、string[] st を char[,] t に格納して最初の状態を表示します。
    次に、座標(20,5)を起点にして paint(20,5); 関数を呼び出します。
    最後に塗りつぶされた結果を表示します。
  6. ソースコードです。
    内部を塗りつぶす paint() 関数ですが、驚くほど簡単でしょう。
    paint() 関数の中から paint() 関数を呼び出していることに注目して下さい。
        //★内部を塗りつぶす
        static void  paint(int x,int y)
        {
            if (t[y,x]=='*')   return;
            t[y,x]= '*';
            paint(x+1,y);
            paint(x-1,y);
            paint(x,y+1);
            paint(x,y-1);
        }
        

超初心者のプログラム入門(C# Frame Work)