Beispiel #1
0
        /*********************************
        *
        * bitmapからぱずぷれ形式のtxtを生成
        *
        * 引数
        *	mozaic	:	変換対象のbitmap
        *	size	:	マスのサイズ
        *
        * *******************************/
        public static void makeBoardFromDot(Bitmap mozaic, int size = 6)
        {
            // ビットマップ画像から全てのピクセルを抜き出す
            PixelManipulator s = PixelManipulator.LoadBitmap(mozaic);

            // 範囲チェック
            if (size < 1)
            {
                size = 1;
            }
            if (size > 32)
            {
                size = 32;
            }
            int w = size * 2 + 1;

            Tapa.MAX_BOARD_ROW = s.height / w;                          // 問題の行数
            Tapa.MAX_BOARD_COL = s.width / w;                           // 問題の列数
            Tapa.BOX_SUM       = Tapa.MAX_BOARD_ROW * Tapa.MAX_BOARD_COL;

            Tapa.resetBoard();

            // 全てのピクセルを巡回する
            Box.during_make_inputbord = true;
            s.EachPixel((x, y) => {
                // 確認の終わったモザイクマスは飛ばす
                if (x % w != 0 || y % w != 0)
                {
                    return;
                }
                // 2値画像なので、rのみのチェックでok
                Tapa.box[y / w][x / w].Color = (s.R(x, y) == 0) ? Box.BLACK : Box.NOCOLOR;
            });
            Box.during_make_inputbord = false;
        }
Beispiel #2
0
        /*********************************
        *
        * 盤面の間違っている箇所を未定マスにする.
        *
        * 引数
        * partway	:	途中盤面を保存したもの
        * result	:	解答
        *
        * *******************************/
        private static void modifyMistakeBoard(StateSave partway, StateSave result)
        {
            // 数字マスの座標と数値のハッシュを作成
            Dictionary <Coordinates, int> num_dict = new Dictionary <Coordinates, int>();

            foreach (Coordinates num in Tapa.numbox_coord_list)
            {
                num_dict[num] = Tapa.box[num.x][num.y].boxNum;
            }
            // 盤面の初期化
            Tapa.resetBoard();
            // 数字マスの設置
            Problem.setNumBoxInBoard(num_dict);

            // 回答途中の盤面のうち,正しいマスのみを残す
            for (int i = 1; i <= Tapa.MAX_BOARD_ROW; i++)
            {
                for (int j = 1; j <= Tapa.MAX_BOARD_COL; j++)
                {
                    Box r = result.saved_box[i][j];
                    Box p = partway.saved_box[i][j];
                    if (p.Color == Box.NOCOLOR || p.Color != r.Color)
                    {
                        continue;
                    }
                    else
                    {
                        Tapa.box[i][j].Color = p.Color;
                    }
                }
            }
        }
Beispiel #3
0
        /*********************************
        *
        * 問題のランダム生成
        *
        * *******************************/
        public static void manageMakingProblem()
        {
            Problem p;

            do
            {
                Tapa.resetBoard();
                p = new Problem();

                p.setRandomWhiteBox();
                if (Tapa.DEBUG)
                {
                    Console.WriteLine("白マス配置完了");
                    Tapa.printBoard();
                }

                p.makeBlackBoxRoute();
                if (Tapa.DEBUG)
                {
                    Console.WriteLine("黒マス配置完了");
                    Tapa.printBoard();
                }
            } while (!Tapa.isCorrectAnswer());

            p.setBoxNumber();
            if (Tapa.DEBUG)
            {
                Console.WriteLine("数字マス配置完了");
                Tapa.printBoard();
            }

            p.generateTapaPrblem(1);
            Tapa.processnum_numbox = Tapa.numbox_coord_list.Count;
            generateTapaProblemText(Problem.savefile_path);
        }
Beispiel #4
0
        /*********************************
        *
        * txtからヒントを生成
        *
        * *******************************/
        public static bool manageMakingHintFromTxt()
        {
            Problem p = new Problem();

            p.readPartwayTapaTxt(Problem.prb_hintfile_path);
            StateSave partway = new StateSave();
            StateSave result  = new StateSave();

            // 入力盤面の保存
            StateSave.saveNowState(partway);

            // 初期盤面を解けないとき,途中まででも出力.
            if (!Problem.judgeCanSolveInitialBoard(partway, result))
            {
                StateSave.loadSavedState(result);
                generateTapaHintText(Problem.ans_hintfile_path);
                return(false);
            }

            // 途中盤面が正しい場合,ヒントを与える.
            if (Problem.isCorrectMiddleBoard(partway))
            {
                Tapa.solveTapa(Tapa.not_deployedbox_coord_list.Count - calcHintNum());
            }                   // そうでない場合,間違った箇所を未定マスにする.
            else
            {
                Problem.modifyMistakeBoard(partway, result);
            }
            // ans_hintfile_path = @"C:\Users\Amano\OneDrive\zemi\ans_tapa.txt";
            // ヒントtxtはexeファイルと同じディレクトリ
            generateTapaHintText(Problem.ans_hintfile_path);
            return(true);
        }
