Beispiel #1
0
 public Status_Node(string code, Status_Node parent, int g, int h)
 {
     Code     = code;
     m_Parent = parent;
     m_G      = g;
     m_H      = h;
     m_Font   = new Font("Candara", 25F, FontStyle.Regular, GraphicsUnit.Point);
 }
        private Status_Node m_Parent; // node cha

        #endregion Fields

        #region Constructors

        public Status_Node(string code, Status_Node parent, int g, int h)
        {
            Code = code;
            m_Parent = parent;
            m_G = g;
            m_H = h;
            m_Font = new Font("Candara", 25F, FontStyle.Regular, GraphicsUnit.Point);
        }
Beispiel #3
0
 /// <summary>
 /// Kiểm tra sự tồn tại của 1 node trong list Close
 /// nếu có -> return true, ngược lại là false
 /// </summary>
 private bool IsInCloseList(Status_Node n)
 {
     for (int i = 0; i < CloseList.Count; i++)
     {
         if (CloseList[i].Code.Equals(n.Code))
         {
             return(true);
         }
     }
     return(false);
 }
Beispiel #4
0
        /// <summary>
        /// Lấy 1 trạng thái từ List OPen chuyển sang list Close
        /// do list đã sắp xếp theo thứ tự tăng dần của F nên lấy phần tử đầu tiên (OpenList[0])
        /// - trả về node lấy được
        /// </summary>
        private Status_Node GetNodeFromOpenList()
        {
            if (OpenList.Count > 0)
            {
                Status_Node n = OpenList[0];

                OpenList.RemoveAt(0); // xóa node đầu tiên
                CloseList.Add(n);     // chuyển sang CloseList
                return(n);
            }
            return(null);
        }
Beispiel #5
0
        private void btnResolve_Click(object sender, EventArgs e)
        {
            if (this.btnResolve.Text == "Giải" || this.btnResolve.Text == "Tiếp tục")
            {
                if (this.btnResolve.Text == "Giải")
                {
                    if (IsCanSolve(this.CurNode))
                    {
                        progressBar1.Style = ProgressBarStyle.Marquee;
                        progressBar1.MarqueeAnimationSpeed = 20;
                        Status_Node n = Start(this.CurNode.Code, FINISH);

                        if (n != null)// nếu giải được thì chèn vào mảng truy vết
                        {
                            TraceList.Clear();
                            while (n != null)
                            {
                                TraceList.Insert(0, n); // chèn vào TraceList
                                n = n.Parent;           // truy vết
                            }

                            this.StepCount = 0;
                            MessageBox.Show("Số bước đi: " + (TraceList.Count - 1), "Số bước đi", MessageBoxButtons.OK, MessageBoxIcon.Information);

                            this.btnResolve.Enabled = true;
                            this.btnResolve.Text    = "Dừng";
                            this.timerPlay.Enabled  = true;
                        }
                        else
                        {
                            this.btnResolve.Enabled = false;
                            MessageBox.Show("Không tìm được lời giải, số trạng thái quá lớn");
                        }
                    }
                    else
                    {
                        this.btnResolve.Enabled = false;
                        MessageBox.Show("Không tìm được lời giải");
                        return;
                    }
                }
                else
                {
                    this.timerPlay.Enabled = true;
                    this.btnResolve.Text   = "Tiếp tục";
                }
            }
            else
            {
                this.btnResolve.Text   = "Tiếp tục";
                this.timerPlay.Enabled = false;
            }
        }
