Exemple #1
0
 public ChessPosition()
 {
     initChessEval();
     Board = new SquareInfo[64];
     emptyBoard = new SquareInfo[64];
     Princ = new ChessMove[maxDepth, maxDepth];
     killers = new ChessMove[2, 1000];
     mvvLva = new int[8, 8];
     searchHistory = new int[16, 64];
     // Init the mvvLva array
     for (int v = 0; v <= 6; v++)
         for (int a = 0; a <= 6; a++)
             mvvLva[v, a] = v * 100 +6 - a;
     // Init the killers array
     for (int i = 0; i < 1000; i++)
     {
         killers[0, i] = new ChessMove(new Square(99, 99), new Square(99, 99));
         killers[1, i] = new ChessMove(new Square(99, 99), new Square(99, 99));
     }
     // Init the emptyBoard and Board arrays
     for (int i = 0; i <= 63; i++)
     {
         emptyBoard[i] = new SquareInfo(Pieces.None, new Square(i));
         Board[i] = emptyBoard[i];
     }
     // Init the hashKeys
     Random rng = new Random();
     pieceKeys = new UInt64[16, 64];
     for (int p = 0; p <= 15; p++)
         for (int sq = 0; sq <= 63; sq++)
             pieceKeys[p, sq] = (UInt64)rng.Next() + ((UInt64)rng.Next() << 15) + ((UInt64)rng.Next() << 30) + ((UInt64)rng.Next() << 45) + ((UInt64)rng.Next() << 60);
     castleKeys = new UInt64[16];
     for (int i = 0; i <= 15; i++)
         castleKeys[i] = (UInt64)rng.Next() + ((UInt64)rng.Next() << 15) + ((UInt64)rng.Next() << 30) + ((UInt64)rng.Next() << 45) + ((UInt64)rng.Next() << 60);
     sideKey = (UInt64)rng.Next() + ((UInt64)rng.Next() << 15) + ((UInt64)rng.Next() << 30) + ((UInt64)rng.Next() << 45) + ((UInt64)rng.Next() << 60);
     // Init the pvTable
     pvTable = new Dictionary<ulong, int>();
     EpSquare = new Square(0, 0);
     white = new ToMoveData(PieceColour.White, new Piece(PieceType.Pawn, PieceColour.White), new Piece(PieceType.Knight, PieceColour.White),
         new Piece(PieceType.Bishop, PieceColour.White), new Piece(PieceType.Rook, PieceColour.White), new Piece(PieceType.Queen, PieceColour.White),
         new Piece(PieceType.King, PieceColour.White), 1, 7, 1, CastleFlags.Wks, CastleFlags.Wqs, new Square("e1"), new Square("h1"), new Square("a1"));
     black = new ToMoveData(PieceColour.Black, new Piece(PieceType.Pawn, PieceColour.Black), new Piece(PieceType.Knight, PieceColour.Black),
         new Piece(PieceType.Bishop, PieceColour.Black), new Piece(PieceType.Rook, PieceColour.Black), new Piece(PieceType.Queen, PieceColour.Black),
         new Piece(PieceType.King, PieceColour.Black), 6, 0, -1, CastleFlags.Bks, CastleFlags.Bqs, new Square("e8"), new Square("h8"), new Square("a8"));
     PossibleMoves = new Collection<ChessMove>();
     MoveHistory = new Collection<ChessMove>();
     undoStack = new Stack<ChessMove>();
     NewGame();
 }
Exemple #2
0
 void updatePrinc(ChessMove move, int ply)
 {
     Princ[ply, ply] = move;
     for (int i = ply + 1; i < maxDepth; i++)
         Princ[ply, i] = Princ[ply + 1, i];
     pvTable[HashKey] = (int)move.FromSq + ((int)move.ToSq << 8);
 }