Beispiel #5
0
        /*********************************
        *
        * 盤面の初期状態から始めて問題を解けるか判断する.
        *
        * True:解ける
        *
        * 引数
        * partway	:	途中盤面を保存したもの
        * result	:	解答保存用
        *
        * *******************************/
        private static bool judgeCanSolveInitialBoard(StateSave partway, StateSave result)
        {
            // 数字マスの座標と数値のハッシュを作成
            Dictionary <Coordinates, int> num_dict = new Dictionary <Coordinates, int>();

            foreach (Coordinates num in Tapa.numbox_coord_list)
            {
                num_dict[num] = Tapa.box[num.x][num.y].boxNum;
            }

            // 盤面の初期化
            Tapa.resetBoard();
            // 数字マスの設置
            Problem.setNumBoxInBoard(num_dict);

            // 回答する
            Tapa.solveTapa();
            StateSave.saveNowState(result);

            if (Tapa.isCorrectAnswer())
            {
                StateSave.loadSavedState(partway);
                return(true);
            }
            StateSave.loadSavedState(partway);
            return(false);
        }
Beispiel #6
0
        /*********************************
        *
        * ぱずぷれで作成したtxtファイルの読み込み(回答途中)
        * #	:	黒
        * +	:	白
        * ・	:	未定
        * 1,2	:	[12]
        *
        * *******************************/
        public void readPartwayTapaTxt(string readfile_path)
        {
            List <string> line_list = new List <string>();

            using (StreamReader sr = new StreamReader(
                       readfile_path, Encoding.GetEncoding("Shift_JIS"))) {
                string line = "";

                while ((line = sr.ReadLine()) != null)
                {
                    line_list.Add(line);
                }
            }
            if (line_list[0] != "pzprv3" || line_list[1] != "tapa")
            {
                Problem.is_correct_txtformat = false;
                return;
            }

            Tapa.MAX_BOARD_ROW = Convert.ToInt32(line_list[2]);                 // 3行目に行数
            Tapa.MAX_BOARD_COL = Convert.ToInt32(line_list[3]);                 // 4行目に列数
            Tapa.BOX_SUM       = Tapa.MAX_BOARD_ROW * Tapa.MAX_BOARD_COL;

            // 盤面生成
            Tapa.resetBoard();

            for (int i = 1; i <= Tapa.MAX_BOARD_ROW; i++)
            {
                string wk_str = line_list[i + 3].Replace(",", "");                      // 数字マスの区切りを削除
                for (int j = 1; j <= Tapa.MAX_BOARD_COL; j++)
                {
                    int pt = wk_str.IndexOf(' ');

                    if (wk_str.Substring(0, pt) == "#")
                    {
                        Tapa.box[i][j].connecting_color = Box.BLACK;
                    }
                    else if (wk_str.Substring(0, pt) == "+")
                    {
                        Tapa.box[i][j].connecting_color = Box.WHITE;
                    }
                    else if (char.IsDigit(wk_str, 0))
                    {
                        Box tmp_box = Tapa.box[i][j];
                        tmp_box.hasNum = true;
                        tmp_box.boxNum = int.Parse(wk_str.Substring(0, pt));
                        Tapa.not_deployedbox_coord_list.Remove(tmp_box.coord);
                        Tapa.numbox_coord_list.Add(tmp_box.coord);
                    }
                    else
                    {
                    }

                    wk_str = wk_str.Substring(pt + 1);
                }
            }
            // 数字に対応したidを格納
            PatternAroundNumBox.preparePatternArroundNumBox();
        }
Beispiel #7
0
 /*********************************
 *
 * 盤面の埋め方が正しいか判断する
 *
 * true	:	正しい
 *
 * 引数
 * partway	:	途中盤面
 *
 * *******************************/
 private static bool isCorrectMiddleBoard(StateSave partway)
 {
     Tapa.solveTapa();
     if (Tapa.isCorrectAnswer())
     {
         StateSave.loadSavedState(partway);
         return(true);
     }
     StateSave.loadSavedState(partway);
     return(false);
 }