Beispiel #6
0
        /// <summary>
        /// thêm 1 trạng thái mới vào trong list open (chứa các trạng thái con được sinh ra)
        /// sao cho danh sách được sắp xếp theo thứ tự tăng dần giá trị F
        /// - biến vào là node n
        /// </summary>
        private void AddNodeToOpenList(Status_Node n)
        {
            int i = 1;

            if (OpenList.Count == 0) // nếu list rỗng
            {
                OpenList.Add(n);
                return;
            }

            // nếu list không rỗng, tìm kiếm xem đã có chưa
            bool found  = false;
            bool canadd = false;

            for (i = 0; i < OpenList.Count; i++)
            {
                // tìm thấy
                if (n.Code.Equals(OpenList[i].Code))
                {
                    found = true;
                    if (n.G < OpenList[i].G) // so sánh giá trị G, lấy Node nhỏ hơn
                    {
                        canadd = true;
                        OpenList.RemoveAt(i); // xóa phần tử thử i
                    }
                    return;
                }
            }

            // không tìm thấy hoặc có thể thêm được
            if (!found || canadd)
            {
                // duyệt list và chèn theo thứ tự tăng dần của F
                for (i = 0; i < OpenList.Count; i++)
                {
                    if (n.F < OpenList[i].F)
                    {
                        break;
                    }
                }

                if (i == OpenList.Count)
                {
                    OpenList.Add(n);
                }
                else
                {
                    OpenList.Insert(i, n);
                }
            }
        }
        /// <summary>
        /// thêm 1 trạng thái mới vào trong list open (chứa các trạng thái con được sinh ra)
        /// sao cho danh sách được sắp xếp theo thứ tự tăng dần giá trị F
        /// - biến vào là node n
        /// </summary>
        private void AddNodeToOpenList(Status_Node n)
        {
            int i = 1;

            if (OpenList.Count == 0) // nếu list rỗng
            {
                OpenList.Add(n);
                return;
            }

            // nếu list không rỗng, tìm kiếm xem đã có chưa
            bool found = false;
            bool canadd = false;

            for (i = 0; i < OpenList.Count; i++)
            {
                // tìm thấy
                if (n.Code.Equals(OpenList[i].Code))
                {
                    found = true;
                    if (n.G < OpenList[i].G) // so sánh giá trị G, lấy Node nhỏ hơn
                    {
                        canadd = true;
                        OpenList.RemoveAt(i); // xóa phần tử thử i
                    }
                    return;
                }
            }

            // không tìm thấy hoặc có thể thêm được
            if (!found || canadd)
            {
                // duyệt list và chèn theo thứ tự tăng dần của F
                for (i = 0; i < OpenList.Count; i++)
                {
                    if (n.F < OpenList[i].F)
                    {
                        break;
                    }
                }

                if (i == OpenList.Count)
                    OpenList.Add(n);
                else
                    OpenList.Insert(i, n);
            }
        }
Beispiel #8
0
        private void bntNew_Click(object sender, EventArgs e)
        {
            this.timerPlay.Enabled  = false;
            this.btnResolve.Enabled = true;
            // khởi tạo mặc định
            if (this.first)
            {
                this.CurNode = new Status_Node("876042531", null, 0, CalculateH("876042531"));
                //this.CurNode = new Status_Node("684031275", null, 0, CalculateH("684031275"));
                this.first = false;
            }
            else
            {
                if (this.reset)
                {
                    this.CurNode = this.Game;
                    this.reset   = false;
                }
                else
                {
                    // khởi tạo ngẫu nhiên
                    this.CurNode = new Status_Node(FINISH, null, 0, 0); // CurNode là trạng thái đích
                    Random rd = new Random();

                    for (int i = 0; i < 100; i++)
                    {
                        int j = rd.Next(1000) % 4;
                        MoveStep((Direction)j);// xáo trộn 8 puzzle theo 4 hướng
                    }
                }
            }

            this.Game            = new Status_Node(this.CurNode.Code, null, 0, this.CurNode.H);// lưu lại trạng thái hiện tại cho nút reset
            this.btnResolve.Text = "Giải";
            this.StepCount       = 0;
            this.lblCount.Text   = this.StepCount.ToString();
            this.pbGame.Refresh();
        }
