static void TryMove(int[,] State, clsMove Move) { Point c = Move.CurPos; Point n = Move.NewPos; int value = State[c.X, c.Y]; //Nhập Thành if (value / 10 == 6) { if (Math.Abs(n.X - c.X) == 2) { if (n.X == 7) { int tmp = State[8, n.Y]; State[8, n.Y] = 0; State[6, n.Y] = tmp; } if (n.X == 3) { int tmp = State[1, n.Y]; State[1, n.Y] = 0; State[4, n.Y] = tmp; } } } State[n.X, n.Y] = value; State[c.X, c.Y] = 0; }
static void TryMove(int[,] State, clsMove Move) { Vector2 c = Move.CurPos; Vector2 n = Move.NewPos; int value = State[(int)c.x, (int)c.y]; //Nhập Thành if (value / 10 == 6) { if (Math.Abs(n.x - c.x) == 2) { if (n.x == 7) { int tmp = State[8, (int)n.y]; State[8, (int)n.y] = 0; State[6, (int)n.y] = tmp; } if (n.x == 3) { int tmp = State[1, (int)n.y]; State[1, (int)n.y] = 0; State[4, (int)n.y] = tmp; } } } State[(int)n.x, (int)n.y] = value; State[(int)c.x, (int)c.y] = 0; }
//vd: E2E3, E7E8=q public void MakeMove(string strMove) { if (strMove == "") { return; } clsMove MyMove = new clsMove(strMove); UcChessPiece Piece = this.arrChessCell[MyMove.CurPos.X, MyMove.CurPos.Y].ChessPiece; if (Piece == null) { return; } arrMove = clsChessEngine.FindAllLegalMove(_BoardState, MyMove.CurPos, Piece.Type); DoMove(Piece, MyMove); }
//DateTime StartTime, EndTime; private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { try { IsThinking = true; if (IsCancelThinking == true) { IsCancelThinking = false; return; } Point CurPos = new Point(); Point NewPos = new Point(); string strFen = clsFEN.GetFENWithoutMoveNumber(this); MyMove = clsChessEngine.ReadFromBook(strFen); if (MyMove == null) { MyMove = new clsMove(CurPos, NewPos); //StartTime = DateTime.Now; arrMove = clsChessEngine.GenerateMove(this._BoardState, this.arrFEN, tmpOppSide, ref MyMove, tmpDifficulty); if (tmpDifficulty == GameDifficulty.Hard) { clsChessEngine.WriteToBook(strFen, MyMove); } } else { // intOutOfBookCount = 0; ChessPieceType eType = (ChessPieceType)(this._BoardState[MyMove.CurPos.X, MyMove.CurPos.Y] / 10); arrMove = clsChessEngine.FindAllLegalMove(this._BoardState, MyMove.CurPos, eType); } } catch (Exception ex) { MessageBox.Show(ex.Message); } }
//Code change ngày 30/07/2010 //Thêm đối số để phục vụ cho việc xác định các nước đi bất biến 3 lần public static int AlphaBeta(int[,] BoardState, ArrayList arrFEN, int depth, ChessSide eSide, int Alpha, int Beta) { //NodeCount++; if (depth == 0) { return(Evaluate(BoardState, arrFEN)); } int best = -100000; clsMove bestmove = new clsMove(); ArrayList arrMoves = Successors(BoardState, eSide); if (arrMoves.Count == 0) { //Quân Vua mình bị chiếu và người hết cờ là mình => trừ điểm mình if (clsKing.IsChecked(BoardState, Myside) == true) { if (eSide == Myside) { return(-10000 - depth); } } //Quân Vua đối phươn bị chiếu và người hết cờ là đối phương => trừ điểm đối phương if (clsKing.IsChecked(BoardState, OppSide) == true) { if (eSide == OppSide) { return(-10000 - depth); } } return(0); } //Sắp xếp các nước đi nhằm tăng hiệu quả của hàm Alpha Beta int intPromotionType = 2; if (depth > 1) { foreach (clsMove m in arrMoves) { int[,] State = new int[10, 10]; Array.Copy(BoardState, State, BoardState.Length); Point c = m.CurPos; Point n = m.NewPos; int value = State[c.X, c.Y]; if (value / 10 == 1) { if (value % 10 == 1 && n.Y == 1) { value = intPromotionType * 10 + 1; intPromotionType++; State[c.X, c.Y] = value; } if (value % 10 == 2 && n.Y == 8) { value = intPromotionType * 10 + 2; intPromotionType++; State[c.X, c.Y] = value; } } if (intPromotionType == 6) { intPromotionType = 2; } TryMove(State, m); int Score = AlphaBeta(State, arrFEN, 0, eSide, -Beta, -Alpha); m.Score = Score; } Sort(arrMoves, eSide); } intPromotionType = 5; while (arrMoves.Count > 0 && best < Beta) { int[,] State = new int[10, 10]; Array.Copy(BoardState, State, BoardState.Length); clsMove Move = (clsMove)arrMoves[arrMoves.Count - 1]; Point c = Move.CurPos; Point n = Move.NewPos; int x = State[c.X, c.Y]; if (x / 10 == 1) { if (x % 10 == 1 && n.Y == 1) { x = intPromotionType * 10 + 1; Move.PromoteTo = (ChessPieceType)intPromotionType; intPromotionType--; State[c.X, c.Y] = x; } if (x % 10 == 2 && n.Y == 8) { x = intPromotionType * 10 + 2; Move.PromoteTo = (ChessPieceType)intPromotionType; intPromotionType--; State[c.X, c.Y] = x; } if (intPromotionType == 1) { intPromotionType = 5; } } TryMove(State, Move); arrMoves.RemoveAt(arrMoves.Count - 1); //Đã đi thử xong ArrayList arrFENNew = new ArrayList(); arrFENNew.AddRange(arrFEN); arrFENNew.Add(clsFEN.GetPiecePlacementString(State)); ChessSide s; if (eSide == ChessSide.White) { s = ChessSide.Black; } else { s = ChessSide.White; } if (best > Alpha) { Alpha = best; } int value = -AlphaBeta(State, arrFENNew, depth - 1, s, -Beta, -Alpha); if (value > best) { best = value; bestmove = Move; } } if (depth == MaxDepth) { bestmove.Score = best; MyBestMove = bestmove; } return(best); }
public void DoMove(UcChessPiece Piece, clsMove move) { if ((Piece.Side == ChessSide.Black && this._WhiteToMove == true) || (Piece.Side == ChessSide.White && this._WhiteToMove == false)) { return; } Point CurPos = move.CurPos; Point NewPos = move.NewPos; UcChessCell ct = (UcChessCell)this.arrChessCell[NewPos.X, NewPos.Y]; //*********************************Kiểm tra nước đi************************ //Kiểm tra Xem Quân Cờ có thể di chuyển từ CurPos đến NewPos hay không if (clsChessEngine.CanMove(arrMove, NewPos) == true) { UnHighlightLastMove(); PushState(); string strLastCell = Convert.ToChar(CurPos.X + 64) + CurPos.Y.ToString(); string strNewCell = Convert.ToChar(NewPos.X + 64) + NewPos.Y.ToString(); this._BoardState[CurPos.X, CurPos.Y] = 0;//Đánh dấu vị trí cũ không chứa quân cờ this._BoardState[NewPos.X, NewPos.Y] = (int)Piece.Type * 10 + (int)Piece.Side; //Kiểm tra xem quân vua có bị chiếu không //****************Chưa tính trường hợp chiếu bí và Hòa*************** bool bCapture = false; //Lấy vị trí Bắt tôt qua đường nếu có if (Piece.Type == ChessPieceType.Pawn) { if (Math.Abs(NewPos.Y - CurPos.Y) == 2) { _EnPassantPoint = clsPawn.GetEnPassantPoint(this._BoardState, NewPos); } else if (CurPos.X == NewPos.X) { _EnPassantPoint = new Point(); } //Thực hiện nước bắt tốt qua đường if (NewPos == _EnPassantPoint) { Point CapturedPoint; if (Piece.Side == ChessSide.White) { CapturedPoint = new Point(_EnPassantPoint.X, _EnPassantPoint.Y - 1); } else { CapturedPoint = new Point(_EnPassantPoint.X, _EnPassantPoint.Y + 1); } UcChessCell bt = arrChessCell[CapturedPoint.X, CapturedPoint.Y]; this._BoardState[CapturedPoint.X, CapturedPoint.Y] = 0;//Đánh dấu vị trí cũ không chứa quân cờ stkCapturedPieces.Push(bt.ChessPiece); bt.ChessPiece.Hide(); bt.ChessPiece = null; _EnPassantPoint = new Point(); bCapture = true; } } else { _EnPassantPoint = new Point(); } if (ct.ChessPiece != null && ct.ChessPiece.Side != Piece.Side)//Nếu đã có quân cờ đặt tại ô đến { UcChessPiece CapturedPiece = ct.ChessPiece; stkCapturedPieces.Push(CapturedPiece); CapturedPiece.Hide();//Xóa quân cờ tại ô Di chuyển đến if (CapturedPiece.Type == ChessPieceType.Rook) { if (CapturedPiece.Side == ChessSide.White) { if (CapturedPiece.PositionX == 1) { QUEENsideCastling = false; } if (CapturedPiece.PositionX == 8) { KINGsideCastling = false; } } else { if (CapturedPiece.PositionX == 1) { queensideCastling = false; } if (CapturedPiece.PositionX == 8) { kingsideCastling = false; } } } ct.ChessPiece = null; bCapture = true; } Piece.UConCell.ChessPiece = null;//Ô cờ trước đó ko còn chứa quân cờ này nữa //Dat Quan Co Tai Vi Tri Moi ct.ChessPiece = Piece; Piece.UConCell = ct; //Gán tọa độ mới cho quân cờ Piece.PositionX = NewPos.X; Piece.PositionY = NewPos.Y; string strPromote = ""; if (Piece.Type == ChessPieceType.Pawn) { if (clsPawn.Promotion(Piece, move.PromoteTo) == true) { this._BoardState[Piece.PositionX, Piece.PositionY] = (int)Piece.Type * 10 + (int)Piece.Side; switch (Piece.Type) { case ChessPieceType.Bishop: strPromote = "=B"; break; case ChessPieceType.Knight: strPromote = "=N"; break; case ChessPieceType.Rook: strPromote = "=R"; break; case ChessPieceType.Queen: strPromote = "=Q"; break; } move.PromoteTo = Piece.Type; } } if (bCapture == true) { PushMove(Piece.Side, strLastCell + "X" + strNewCell + strPromote); OnPieceCaptured(EventArgs.Empty); PlayMusic(CapturedSound); } else { PushMove(Piece.Side, strLastCell + "-" + strNewCell + strPromote); PlayMusic(MovedSound); } //Cập Nhật trạng thái nhập thành if (Piece.Type == ChessPieceType.Rook) { if (Piece.Side == ChessSide.White) { if (Piece.PositionX == 1) { QUEENsideCastling = false; } if (Piece.PositionX == 8) { KINGsideCastling = false; } } else { if (Piece.PositionX == 1) { queensideCastling = false; } if (Piece.PositionX == 8) { kingsideCastling = false; } } } if (Piece.Type == ChessPieceType.King) { if (Piece.Side == ChessSide.White) { QUEENsideCastling = false; KINGsideCastling = false; } else { queensideCastling = false; kingsideCastling = false; } if (Math.Abs(NewPos.X - CurPos.X) == 2)//Nhập Thành { if (NewPos.X == 3) { UcChessCell OldRookCell = (UcChessCell)this.arrChessCell[1, NewPos.Y]; UcChessCell NewRookCell = (UcChessCell)this.arrChessCell[4, NewPos.Y]; this._BoardState[1, NewPos.Y] = 0; //Đánh dấu quân xe không còn ở vị trí cũ this._BoardState[4, NewPos.Y] = 40 + (int)Piece.Side; //Đặt quân xe tại vị trí mới NewRookCell.ChessPiece = OldRookCell.ChessPiece; OldRookCell.ChessPiece = null; NewRookCell.ChessPiece.UConCell = NewRookCell; NewRookCell.ChessPiece.PositionX = NewRookCell.PositionX; NewRookCell.ChessPiece.PositionY = NewRookCell.PositionY; } else { UcChessCell OldRookCell = (UcChessCell)this.arrChessCell[8, NewPos.Y]; UcChessCell NewRookCell = (UcChessCell)this.arrChessCell[6, NewPos.Y]; this._BoardState[8, NewPos.Y] = 0; //Đánh dấu quân xe không còn ở vị trí cũ this._BoardState[6, NewPos.Y] = 40 + (int)Piece.Side; //Đặt quân xe tại vị trí mới NewRookCell.ChessPiece = OldRookCell.ChessPiece; OldRookCell.ChessPiece = null; NewRookCell.ChessPiece.UConCell = NewRookCell; NewRookCell.ChessPiece.PositionX = NewRookCell.PositionX; NewRookCell.ChessPiece.PositionY = NewRookCell.PositionY; } } } arrFEN.Add(clsFEN.GetPiecePlacementString(this._BoardState)); //********Play Sound, Hiển thị thông báo************* this._GameStatus = clsChessEngine.GetGameStatus(this._BoardState, arrFEN, Piece.Side); if (this._GameStatus == GameStatus.BlackWin) { PlayMusic(CheckMatedSound); DisplayMessage("Quân Đen Thắng !"); } if (this._GameStatus == GameStatus.WhiteWin) { PlayMusic(CheckMatedSound); DisplayMessage("Quân Trắng Thắng !"); } if (this._GameStatus == GameStatus.Draw) { if (clsChessEngine.CheckThreefoldRepetition(arrFEN)) { DisplayMessage("Ván cờ Hòa do \"Bất Biến 3 Lần\""); } else if (clsChessEngine.CheckInsufficientMaterial(this._BoardState, Piece.Side)) { DisplayMessage("Ván cờ Hòa do cả 2 bên không đủ quân chiếu bí đối phương"); } else { DisplayMessage("Ván cờ Hòa do không còn nước đi hợp lệ"); } } if (this._GameStatus == GameStatus.NowPlaying && (clsKing.IsChecked(this._BoardState, ChessSide.Black) == true || clsKing.IsChecked(this._BoardState, ChessSide.White) == true)) { PlayMusic(CheckedSound); if ((this._OwnSide == ChessSide.White && this._WhiteToMove == false) || (this._OwnSide == ChessSide.Black && this._WhiteToMove == true)) { DisplayMessage("Chiếu !"); } } if (Piece.Side == this._OwnSide) { AlreadyMakeMove = true; } //Chuyển lượt đi cho đối phương if (Piece.Side == ChessSide.Black) { this.WhiteToMove = true; } else { this.WhiteToMove = false; } //Cho máy đi if (Piece.Side == this.OwnSide && this.GameMode == GameMode.VsComputer) { IsThinking = true; timerComputerMove.Enabled = true; } LastMove = move; HighlightLastMove(); OnMoveMaked(EventArgs.Empty); } else { Piece.UConCell.ChessPiece = Piece;// tra về ô cũ } }