Beispiel #8
0
        /*********************************
        *
        * 問題を生成するプログラムを呼び出す。
        * 引数
        * pattern	:	呼び出すプログラムのid
        * 0 >> 数字を追加して問題生成する
        * 1 >> 数字を削除して問題生成する
        * 2 >> 数字を追加したあと冗長な数字を削除して問題生成する
        *
        * *******************************/
        private void generateTapaPrblem(int pattern)
        {
            // 数字マスの座標とその数字を関連付けたハッシュ
            Dictionary <Coordinates, int> boxnumber_in_whitebox_coord_dict = new Dictionary <Coordinates, int>();

            foreach (Coordinates tmp_co in Problem.can_be_number_whitebox_list)
            {
                boxnumber_in_whitebox_coord_dict[tmp_co] = Tapa.box[tmp_co.x][tmp_co.y].boxNum;
            }
            // (黒マスListなども含む)盤面の初期化
            Tapa.resetBoard();

            switch (pattern)
            {
            case 0:
                generateTapaProblemInAddNumBox(boxnumber_in_whitebox_coord_dict);
                break;

            case 1:
                // 数字マスを全て配置する
                Box.during_make_inputbord = true;
                foreach (KeyValuePair <Coordinates, int> pair in boxnumber_in_whitebox_coord_dict)
                {
                    Box tmp_box = Tapa.box[pair.Key.x][pair.Key.y];

                    tmp_box.hasNum = true;                                       // 数字を持ってるフラグをオンにする
                    tmp_box.boxNum = boxnumber_in_whitebox_coord_dict[pair.Key]; // 選択した座標に数字を格納
                    Tapa.numbox_coord_list.Add(new Coordinates(pair.Key));       // 数字マスリストに追加
                    Tapa.not_deployedbox_coord_list.Remove(pair.Key);            // 未定マスリストから除外
                    PatternAroundNumBox.preparePatternArroundNumBox();           // 数字に対応したidを格納
                }
                Box.during_make_inputbord = false;

                generateTapaProblemInDeleteNumBox();
                break;

            case 2:
                // 時間計測開始
                System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();
                generateTapaProblemInAddNumBox(boxnumber_in_whitebox_coord_dict);
                //時間計測終了
                sw.Stop();
                Console.WriteLine("generateTapaProblemInAddNumBoxの総時間 >> " + sw.Elapsed + "(" + Problem.can_be_number_whitebox_list.Count + ")");


                // 時間計測開始
                System.Diagnostics.Stopwatch sw2 = System.Diagnostics.Stopwatch.StartNew();
                generateTapaProblemInDeleteNumBox();
                //時間計測終了
                sw2.Stop();
                Console.WriteLine("generateTapaProblemInDeleteNumBoxの総時間 >> " + sw2.Elapsed + "(" + Problem.can_be_number_whitebox_list.Count + ")");
                break;
            }
        }
Beispiel #9
0
 /*********************************
 *
 * 盤面sのうち、bの座標を未定マスにした盤面を作成する。
 *
 * *******************************/
 public static void makeEditBoard(StateSave s)
 {
     Tapa.resetBoard();
     for (int i = 1; i <= Tapa.MAX_BOARD_ROW; i++)
     {
         for (int j = 1; j <= Tapa.MAX_BOARD_COL; j++)
         {
             Tapa.box[i][j].connecting_color = s.saved_box[i][j].Color;
         }
     }
 }
Beispiel #10
0
        /*********************************
        *
        * ぱずぷれで作成したtxtファイルの読み込み(Dot画用)
        * #	:	黒
        * +	:	白
        * ・	:	未定
        * 1,2	:	[12]
        *
        * True	: Tapaの解として正しい
        * false: Tapaの解として正しくない
        *
        * *******************************/
        public bool readDotTapaTxt(string readfile_path)
        {
            List <string> line_list = new List <string>();

            using (StreamReader sr = new StreamReader(
                       readfile_path, Encoding.GetEncoding("Shift_JIS"))) {
                string line = "";

                while ((line = sr.ReadLine()) != null)
                {
                    line_list.Add(line);
                }
            }
            if (line_list[0] != "pzprv3" || line_list[1] != "tapa")
            {
                Problem.is_correct_txtformat = false;
                return(false);
            }

            Tapa.MAX_BOARD_ROW = Convert.ToInt32(line_list[2]);                 // 3行目に行数
            Tapa.MAX_BOARD_COL = Convert.ToInt32(line_list[3]);                 // 4行目に列数
            Tapa.BOX_SUM       = Tapa.MAX_BOARD_ROW * Tapa.MAX_BOARD_COL;

            // 盤面生成
            Tapa.resetBoard();

            for (int i = 1; i <= Tapa.MAX_BOARD_ROW; i++)
            {
                string wk_str = line_list[i + 3];
                for (int j = 1; j <= Tapa.MAX_BOARD_COL; j++)
                {
                    int pt = wk_str.IndexOf(' ');

                    if (wk_str.Substring(0, pt) == "#")
                    {
                        Tapa.box[i][j].connecting_color = Box.BLACK;
                    }
                    else
                    {
                        Tapa.box[i][j].connecting_color = Box.WHITE;
                    }

                    wk_str = wk_str.Substring(pt + 1);
                }
            }
            // 入力された盤面が正しいか
            if (Tapa.isCorrectAnswer())
            {
                return(true);
            }
            Problem.is_correct_tapa_dot = false;
            return(false);
        }