Beispiel #9
0
        private bool reset = false;                // reset lại ma trận Puzzle

        #endregion

        #region Các phương thức

        /// <summary>
        /// tính toán xem trạng thái có thể trở về trạng thái đích được không
        /// </summary>
        private bool IsCanSolve(Status_Node n)
        {
            int length = n.Code.Length;
            int value  = 0;

            int[] k = new int[length];

            for (int i = 0; i < length; i++)
            {
                int.TryParse(n.Code[i].ToString(), out k[i]);
            }

            for (int i = 0; i < length; i++)
            {
                int t = k[i];
                if (t > 0)
                {
                    for (int j = i + 1; j < length; j++)
                    {
                        if (k[j] < t && k[j] > 0)
                        {
                            value++;
                        }
                    }
                }
            }

            if (value % 2 != 0)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #10
0
        // truy vết, hiển thị bước đi
        private void timerPlay_Tick(object sender, EventArgs e)
        {
            progressBar1.Style   = ProgressBarStyle.Continuous;
            progressBar1.Maximum = this.TraceList.Count;
            progressBar1.Minimum = 0;
            progressBar1.Step    = 1;

            if (this.StepCount < this.TraceList.Count)
            {
                this.CurNode = this.TraceList[this.StepCount];
                pbGame.Refresh();

                this.lblCount.Text = "" + this.StepCount++;
                progressBar1.PerformStep();

                if (this.StepCount == this.TraceList.Count)
                {
                    this.timerPlay.Enabled = false;
                    lblFinish.Text         = "ĐÃ GIẢI XONG";
                    MessageBox.Show("Đã giải xong", "Hoàn thành", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    if (MessageBox.Show("Bạn muốn tiếp tục không?", "?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        lblFinish.Text         = "";
                        lblCountStatistic.Text = "";
                        progressBar1.Value     = 0;
                        bntNew_Click(null, null);
                    }
                    else
                    {
                        Application.Exit();
                    }
                    GC.Collect();
                    this.btnResolve.Text = "Giải";
                }
            }
        }
Beispiel #11
0
        // Thuật toán A*
        private Status_Node Start(string start, string end)
        {
            Stopwatch sw = new Stopwatch();

            // khởi tạo danh sách
            OpenList.Clear();
            CloseList.Clear();
            StepCount = 0;

            sw.Start();

            // node đầu tiên là ma trận đề bài
            Status_Node firstNode = new Status_Node(start, null, 0, CalculateH(start));

            AddNodeToOpenList(firstNode);

            Status_Node currentNode = null;

            // tính toán bước đi, với list có số ptu lớn quá 50000 -> không tìm thấy
            while (OpenList.Count > 0 && OpenList.Count < 50000)
            {
                currentNode = GetNodeFromOpenList(); // lấy 1 node đầu tiên trong list, chuyển vào close list

                // kiểm tra xem có phải trạng thái đích không?
                if (currentNode.Code.Equals(FINISH)) // nếu đúng thì trả về trạng thái này
                {
                    sw.Stop();
                    lblFinish.Text         = "Thời gian: " + sw.ElapsedMilliseconds.ToString() + " mili giây";
                    lblCountStatistic.Text = "Số trạng thái tìm được: " + OpenList.Count.ToString();
                    return(currentNode);
                }

                ExpandNode(currentNode);// tìm các trạng thái con nếu không thấy
            }
            return(null);
        }
Beispiel #12
0
        private void bntNew_Click(object sender, EventArgs e)
        {
            this.timerPlay.Enabled = false;
            this.btnResolve.Enabled = true;
            // khởi tạo mặc định
            if (this.first)
            {
                this.CurNode = new Status_Node("876042531", null, 0, CalculateH("876042531"));
                //this.CurNode = new Status_Node("684031275", null, 0, CalculateH("684031275"));
                this.first = false;
            }
            else
            {
                if (this.reset)
                {
                    this.CurNode = this.Game;
                    this.reset = false;
                }
                else
                {
                    // khởi tạo ngẫu nhiên
                    this.CurNode = new Status_Node(FINISH, null, 0, 0); // CurNode là trạng thái đích
                    Random rd = new Random();

                    for (int i = 0; i < 100; i++)
                    {
                        int j = rd.Next(1000) % 4;
                        MoveStep((Direction)j);// xáo trộn 8 puzzle theo 4 hướng
                    }
                }
            }

            this.Game = new Status_Node(this.CurNode.Code, null, 0, this.CurNode.H);// lưu lại trạng thái hiện tại cho nút reset
            this.btnResolve.Text = "Giải";
            this.StepCount = 0;
            this.lblCount.Text = this.StepCount.ToString();
            this.pbGame.Refresh();
        }
Beispiel #13
0
        /// <summary>
        /// Tính toán các trạng thái con của node n
        /// </summary>
        private void ExpandNode(Status_Node n)
        {
            int index = n.Code.IndexOf('0'); // tìm vị trí '0' trong chuỗi

            switch (index)
            {
            case 0:     // nếu ô 0 đang ở vị trí của ô số 1 thì có thể sang phải hoặc xuống dưới
            {
                // trạng thái con 1 - sang phải
                char[] child1 = n.Code.ToCharArray();
                // sang phải. VD: 083124765 chuyển thành 803124765
                child1[0] = child1[1];
                child1[1] = '0';
                string map = new string(child1);

                // nếu node n không có cha hoặc node con sinh ra khác n
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    // sinh node con
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    // nếu node con chưa có trong list close
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);         // chèn vào list open
                    }
                }

                // xuống dưới
                char[] child2 = n.Code.ToCharArray();
                child2[0] = child2[3];
                child2[3] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 1:
            {
                // sang trái
                char[] child1 = n.Code.ToCharArray();
                child1[1] = child1[0];
                child1[0] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang phải
                char[] child2 = n.Code.ToCharArray();
                child2[1] = child2[2];
                child2[2] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // xuống dưới
                char[] child3 = n.Code.ToCharArray();
                child3[1] = child3[4];
                child3[4] = '0';
                map       = new string(child3);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 2:
            {
                // sang trái
                char[] child1 = n.Code.ToCharArray();
                child1[2] = child1[1];
                child1[1] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // xuống dưới
                char[] child2 = n.Code.ToCharArray();
                child2[2] = child2[5];
                child2[5] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 3:
            {
                // lên trên
                char[] child1 = n.Code.ToCharArray();
                child1[3] = child1[0];
                child1[0] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang phải
                char[] child2 = n.Code.ToCharArray();
                child2[3] = child2[4];
                child2[4] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // xuống dưới
                char[] child3 = n.Code.ToCharArray();
                child3[3] = child3[6];
                child3[6] = '0';
                map       = new string(child3);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 4:
            {
                // lên trên
                char[] child1 = n.Code.ToCharArray();
                child1[4] = child1[1];
                child1[1] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang trái
                char[] child2 = n.Code.ToCharArray();
                child2[4] = child2[3];
                child2[3] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang phải
                char[] child3 = n.Code.ToCharArray();
                child3[4] = child3[5];
                child3[5] = '0';
                map       = new string(child3);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // xuống dưới
                char[] child4 = n.Code.ToCharArray();
                child4[4] = child4[7];
                child4[7] = '0';
                map       = new string(child4);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 5:
            {
                // lên trên
                char[] child1 = n.Code.ToCharArray();
                child1[5] = child1[2];
                child1[2] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang trái
                char[] child2 = n.Code.ToCharArray();
                child2[5] = child2[4];
                child2[4] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // xuống dưới
                char[] child3 = n.Code.ToCharArray();
                child3[5] = child3[8];
                child3[8] = '0';
                map       = new string(child3);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 6:
            {
                // lên trên
                char[] child1 = n.Code.ToCharArray();
                child1[6] = child1[3];
                child1[3] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang phải
                char[] child2 = n.Code.ToCharArray();
                child2[6] = child2[7];
                child2[7] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 7:
            {
                // lên trên
                char[] child1 = n.Code.ToCharArray();
                child1[7] = child1[4];
                child1[4] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang trái
                char[] child2 = n.Code.ToCharArray();
                child2[7] = child2[6];
                child2[6] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang phải
                char[] child3 = n.Code.ToCharArray();
                child3[7] = child3[8];
                child3[8] = '0';
                map       = new string(child3);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }

            case 8:
            {
                // lên trên
                char[] child1 = n.Code.ToCharArray();
                child1[8] = child1[5];
                child1[5] = '0';
                string map = new string(child1);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }

                // sang trái
                char[] child2 = n.Code.ToCharArray();
                child2[8] = child2[7];
                child2[7] = '0';
                map       = new string(child2);
                if (n.Parent == null || !n.Code.Equals(map))
                {
                    Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                    if (!IsInCloseList(child))
                    {
                        AddNodeToOpenList(child);
                    }
                }
                break;
            }
            }
        }
Beispiel #14
0
        // truy vết, hiển thị bước đi
        private void timerPlay_Tick(object sender, EventArgs e)
        {
            progressBar1.Style = ProgressBarStyle.Continuous;
            progressBar1.Maximum = this.TraceList.Count;
            progressBar1.Minimum = 0;
            progressBar1.Step = 1;

            if (this.StepCount < this.TraceList.Count)
            {
                this.CurNode = this.TraceList[this.StepCount];
                pbGame.Refresh();

                this.lblCount.Text = "" + this.StepCount++;
                progressBar1.PerformStep();

                if (this.StepCount == this.TraceList.Count)
                {
                    this.timerPlay.Enabled = false;
                    lblFinish.Text = "ĐÃ GIẢI XONG";
                    MessageBox.Show("Đã giải xong", "Hoàn thành", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    if (MessageBox.Show("Bạn muốn tiếp tục không?", "?", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        lblFinish.Text = "";
                        lblCountStatistic.Text = "";
                        progressBar1.Value = 0;
                        bntNew_Click(null, null);
                    }
                    else
                    {
                        Application.Exit();
                    }
                    GC.Collect();
                    this.btnResolve.Text = "Giải";
                }
            }
        }
Beispiel #15
0
        // Thuật toán A*
        private Status_Node Start(string start, string end)
        {
            Stopwatch sw = new Stopwatch();

            // khởi tạo danh sách
            OpenList.Clear();
            CloseList.Clear();
            StepCount = 0;

            sw.Start();

            // node đầu tiên là ma trận đề bài
            Status_Node firstNode = new Status_Node(start, null, 0, CalculateH(start));

            AddNodeToOpenList(firstNode);

            Status_Node currentNode = null;
            // tính toán bước đi, với list có số ptu lớn quá 50000 -> không tìm thấy
            while (OpenList.Count > 0 && OpenList.Count < 50000)
            {
                currentNode = GetNodeFromOpenList(); // lấy 1 node đầu tiên trong list, chuyển vào close list

                // kiểm tra xem có phải trạng thái đích không?
                if (currentNode.Code.Equals(FINISH)) // nếu đúng thì trả về trạng thái này
                {
                    sw.Stop();
                    lblFinish.Text = "Thời gian: " + sw.ElapsedMilliseconds.ToString() + " mili giây";
                    lblCountStatistic.Text = "Số trạng thái tìm được: " + OpenList.Count.ToString();
                    return currentNode;
                }

                ExpandNode(currentNode);// tìm các trạng thái con nếu không thấy
            }
            return null;
        }
Beispiel #16
0
 /// <summary>
 /// Kiểm tra sự tồn tại của 1 node trong list Close
 /// nếu có -> return true, ngược lại là false
 /// </summary>
 private bool IsInCloseList(Status_Node n)
 {
     for (int i = 0; i < CloseList.Count; i++)
     {
         if (CloseList[i].Code.Equals(n.Code))
         {
             return true;
         }
     }
     return false;
 }
Beispiel #17
0
        /// <summary>
        /// tính toán xem trạng thái có thể trở về trạng thái đích được không
        /// </summary>
        private bool IsCanSolve(Status_Node n)
        {
            int length = n.Code.Length;
            int value = 0;
            int[] k = new int[length];

            for (int i = 0; i < length; i++)
                int.TryParse(n.Code[i].ToString(), out k[i]);

            for (int i = 0; i < length; i++)
            {
                int t = k[i];
                if (t > 0)
                {
                    for (int j = i + 1; j < length; j++)
                    {
                        if (k[j] < t && k[j] > 0)
                        {
                            value++;
                        }
                    }
                }
            }

            if (value % 2 != 0)
                return true;
            else
                return false;
        }
Beispiel #18
0
        /// <summary>
        /// Tính toán các trạng thái con của node n
        /// </summary>
        private void ExpandNode(Status_Node n)
        {
            int index = n.Code.IndexOf('0'); // tìm vị trí '0' trong chuỗi

            switch (index)
            {
                case 0: // nếu ô 0 đang ở vị trí của ô số 1 thì có thể sang phải hoặc xuống dưới
                    {
                        // trạng thái con 1 - sang phải
                        char[] child1 = n.Code.ToCharArray();
                        // sang phải. VD: 083124765 chuyển thành 803124765
                        child1[0] = child1[1];
                        child1[1] = '0';
                        string map = new string(child1);

                        // nếu node n không có cha hoặc node con sinh ra khác n
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            // sinh node con
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            // nếu node con chưa có trong list close
                            if (!IsInCloseList(child))
                            {
                                AddNodeToOpenList(child); // chèn vào list open
                            }
                        }

                        // xuống dưới
                        char[] child2 = n.Code.ToCharArray();
                        child2[0] = child2[3];
                        child2[3] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                            {
                                AddNodeToOpenList(child);
                            }
                        }
                        break;
                    }
                case 1:
                    {
                        // sang trái
                        char[] child1 = n.Code.ToCharArray();
                        child1[1] = child1[0];
                        child1[0] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang phải
                        char[] child2 = n.Code.ToCharArray();
                        child2[1] = child2[2];
                        child2[2] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // xuống dưới
                        char[] child3 = n.Code.ToCharArray();
                        child3[1] = child3[4];
                        child3[4] = '0';
                        map = new string(child3);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
                case 2:
                    {
                        // sang trái
                        char[] child1 = n.Code.ToCharArray();
                        child1[2] = child1[1];
                        child1[1] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // xuống dưới
                        char[] child2 = n.Code.ToCharArray();
                        child2[2] = child2[5];
                        child2[5] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
                case 3:
                    {
                        // lên trên
                        char[] child1 = n.Code.ToCharArray();
                        child1[3] = child1[0];
                        child1[0] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang phải
                        char[] child2 = n.Code.ToCharArray();
                        child2[3] = child2[4];
                        child2[4] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // xuống dưới
                        char[] child3 = n.Code.ToCharArray();
                        child3[3] = child3[6];
                        child3[6] = '0';
                        map = new string(child3);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
                case 4:
                    {
                        // lên trên
                        char[] child1 = n.Code.ToCharArray();
                        child1[4] = child1[1];
                        child1[1] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang trái
                        char[] child2 = n.Code.ToCharArray();
                        child2[4] = child2[3];
                        child2[3] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang phải
                        char[] child3 = n.Code.ToCharArray();
                        child3[4] = child3[5];
                        child3[5] = '0';
                        map = new string(child3);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // xuống dưới
                        char[] child4 = n.Code.ToCharArray();
                        child4[4] = child4[7];
                        child4[7] = '0';
                        map = new string(child4);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
                case 5:
                    {
                        // lên trên
                        char[] child1 = n.Code.ToCharArray();
                        child1[5] = child1[2];
                        child1[2] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang trái
                        char[] child2 = n.Code.ToCharArray();
                        child2[5] = child2[4];
                        child2[4] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // xuống dưới
                        char[] child3 = n.Code.ToCharArray();
                        child3[5] = child3[8];
                        child3[8] = '0';
                        map = new string(child3);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
                case 6:
                    {
                        // lên trên
                        char[] child1 = n.Code.ToCharArray();
                        child1[6] = child1[3];
                        child1[3] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang phải
                        char[] child2 = n.Code.ToCharArray();
                        child2[6] = child2[7];
                        child2[7] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
                case 7:
                    {
                        // lên trên
                        char[] child1 = n.Code.ToCharArray();
                        child1[7] = child1[4];
                        child1[4] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang trái
                        char[] child2 = n.Code.ToCharArray();
                        child2[7] = child2[6];
                        child2[6] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang phải
                        char[] child3 = n.Code.ToCharArray();
                        child3[7] = child3[8];
                        child3[8] = '0';
                        map = new string(child3);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
                case 8:
                    {
                        // lên trên
                        char[] child1 = n.Code.ToCharArray();
                        child1[8] = child1[5];
                        child1[5] = '0';
                        string map = new string(child1);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }

                        // sang trái
                        char[] child2 = n.Code.ToCharArray();
                        child2[8] = child2[7];
                        child2[7] = '0';
                        map = new string(child2);
                        if (n.Parent == null || !n.Code.Equals(map))
                        {
                            Status_Node child = new Status_Node(map, n, n.G + 1, CalculateH(map));
                            if (!IsInCloseList(child))
                                AddNodeToOpenList(child);
                        }
                        break;
                    }
            }
        }