Exemple #3
0
 void makeMove(ChessMove move)
 {
     Square from = move.FromSq;
     Square to = move.ToSq;
     SquareInfo CapturedSqInfo = Board[to];
     Board[to] = Board[from];                    // Move the piece
     Board[from] = emptyBoard[from];             // Replace from SquareInfo with the empty SquareInfo from emptyBoard
     Board[to].Location = to;                    // Update SqInfo location
     move.OldHashKey = HashKey;
     move.OldEpSq = EpSquare;
     EpSquare = new Square(0, 0);
     move.OldCastleFlags = CastleFlags;
     HashKey ^= pieceKeys[move.Piece.ToInt(), from] ^ pieceKeys[move.Piece.ToInt(), to];
     bool pawnMoveOrCapture = false;
     switch (move.Special)
     {
         case SpecialMoveType.PawnMove:
             pawnMoveOrCapture = true;
             break;
         case SpecialMoveType.DoublePawnMove:
             EpSquare = new Square(from.File, from.Rank + thisSide.PawnYDir);
             pawnMoveOrCapture = true;
             break;
         case SpecialMoveType.Promotion:
             Board[to].Piece = move.PromotedTo;
             pawnMoveOrCapture = true;
             HashKey ^= pieceKeys[move.Piece.ToInt(), to] ^ pieceKeys[move.PromotedTo.ToInt(), to];
             break;
         case SpecialMoveType.EnPassant:
             // After the piece has been moved make to = the square of the captured ep pawn
             to.Rank -= thisSide.PawnYDir;
             CapturedSqInfo = Board[to];                 // CapturedSqInfo is the enemy pawn not the square moved into
             Board[to] = emptyBoard[to];
             break;
         case SpecialMoveType.CastleKS:
             // Move the rook
             to = thisSide.RookKCastleSq;
             from = thisSide.KingRookSq;
             Board[to] = Board[from];                    // Move the piece
             Board[from] = emptyBoard[from];             // Replace from SquareInfo with the empty SquareInfo from emptyBoard
             Board[to].Location = to;                    // Update SqInfo location
             HashKey ^= pieceKeys[Board[to].Piece.ToInt(), from] ^ pieceKeys[Board[to].Piece.ToInt(), to];
             break;
         case SpecialMoveType.CastleQS:
             to = thisSide.RookQCastleSq;
             from = thisSide.QueenRookSq;
             Board[to] = Board[from];                    // Move the piece
             Board[from] = emptyBoard[from];             // Replace from SquareInfo with the empty SquareInfo from emptyBoard
             Board[to].Location = to;                    // Update SqInfo location
             HashKey ^= pieceKeys[Board[to].Piece.ToInt(), from] ^ pieceKeys[Board[to].Piece.ToInt(), to];
             break;
     }
     if (CapturedSqInfo.Piece.PieceColour != PieceColour.None)
     {
         CapturedSqInfo.Prev.Next = CapturedSqInfo.Next;                      // Delink the captured piece
         CapturedSqInfo.Next.Prev = CapturedSqInfo.Prev;
         pawnMoveOrCapture = true;
         // Clear enemy castling rights when capturing one of their rooks on its starting square
         if (to == otherSide.KingRookSq)
             CastleFlags = CastleFlags & ~(otherSide.CanCastleKS);
         if (to == otherSide.QueenRookSq)
             CastleFlags = CastleFlags & ~(otherSide.CanCastleQS);
         HashKey ^= pieceKeys[CapturedSqInfo.Piece.ToInt(), to];
     }
     // Clear castle flag if king or rooks have moved
     if (Board[thisSide.KingStartSq].Piece == thisSide.King)
     {
         if (Board[thisSide.KingRookSq].Piece != thisSide.Rook)
             CastleFlags = CastleFlags & ~thisSide.CanCastleKS;
         if (Board[thisSide.QueenRookSq].Piece != thisSide.Rook)
             CastleFlags = CastleFlags & ~thisSide.CanCastleQS;
     }
     else
         CastleFlags = CastleFlags & ~(thisSide.CanCastleKS | thisSide.CanCastleQS);
     ToMove = toMove == PieceColour.White ? PieceColour.Black : PieceColour.White;
     HashKey ^= castleKeys[(int)move.OldCastleFlags] ^ castleKeys[(int)CastleFlags] ^ sideKey;
     move.CapturedSqInfo = CapturedSqInfo;
     move.HalfMovesSinceLastPawnMoveOrCapture = HalfMovesSinceLastPawnMoveOrCapture;
     undoStack.Push(move);
     if (pawnMoveOrCapture)
         HalfMovesSinceLastPawnMoveOrCapture = 0;
     else
         HalfMovesSinceLastPawnMoveOrCapture++;
     return;
 }