Beispiel #11
0
        /*********************************
        *
        * 一繋がりの未定マス群毎にバックトラックを行う
        *
        * *******************************/
        public void manageBackTrack()
        {
            //StateSave state_base = new StateSave();
            //StateSave.saveNowState(state_base);
            // 一繋がりの未定マス群のリストを作成
            // Box.divideNotDeployedBoxToGroup();
            do
            {
                if (doBackTrack(0))
                {
                    StateSave.loadSavedState(BackTrack.correct_save_point);

                    Console.WriteLine("バックトラック成功 深さ:{0}", min_Depth);
                    Tapa.printBoard();
                    Console.WriteLine();
                }
            } while (Tapa.not_deployedbox_coord_list.Count > 0);
        }
Beispiel #12
0
        /*********************************
        *
        * txtから問題生成
        *
        * *******************************/
        public static void manageMakingProblemFromTxt()
        {
            Problem p = new Problem();

            if (!p.readDotTapaTxt(Problem.dotfile_path))
            {
                return;
            }

            p.setBoxNumber();
            if (Tapa.DEBUG)
            {
                Console.WriteLine("数字マス配置完了");
                Tapa.printBoard();
            }

            // 0:add 1:del 2:add+del
            p.generateTapaPrblem(1);
            Tapa.processnum_numbox = Tapa.numbox_coord_list.Count;
            generateTapaProblemText(Problem.savefile_path);
        }
Beispiel #13
0
        /*********************************
        *
        * 未定マスを試し塗りしてバックトラックを行う
        * バックトラックの結果が一度でも正しければtrueを返す
        * 引数
        * depth	: バックトラックの深さ
        *
        * *******************************/
        private bool doBackTrack(int depth)
        {
            StateSave save_point = new StateSave();

            StateSave.saveNowState(save_point);
            bool ret_bool = false;              // true:(途中)盤面が正しい

            // 深さをインクリメント
            depth++;
            // 黒マスと接している未定マスのリストを作成
            List <Coordinates> adjacent_notdeployedbox_coord_list = new List <Coordinates>();

            // 黒マスと接している未定マスがある時
            foreach (Coordinates tmp_ndbox_coord in Tapa.not_deployedbox_coord_list)
            {
                if (Box.existBlackBoxAround(tmp_ndbox_coord))
                {
                    adjacent_notdeployedbox_coord_list.Add(tmp_ndbox_coord);
                }
            }
            // 未定マスはあるが、黒マスと接している未定マスがない時
            if (adjacent_notdeployedbox_coord_list.Count == 0 &&
                Tapa.not_deployedbox_coord_list.Count > 0)
            {
                foreach (Coordinates tmp_ndbox_coord in Tapa.not_deployedbox_coord_list)
                {
                    adjacent_notdeployedbox_coord_list.Add(new Coordinates(tmp_ndbox_coord));
                }
            }

            // 注目している未定マス領域に未定マスがただ1つ存在する時の処理
            if (adjacent_notdeployedbox_coord_list.Count == 1)
            {
                for (int i = 0; i < 2; i++)
                {
                    Coordinates tmp_ndbox_coord = adjacent_notdeployedbox_coord_list[0];
                    Tapa.box[tmp_ndbox_coord.x][tmp_ndbox_coord.y].Color = (i == 0) ? Box.BLACK : Box.WHITE;

                    // 変化がなくなるまで処理を行う
                    do
                    {
                        Tapa.was_change_board = false;
                        PatternAroundNumBox.managePatternAroundNumBox();
                        Box.manageBlackBox();
                    } while (Tapa.was_change_board);


                    // 処理中の未定マス群から色のついたマスを除外したリストを作成
                    List <Coordinates> arg_list = new List <Coordinates>(Tapa.not_deployedbox_coord_list);
                    for (int j = arg_list.Count - 1; j >= 0; j--)
                    {
                        if (Tapa.box[arg_list[j].x][arg_list[j].y].Color != Box.NOCOLOR)
                        {
                            arg_list.RemoveAt(j);
                        }
                    }

                    // 未定マスが存在すれば再起する
                    if (arg_list.Count > 0)
                    {
                        ret_bool = ret_bool || doBackTrack(depth);
                    }
                    else                                                                    // 未定マスが存在しない
                    {
                        if (Box.checkNotIsolationBlackBoxGroup() || Tapa.isCorrectAnswer()) // 盤面の一繋がりの黒マス群が孤立していないか
                        {
                            StateSave.saveNowState(BackTrack.correct_save_point);           // 正しければ現在の盤面を保存
                            if (depth < min_depth)                                          // 先読みした深さ(のうち小さい方)を記録
                            {
                                min_depth = depth;
                                tmp_ndbox_coord.printCoordinates();
                                Console.WriteLine(":min_depth >> " + min_depth);
                            }
                            ret_bool = true;
                        }
                    }
                    // 元の状態に戻す
                    StateSave.loadSavedState(save_point);

                    // 黒マスで塗ったら正解の盤面が生成できなかった場合
                    if (!ret_bool)
                    {
                        // 未定マスの色を白にする
                        Tapa.box[tmp_ndbox_coord.x][tmp_ndbox_coord.y].Color = Box.WHITE;
                        StateSave.saveNowState(save_point);
                    }
                }
                return(ret_bool);
            }

            // 注目している未定マス領域に未定マスが複数存在する時の処理
            // 未定マスをたどる
            for (int i = 0; i < adjacent_notdeployedbox_coord_list.Count; i++)
            {
                Coordinates tmp_ndbox_coord = adjacent_notdeployedbox_coord_list[i];

                // 未定マスの色を黒にする
                Tapa.box[tmp_ndbox_coord.x][tmp_ndbox_coord.y].Color = Box.BLACK;

                // 変化がなくなるまで処理を行う
                do
                {
                    Tapa.was_change_board = false;
                    PatternAroundNumBox.managePatternAroundNumBox();
                    Box.manageBlackBox();
                } while (Tapa.was_change_board);

                // 処理中の未定マス群から色のついたマスを除外したリストを作成
                List <Coordinates> arg_list = new List <Coordinates>(Tapa.not_deployedbox_coord_list);
                for (int j = arg_list.Count - 1; j >= 0; j--)
                {
                    if (Tapa.box[arg_list[j].x][arg_list[j].y].Color != Box.NOCOLOR)
                    {
                        arg_list.RemoveAt(j);
                    }
                }

                // 処理中の未定マス群に未定マスが残っていれば再起する
                if (arg_list.Count > 0)
                {
                    ret_bool = ret_bool || doBackTrack(depth);
                }
                else                    // 処理中の未定マス群に未定マスが存在しない
                                        // 盤面に一繋がりの黒マス群が孤立していない or 盤面が正解
                {
                    if (Box.checkNotIsolationBlackBoxGroup() || Tapa.isCorrectAnswer())
                    {
                        StateSave.saveNowState(BackTrack.correct_save_point);           // 正しければ現在の盤面を保存
                        if (depth < min_depth)                                          // 先読みした深さ(のうち小さい方)を記録
                        {
                            min_depth = depth;
                            tmp_ndbox_coord.printCoordinates();
                            Console.WriteLine(":min_depth >> " + min_depth);
                        }
                        ret_bool = true;
                    }
                }
                // 元の状態に戻す
                StateSave.loadSavedState(save_point);

                // 黒マスで塗ったら正解の盤面が生成できなかった場合
                if (!ret_bool)
                {
                    // 未定マスの色を白にする
                    Tapa.box[tmp_ndbox_coord.x][tmp_ndbox_coord.y].Color = Box.WHITE;
                    StateSave.saveNowState(save_point);
                }
            }
            return(ret_bool);
        }
