Esempio n. 1
0
        public void ComputerMove(int player, int difficulty) //máy đánh ( có thể đánh cho người hoặc đánh cho máy)
        {
            if (_StackMoves.Count == 0)                      //khi máy đánh trước(chưa có quân nào trên bàn cờ) thì đánh vào giữa bàn cờ
            {
                int L = _CaroBoard.LineAmount / 2, C = _CaroBoard.ColumnAmount / 2;
                _Nodes[L, C].NStatus = player;
                _Nodes[L, C].PaintNewNode();  //tô màu cho nước mới đánh cho dễ thấy
                _Nodes[L, C].Draw();
                _Player = -player;
                _StackMoves.Push(_Nodes[L, C]);
                return;
            }
            VMove Move = new VMove();;

            switch (difficulty)                                        //tìm kiếm nước đi tùy theo độ khó đã chọn
            {
            case 1: Move = FindCMove(1, 1, 1, player, -10, 10); break; //dễ

            case 2: Move = FindCMove(3, 2, 2, player, -10, 10); break; //thường

            case 3: Move = FindCMove(5, 3, 3, player, -10, 10); break; //khó

            case 4: Move = FindCMove(8, 3, 3, player, -10, 10); break; //rất khó
            }
            _Nodes[Move.x, Move.y].NStatus = player;                   //set trạng thái
            _Nodes[Move.x, Move.y].PaintNewNode();                     //tô màu và vẽ quân cờ
            _Nodes[Move.x, Move.y].Draw();
            _StackMoves.Peek().Del();                                  //xóa màu của nước trước
            _StackMoves.Peek().Draw();
            _Player = -player;                                         //nhường lượt chơi lại
            _StackMoves.Push(_Nodes[Move.x, Move.y]);                  //lưu vào stack
        }
Esempio n. 2
0
        private List <VMove> EValue(int player)              //lượng giá các nước đi trong khu vực tìm kiếm
        {
            List <VMove>    ValueBoard = new List <VMove>(); //mảng lưu các nước đi đã được lượng giá
            List <CaroNode> search     = SearchArea(2);      // khu vực tìm kiếm

            foreach (CaroNode a in search)                   //lượng giá
            {
                long AttackPoint = AttackPointHorizontal(a.Line, a.Column, player) + AttackPointVertical(a.Line, a.Column, player) + AttackPointDiagonalL(a.Line, a.Column, player) + AttackPointDiagonalR(a.Line, a.Column, player);
                long DefendPoint = DefendPointHorizontal(a.Line, a.Column, player) + DefendPointVertical(a.Line, a.Column, player) + DefendPointDiagonalL(a.Line, a.Column, player) + DefendPointDiagonalR(a.Line, a.Column, player);
                if (AttackPoint >= DefendPoint)                    //Nếu điểm tấn công lớn hơn
                {
                    VMove b = new VMove(AttackPoint, DefendPoint); //khởi tạo và thêm vào list điểm chính là tấn công
                    b.x = a.Line;
                    b.y = a.Column;
                    ValueBoard.Add(b);
                }
                else
                {
                    VMove b = new VMove(DefendPoint, AttackPoint);       //nếu không thì điểm chính là phòng ngư
                    b.x = a.Line;
                    b.y = a.Column;
                    ValueBoard.Add(b);
                }
            }
            return(ValueBoard);
        }
Esempio n. 3
0
        private VMove VlMaxPos(List <VMove> ValueBoard)  //lấy ra nước đi có giá trị lớn nhất
        {
            long  temp = long.MinValue;
            VMove rs   = new VMove();
            int   max  = 0;

            for (int i = 0; i < ValueBoard.Count; i++) //lấy ra nước có điểm cao nhất , nếu bằng thì so sánh điểm phụ
            {
                if (ValueBoard[i].value > temp || (ValueBoard[i].value == temp && ValueBoard[i].subvalue > ValueBoard[max].subvalue))
                {
                    rs.x = ValueBoard[i].x;
                    rs.y = ValueBoard[i].y;
                    temp = ValueBoard[i].value;
                    max  = i;
                }
            }
            ValueBoard[max] = new VMove(rs.x, rs.y, long.MinValue, 0);       //set giá tri xuống để không bị lấy ra lần nữa
            return(rs);
        }