Exemple #4
0
 public bool MakeMove(ChessMove move)
 {
     // Make a move at Ply in the MoveHistory deleting all moves following
     // Look for the move with matching from and to squares in PossibleMoves and make that move since it has SpecialMoveType set up
     ChessMove foundMove = PossibleMoves.FirstOrDefault(o => o.FromSq == move.FromSq && o.ToSq == move.ToSq);
     if (foundMove == null) return false;                   // No matching move
     if (foundMove.Special == SpecialMoveType.Promotion)
         // If the match is a promotion, filter to the promoted piece if specified else a queen
         foundMove = PossibleMoves.FirstOrDefault(o => o.FromSq == move.FromSq && o.ToSq == move.ToSq &&
             o.PromotedTo.PieceType == (move.PromotedTo.PieceType != PieceType.None ? move.PromotedTo.PieceType : PieceType.Queen));
     while (MoveHistory.Count > undoStack.Count)
         MoveHistory.RemoveAt(MoveHistory.Count - 1);
     foundMove.GamePlyNr = CurrentGamePly;
     fillMoveText(foundMove);
     makeMove(foundMove);
     MoveHistory.Add(foundMove);
     generatePossibleMoves(PossibleMoves);
     removeIllegalMoves(PossibleMoves);
     if (isInCheck(thisSide, otherSide))
         if (PossibleMoves.Count > 0)
             foundMove.Text += "+";
         else
             foundMove.Text += "#";
     return true;
 }
Exemple #5
0
 void fillMoveText(ChessMove move)
 {
     move.Text = "";
     if (move.Special == SpecialMoveType.CastleKS)
     {
         move.Text = "O-O";
         return;
     }
     if (move.Special == SpecialMoveType.CastleQS)
     {
         move.Text = "O-O-O";
         return;
     }
     PieceType piece = Board[move.FromSq].Piece.PieceType;
     bool capture = (Board[move.ToSq].Piece.PieceType != PieceType.None || move.Special == SpecialMoveType.EnPassant);
     if (piece == PieceType.Pawn)
     {
         if (capture)
             move.Text += ((char)(move.FromSq.File + 'a')).ToString();
     }
     else
     {
         // Can more than one of the move's PieceType move to the same square?
         int sameTo = 0, sameFile = 0, sameRank = 0;
         foreach (ChessMove m in PossibleMoves)
         {
             if (Board[m.FromSq].Piece.PieceType == piece)
                 if (m.FromSq != move.FromSq && m.ToSq == move.ToSq)
                 {
                     sameTo++;
                     if (m.FromSq.File == move.FromSq.File)
                         sameFile++;     // Another possible move with the same PieceType and From file moving to the same square
                     if (m.FromSq.Rank == move.FromSq.Rank)
                         sameRank++;     // Likewise with rank
                 }
         }
         move.Text = pieceStr[(int)piece].ToString();
         if (sameTo > 0)
         {
             if (sameFile == 0 && sameRank == 0 || sameRank > 0)
                 move.Text += ((char)(move.FromSq.File + 'a')).ToString();           // Needs rank specification to disambiguify
             if (sameFile > 0)
                 move.Text += ((char)(move.FromSq.Rank + '1')).ToString();           // Needs file specificatino to disambiguify
         }
     }
     if (capture)
         move.Text += "x";                                                       // Capture
     move.Text += move.ToSq.ToString();
     if (move.Special == SpecialMoveType.Promotion)
         move.Text += "=" + pieceStr[(int)move.PromotedTo.PieceType].ToString(); // Promotion
 }
Exemple #6
0
 void addCaptureMove(ChessMove move)
 {
     move.Piece = Board[move.FromSq].Piece;
     // Adjust score according to most valuable victim least valuable attacker
     move.Score = captureScore + mvvLva[(int)Board[move.ToSq].Piece.PieceType, (int)move.Piece.PieceType];
     tmpMoveList.Add(move);
 }
Exemple #7
0
 void addQuietMove(ChessMove move)
 {
     move.Piece = Board[move.FromSq].Piece;
     if (killers[0, CurrentGamePly].Piece == move.Piece && killers[0, CurrentGamePly].FromSq == move.FromSq && killers[0, CurrentGamePly].ToSq == move.ToSq)
         move.Score = killer0Score;
     else
         if (killers[1, CurrentGamePly].Piece == move.Piece && killers[1, CurrentGamePly].FromSq == move.FromSq && killers[1, CurrentGamePly].ToSq == move.ToSq)
             move.Score = killer1Score;
         else
             move.Score += searchHistory[move.Piece.ToInt(), move.ToSq];
     tmpMoveList.Add(move);
 }
Exemple #8
0
 void movePiece(object o)
 {
     object[] args = (object[])o;
     ChessPiece piece = (ChessPiece)args[0];
     int toFile = (int)args[1];
     int toRank = (int)args[2];
     if (toFile < 0 || toFile > 7 || toRank < 0 || toRank > 7 || (toFile == piece.File && toRank == piece.Rank)) return;
     ChessMove move = new ChessMove(new Square(piece.File, piece.Rank), new Square(toFile, toRank));
     makeMove(move);
 }