Beispiel #14
0
        /*********************************
        *
        * 数字マスを削除して問題生成する。
        * 引数:
        * boxnumber_in_whitebox_coord_dict	: 数字マスの座標と数字の対応
        *
        * *******************************/
        private void generateTapaProblemInDeleteNumBox()
        {
            if (Tapa.DEBUG)
            {
                Console.WriteLine("ソート前");
                Tapa.printCoordList(Problem.can_be_number_whitebox_list);
            }
            // 【削除する数字マスを選ぶ順番】
            // ヒント数で降順にソート[固定] のみ
            //////// ヒント数が同数だったらidの数で昇順にソートしたデータを後ろから選ぶ
            Tapa.numbox_coord_list.Sort(
                delegate(Coordinates co1, Coordinates co2) {
                int hint1 = Tapa.box[co1.x][co1.y].min_hint;
                int hint2 = Tapa.box[co2.x][co2.y].min_hint;
                if (hint1 < hint2)
                {
                    return(1);
                }
                else if (hint1 > hint2)
                {
                    return(-1);
                }
                else
                {
                    return(0);
                    //int num1 = Tapa.box[co1.x][co1.y].id_list.Count;
                    //int num2 = Tapa.box[co2.x][co2.y].id_list.Count;
                    //if (num1 < num2) { return -1; }
                    //else if (num1 > num2) { return 1; }
                    //else return 0;
                }
            });

            // 未削除の数字マスリストを現在残っている数字マスリストで更新
            Problem.can_be_number_whitebox_list = new List <Coordinates>(Tapa.numbox_coord_list);
            if (Tapa.DEBUG)
            {
                Console.WriteLine("ソート後");
                Tapa.printCoordList(Problem.can_be_number_whitebox_list);
            }

            // 削除対象のリストを後ろからチェック
            for (int i = Problem.can_be_number_whitebox_list.Count - 1; i >= 0; i--)
            {
                // 時間計測開始
                System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();

                // 現在の状態を保存
                StateSave save_point = new StateSave();
                StateSave.saveNowState(save_point);

                // 削除判定の行われていない数字マスの内、
                // [最少ヒント数で降順][パターン数で昇順]でソートしたリストの後ろから順に数字マスを選ぶ
                Coordinates deleting_numbox_coord = Problem.can_be_number_whitebox_list[i];

                // 選択された数字マスを、未削除の数字マス座標リストから除外する。
                Problem.can_be_number_whitebox_list.Remove(deleting_numbox_coord);
                Box deleting_box = Tapa.box[deleting_numbox_coord.x][deleting_numbox_coord.y];                  // 浅いコピー

                // 選択した数字マスを未定マスにする
                deleting_box.revision_color = Box.NOCOLOR;                                   // 選択した座標を未定マスにする
                deleting_box.hasNum         = false;                                         // 数字を持ってるフラグをオフにする
                Tapa.numbox_coord_list.Remove(deleting_numbox_coord);                        // 数字マスリストから除外
                Tapa.not_deployedbox_coord_list.Add(new Coordinates(deleting_numbox_coord)); // 未定マスリストに追加

                // 問題を解く
                Tapa.solveTapa();

                // 解ならば復元後に、選択した数字マスをそのまま未定マスにする。
                if (Tapa.isCorrectAnswer())
                {
                    StateSave.loadSavedState(save_point);
                    // 選択した数字マスを未定マスにする
                    Tapa.box[deleting_numbox_coord.x][deleting_numbox_coord.y].revision_color = Box.NOCOLOR;            // 選択した座標を未定マスにする
                    Tapa.box[deleting_numbox_coord.x][deleting_numbox_coord.y].hasNum         = false;                  // 数字を持ってるフラグをオフにする
                    Tapa.numbox_coord_list.Remove(deleting_numbox_coord);                                               // 数字マスリストから除外
                    Tapa.not_deployedbox_coord_list.Add(new Coordinates(deleting_numbox_coord));                        // 未定マスリストに追加
                }
                else
                {
                    // 解でないなら、盤面を復元するのみ。
                    StateSave.loadSavedState(save_point);
                }

                //時間計測終了
                sw.Stop();
                deleting_numbox_coord.printCoordinates();
                Console.WriteLine("del >> " + sw.Elapsed + "(" + Problem.can_be_number_whitebox_list.Count + ")");
            }
        }