Esempio n. 4
0
        private VMove FindCMove(int depth, int cmoveamount, int hmoveamount, int player, long alpha, long beta)
        {
            if (WinCheck(false) == true)       //kiểm tra thắng thua nhưng không vẽ đường chiến thắng
            {
                if (_Result == -1)
                {
                    return(new VMove(1, depth));                    //nếu máy thắng thì trả về -1 và độ sâu
                }
                else
                if (_Result == 1)
                {
                    return(new VMove(-1, depth));                   // thua thì tra về 1 và độ sâu
                }
                else
                {
                    return(new VMove(0, 0));                       //hòa thì trả về 0
                }
            }
            if (depth == 0)
            {
                return(new VMove(0, 0));                //độ sâu giới hạn thì trả về 0
            }
            VMove temp;                                 //nước đi tạm
            VMove rs = new VMove();                     //nước đi kết quả

            if (player == 1)                            //nếu là lượt người chơi
            {
                List <VMove> vb = EValue(1);            //lượng giá các nước đi của người chơi
                //hmoveamount = vb.Count();
                VMove   Bm    = new VMove(2, 10);       //nước đi tôt nhất
                VMove[] hMove = new VMove[hmoveamount]; //mảng lưu các nước đi tiềm năng
                for (int i = 0; i < hmoveamount; i++)   //lấy hmoveamount nước đi tốt nhất từ mảng lượng giá
                {
                    hMove[i] = VlMaxPos(vb);
                }
                for (int i = 0; i < hmoveamount; i++)
                {
                    _Nodes[hMove[i].x, hMove[i].y].NStatus = 1;                             //đi nước đi này
                    _StackMoves.Push(_Nodes[hMove[i].x, hMove[i].y]);
                    temp = FindCMove(depth - 1, cmoveamount, hmoveamount, -1, alpha, beta); //Phát triển đến độ sâu tiếp theo và trả vê giá trị
                    if (Bm.value > temp.value || (Bm.value == 1 && temp.value == 1 && Bm.depth > temp.depth) || (Bm.value == -1 && temp.value == -1 && Bm.depth < temp.depth))
                    {                                                                       //lấy nước đi có giá trị nhỏ nhất ( nếu 2 nước đi dẫn đến chiến thăng (-1) thì depth cao nhất ngược lại dẫn đên thua (1) chon depth thấp nhất
                        rs.value = Bm.value = temp.value;
                        rs.depth = Bm.depth = temp.depth;
                        rs.x     = hMove[i].x;
                        rs.y     = hMove[i].y;
                    }
                    _StackMoves.Pop();         //trả lại  nguyên trạng
                    _Nodes[hMove[i].x, hMove[i].y].NStatus = 0;
                    if (beta > Bm.value)
                    {
                        beta = Bm.value;                    //cắt tỉa alphabeta
                    }
                    if (beta <= alpha)
                    {
                        break;
                    }
                }
                return(rs);
            }
            else
            {
                //nếu là lượt của máy
            }
            {
                List <VMove> vb = EValue(-1);           //lượng giá các nước đi của người chơi
                //cmoveamount = vb.Count();
                VMove   Bm    = new VMove(-2, -1);      //nước đi tôt nhất
                VMove[] cMove = new VMove[cmoveamount]; //mảng lưu các nước đi tiềm năng
                for (int i = 0; i < cmoveamount; i++)   //lấy cmoveamount nước đi tốt nhất từ mảng lượng giá
                {
                    cMove[i] = VlMaxPos(vb);
                }
                for (int i = 0; i < cmoveamount; i++)
                {
                    _Nodes[cMove[i].x, cMove[i].y].NStatus = -1;
                    _StackMoves.Push(_Nodes[cMove[i].x, cMove[i].y]);                      //đi nước đi này
                    temp = FindCMove(depth - 1, cmoveamount, hmoveamount, 1, alpha, beta); //Phát triển đến độ sâu tiếp theo và trả vê giá trị
                    if (Bm.value < temp.value || (Bm.value == 1 && temp.value == 1 && Bm.depth < temp.depth) || (Bm.value == -1 && temp.value == -1 && Bm.depth > temp.depth))
                    {                                                                      //lấy nước đi có giá trị nhỏ nhất ( nếu 2 nước đi dẫn đến chiến thăng (1) thì depth cao nhất ngược lại dẫn đên thua (-1) chon depth thấp nhất
                        rs.value = Bm.value = temp.value;
                        rs.depth = Bm.depth = temp.depth;
                        rs.x     = cMove[i].x;
                        rs.y     = cMove[i].y;
                    }
                    _StackMoves.Pop();  //trả về nguyên trạng
                    _Nodes[cMove[i].x, cMove[i].y].NStatus = 0;
                    if (beta < Bm.value)
                    {
                        beta = Bm.value;                        //cắt tỉa alphabeta
                    }
                    if (beta <= alpha)
                    {
                        break;
                    }
                }
                return(rs);      // trả về nước đi tốt nhất
            }
        }