Beispiel #15
0
        /*********************************
        *
        * 数字マスを追加して問題生成する。
        * 引数:
        * boxnumber_in_whitebox_coord_dict	: 数字マスの座標と数字の対応
        *
        * *******************************/
        private void generateTapaProblemInAddNumBox(Dictionary <Coordinates, int> boxnumber_in_whitebox_coord_dict)
        {
            do
            {
                // 時間計測開始
                System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();


                // 埋める数字マスをランダムに選択
                Coordinates adopting_boxnumber_coord = Problem.can_be_number_whitebox_list[
                    Problem.getRandomInt(0, Problem.can_be_number_whitebox_list.Count)];


                Box tmp_box = Tapa.box[adopting_boxnumber_coord.x][adopting_boxnumber_coord.y];

                // 選択した座標が既に配色済みの場合
                if (tmp_box.Color != Box.NOCOLOR)
                {
                    Problem.can_be_number_whitebox_list.Remove(adopting_boxnumber_coord);                       // 数字マスを格納できる座標リストから除外
                    // boxnumber_in_whitebox_coord_dict.Remove(adopting_boxnumber_coord);		// ハッシュから除外
                    continue;
                }

                Box.during_make_inputbord = true;

                tmp_box.hasNum = true;                                                       // 数字を持ってるフラグをオンにする
                tmp_box.boxNum = boxnumber_in_whitebox_coord_dict[adopting_boxnumber_coord]; // 選択した座標に数字を格納
                Tapa.numbox_coord_list.Add(new Coordinates(adopting_boxnumber_coord));       // 数字マスリストに追加
                Tapa.not_deployedbox_coord_list.Remove(adopting_boxnumber_coord);            // 未定マスリストから除外
                tmp_box.id_list
                    = PatternAroundNumBox.getPatternAroundNumBoxList(tmp_box.boxNum);        // 数字に対応したidを格納

                Problem.can_be_number_whitebox_list.Remove(adopting_boxnumber_coord);        // 数字マスを格納できる座標リストから除外
                boxnumber_in_whitebox_coord_dict.Remove(adopting_boxnumber_coord);           // ハッシュから除外

                Box.during_make_inputbord = false;

                Tapa.solveTapa();

                //時間計測終了
                sw.Stop();
                adopting_boxnumber_coord.printCoordinates();
                Console.WriteLine("の追加にかかった時間 >> " + sw.Elapsed + "(" + Problem.can_be_number_whitebox_list.Count + ")");
            } while (Problem.can_be_number_whitebox_list.Count > 0);

            Console.WriteLine("数字マスランダム配置後");
            Tapa.printBoard();


            while (Tapa.not_deployedbox_coord_list.Count > 0)
            {
                Console.WriteLine("未定マスが存在!!!!");

                // 白マス周りにある未定マスの数を格納
                Dictionary <Coordinates, int> count_whitebox_dict = new Dictionary <Coordinates, int>();

                foreach (Coordinates tmp_co in Tapa.not_deployedbox_coord_list)
                {
                    List <Coordinates> whitebox_around_notdeployedbox_list = Box.getWhiteBoxCoordAround8(tmp_co);
                    foreach (Coordinates tmp_whitebox_co in whitebox_around_notdeployedbox_list)
                    {
                        if (!count_whitebox_dict.ContainsKey(tmp_whitebox_co))
                        {
                            count_whitebox_dict[tmp_whitebox_co] = 1;
                        }
                        else
                        {
                            count_whitebox_dict[tmp_whitebox_co]++;
                        }
                    }
                }

                int         max          = 0;
                Coordinates white2numbox = new Coordinates();                   // 未定マスが最も多く周囲にある白マス
                foreach (KeyValuePair <Coordinates, int> pair in count_whitebox_dict)
                {
                    if (pair.Value > max)
                    {
                        white2numbox = new Coordinates(pair.Key);
                    }
                }

                Box.during_make_inputbord = true;

                Box tmp_box = Tapa.box[white2numbox.x][white2numbox.y];
                tmp_box.hasNum = true;
                tmp_box.boxNum = boxnumber_in_whitebox_coord_dict[white2numbox];                        // 数字を格納
                Tapa.numbox_coord_list.Add(new Coordinates(white2numbox));                              // 数字マスリストに追加
                tmp_box.id_list
                    = PatternAroundNumBox.getPatternAroundNumBoxList(tmp_box.boxNum);                   // 数字に対応したidを格納

                Box.during_make_inputbord = false;

                Tapa.solveTapa();

                if (Tapa.DEBUG)
                {
                    Console.WriteLine("未定マス修正");
                    Tapa.printBoard();
                }
            }
            // 数字ごとのidを元に戻す(回答中にid_listは減少)
            PatternAroundNumBox.preparePatternArroundNumBox();

            // 盤面にある数字マス以外のマスを未定マスにする
            Tapa.numbox_coord_list.Clear();                                             // 数字マスの座標リスト
            Tapa.not_deployedbox_coord_list.Clear();                                    // 未定マスの座標リスト
            Tapa.isolation_notdeployedboxes_group_list.Clear();                         // 一繋がりの未定マス群の座標リスト
            Tapa.edge_blackbox_coord_list.Clear();                                      // 伸び代のある黒マスの座標リスト
            Tapa.isolation_blackboxes_group_list.Clear();                               // 一繋がりの黒マス群の座標リスト
            for (int i = 1; i <= Tapa.MAX_BOARD_ROW; i++)
            {
                for (int j = 1; j <= Tapa.MAX_BOARD_COL; j++)
                {
                    Box tmp = Tapa.box[i][j];
                    if (!tmp.hasNum)
                    {
                        tmp.revision_color = Box.NOCOLOR;
                        Tapa.not_deployedbox_coord_list.Add(new Coordinates(tmp.coord));
                    }
                    else
                    {
                        Tapa.numbox_coord_list.Add(new Coordinates(tmp.coord));
                    }
                }
            }
        }
Beispiel #16
0
        public static void makeSampleData()
        {
            //for (Tapa.MAX_BOARD_ROW = MIN_GEN_ROW; Tapa.MAX_BOARD_ROW <= MAX_GEN_ROW; Tapa.MAX_BOARD_ROW++) {
            //	for (Tapa.MAX_BOARD_COL = MIN_GEN_COL; Tapa.MAX_BOARD_COL <= MAX_GEN_COL; Tapa.MAX_BOARD_COL++) {

            Tapa.MAX_BOARD_ROW = Tapa.MAX_BOARD_COL = 8;
            for (int rate = 25; rate <= 90; rate += 5)
            {
                Problem.MAX_WHITEBOX_START_RATE = rate;
                Problem.MIN_WHITEBOX_START_RATE = rate;


                Tapa.BOX_SUM = Tapa.MAX_BOARD_COL * Tapa.MAX_BOARD_ROW;
                dir_name     = "tapa_fast_normal_" + Tapa.MAX_BOARD_ROW + "" + Tapa.MAX_BOARD_COL + "_r" + rate;
                FolderManagement.makeFolder(base_directory, dir_name);

                // MAX_TXT個の問題に対する
                PreBook sum = new PreBook("average");                   // 合計
                PreBook min = new PreBook("max");                       // 最大
                PreBook max = new PreBook("min", true);                 // 最少


                for (int txt_id = 0; txt_id < MAX_TXT; txt_id++)
                {
                    Tapa.file_name                 = "tapa" + Tapa.MAX_BOARD_ROW + Tapa.MAX_BOARD_COL + String.Format("{0:00000}", txt_id) + ".txt";
                    Tapa.processnum_kuromasu       = 0;
                    Tapa.processnum_kakuteijogaiid = 0;
                    Tapa.processnum_dangoid        = 0;
                    Tapa.processnum_korituid       = 0;
                    Tapa.processnum_betu0id        = 0;
                    Tapa.processnum_kakuteimasu    = 0;
                    Tapa.processnum_numbox         = 0;
                    Tapa.visittimes_kuromasu       = 0;
                    Tapa.visittimes_kakuteijogaiid = 0;
                    Tapa.visittimes_dangoid        = 0;
                    Tapa.visittimes_korituid       = 0;
                    Tapa.visittimes_betu0id        = 0;
                    Tapa.visittimes_kakuteimasu    = 0;
                    Tapa.sum_times_kuromasu        = 0;
                    Tapa.sum_times_kakuteijogaiid  = 0;
                    Tapa.sum_times_dangoid         = 0;
                    Tapa.sum_times_korituid        = 0;
                    Tapa.sum_times_betu0id         = 0;
                    Tapa.sum_times_kakuteimasu     = 0;

                    //// 時間計測開始
                    System.Diagnostics.Stopwatch sw = System.Diagnostics.Stopwatch.StartNew();

                    Problem.manageMakingProblem();

                    ////時間計測終了
                    sw.Stop();
                    Tapa.time_makeproblem = sw.ElapsedMilliseconds;

                    Tapa.is_count = true;
                    Tapa.solveTapa();
                    Tapa.is_count = false;

                    calcSum(sum);
                    calcMax(min);
                    calcMin(max);

                    // http://kageura.hatenadiary.jp/entry/2015/05/18/200000
                    // csvファイルに書き込むlist
                    MyCSVManagement.svc_list.Add(
                        new Book()
                    {
                        tapa_name                 = Tapa.file_name,
                        c_blackbox                = Tapa.isolation_blackboxes_group_list[0].Count.ToString(),
                        c_whitebox                = (Tapa.BOX_SUM - Tapa.isolation_blackboxes_group_list[0].Count).ToString(),
                        c_numbox                  = Tapa.processnum_numbox.ToString(),
                        kuromasu                  = Tapa.processnum_kuromasu.ToString(),
                        kakuteiIdJogai            = Tapa.processnum_kakuteijogaiid.ToString(),
                        dangoIdJogai              = Tapa.processnum_dangoid.ToString(),
                        korituIdJogai             = Tapa.processnum_korituid.ToString(),
                        betuId0Jogai              = Tapa.processnum_betu0id.ToString(),
                        kakuteimasu               = Tapa.processnum_kakuteimasu.ToString(),
                        visittimes_kuromasu       = Tapa.visittimes_kuromasu.ToString(),
                        visittimes_kakuteijogaiid = Tapa.visittimes_kakuteijogaiid.ToString(),
                        visittimes_dangoid        = Tapa.visittimes_dangoid.ToString(),
                        visittimes_korituid       = Tapa.visittimes_korituid.ToString(),
                        visittimes_betu0id        = Tapa.visittimes_betu0id.ToString(),
                        visittimes_kakuteimasu    = Tapa.visittimes_kakuteimasu.ToString(),
                        sum_times_kuromasu        = Tapa.sum_times_kuromasu.ToString(),
                        sum_times_kakuteijogaiid  = Tapa.sum_times_kakuteijogaiid.ToString(),
                        sum_times_dangoid         = Tapa.sum_times_dangoid.ToString(),
                        sum_times_korituid        = Tapa.sum_times_korituid.ToString(),
                        sum_times_betu0id         = Tapa.sum_times_betu0id.ToString(),
                        sum_times_kakuteimasu     = Tapa.sum_times_kakuteimasu.ToString(),
                        avetimes_kuromasu         = (Tapa.visittimes_kuromasu == 0) ? 0 : Tapa.sum_times_kuromasu / (float)Tapa.visittimes_kuromasu,
                        avetimes_kakuteijogaiid   = (Tapa.visittimes_kakuteijogaiid == 0) ? 0 : Tapa.sum_times_kakuteijogaiid / (float)Tapa.visittimes_kakuteijogaiid,
                        avetimes_dangoid          = (Tapa.visittimes_dangoid == 0) ? 0 : Tapa.sum_times_dangoid / (float)Tapa.visittimes_dangoid,
                        avetimes_korituid         = (Tapa.visittimes_korituid == 0) ? 0 : Tapa.sum_times_korituid / (float)Tapa.visittimes_korituid,
                        avetimes_betu0id          = (Tapa.visittimes_betu0id == 0) ? 0 : Tapa.sum_times_betu0id / (float)Tapa.visittimes_betu0id,
                        avetimes_kakuteimasu      = (Tapa.visittimes_kakuteimasu == 0) ? 0 : Tapa.sum_times_kakuteimasu / (float)Tapa.visittimes_kakuteimasu,
                        time_maketapa             = Tapa.time_makeproblem.ToString()
                    });
                }
                addAveBook(sum);
                addBook(max);
                addBook(min);
                writeCSV();
                MyCSVManagement.svc_list.Clear();
            }            ////
            //	}
            //}
        }