internal static Bitboard MoveSquare(ref Bitboard bb, SquareE sqr1, SquareE sqr2) { return(bb = GetSquare(bb, sqr1) ? bb ^ (SquareMask(sqr1) | SquareMask(sqr2)) // right : (bb & ~SquareMask(sqr2))); }
//#region Rotated Bitboard //internal static byte[] DiagIndex = // { // 00, 01, 03, 06, 10, 15, 21, 28, 36, 43, 49, 54, 58, 61, 63 // }; //internal static BitRank[] DiagMask = // { // 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0x7F, 0x3F, 0x1F, 0x0F, 0x07, 0x03, 0x01 // }; //// These functions manipulate adjacent bits in 45° rotated BitBoards, //// which correspond to diagonals in 0° and 90° rotated BitBoards. //internal static byte GetDiagIndex( int n ) //{ // return DiagIndex[ n ]; //} //internal static Bitboard MaskDiag( byte n ) //{ // return ((Bitboard) DiagMask[ n ]) << DiagIndex[ n ]; //} //internal static BitRank GetDiag( Bitboard bb, int n ) //{ // return (BitRank) ((bb >> DiagIndex[ n ]) & DiagMask[ n ]); //} //internal static Bitboard RstDiag( ref Bitboard bb, byte n ) //{ // return bb &= ~MaskDiag(n); //} //#endregion internal static Bitboard PreMaskExclusions(SquareE sqr) { if (IsSquareOn(BorderSquares, sqr)) { Bitboard exclusions = EmptySquares; //if( !CheckSquare(SquaresOfFile[ (byte) FileE.File_A ], sqr) ) exclusions |= SquaresOfFile[ (byte) FileE.File_A ]; //if( !CheckSquare(SquaresOfFile[ (byte) FileE.File_H ], sqr) ) exclusions |= SquaresOfFile[ (byte) FileE.File_H ]; //if( !CheckSquare(SquaresOfRank[ (byte) RankE.Rank_1 ], sqr) ) exclusions |= SquaresOfRank[ (byte) RankE.Rank_1 ]; //if( !CheckSquare(SquaresOfRank[ (byte) RankE.Rank_8 ], sqr) ) exclusions |= SquaresOfRank[ (byte) RankE.Rank_8 ]; if (!IsSquareOn(File_A, sqr)) { exclusions |= File_A; } if (!IsSquareOn(File_H, sqr)) { exclusions |= File_H; } if (!IsSquareOn(Rank_1, sqr)) { exclusions |= Rank_1; } if (!IsSquareOn(Rank_8, sqr)) { exclusions |= Rank_8; } return(exclusions); } else { return(BorderSquares); } }
public void Reset() { Flags.Reset(); EnPassant = SquareE.NoSquare; HalfMovesCounter = 0; FullMovesCounter = 1; }
internal void RemovePiece(Piece piece, SquareE square) { byte color = (byte)piece.Color; byte type = (byte)piece.Type; BitBoard.RstSquare(ref Occupies[color], square); BitBoard.RstSquare(ref Pieces[type], square); --PieceCount[color, type]; }
internal static Bitboard DiagA8H1Mask(SquareE sqr) { Debug.Assert(Square.IsValid(sqr), "Not 0-3F"); sbyte diag = (sbyte)(0x38 - (FileIndex(sqr) << 3) - RankIndex(sqr)); byte nort = (byte)(-diag & (diag >> 31)); byte sout = (byte)(diag & (-diag >> 31)); return((DiagA8H1Squares >> sout) << nort); }
//internal void SetupFen( string fenString ) //{ // if( string.IsNullOrEmpty(fenString) ) // { // Debug.Assert(false, "Null or Empty FEN"); // return; // } // ClearBoard(); // Piece piece; // ushort index = 0; // char ch = fenString[ index ]; // while( ch == ' ' ) ch = fenString[ ++index ]; // //Piece placement. put pieces // SquareE sqr = SquareE.A8; // while( ch != ' ' ) // { // // get the piece from its char representation // piece = Piece.Parse(ch); // if( piece != default(Piece) ) // {// there is a piece // byte color = (byte) piece.Color; // byte type = (byte) piece.Type; // if( color != (byte) ColorE.NoColor && type != (byte) PieceE.NoPiece ) // { // #region Checking // if( type == (byte) PieceE.King && PieceCount[ color, type ] >= 1 ) // Debug.Assert(false, "Illegal FEN format", (ColorE) color + " King already there"); // if( (PieceCount[ color, (byte) PieceE.Pawn ] + // Math.Max(PieceCount[ color, (byte) PieceE.Queen ] - 1, 0) + // Math.Max(PieceCount[ color, (byte) PieceE.Rook ] - 2, 0) + // Math.Max(PieceCount[ color, (byte) PieceE.Bishop ] - 2, 0) + // Math.Max(PieceCount[ color, (byte) PieceE.Knight ] - 2, 0)) > 8 ) // { // Debug.Assert(false, "Illegal FEN format", "Too many Pieces of " + (ColorE) color); // } // if( type == (byte) PieceE.Pawn ) // { // RankE rank = Square._Rank(sqr); // if( rank == RankE.Rank_1 || rank == RankE.Rank_8 ) // Debug.Assert(false, "Illegal FEN format", "Pawn Rank"); // } // #endregion // PutPiece(piece, sqr); // put the piece on board // Square.BackwardInc(ref sqr); // } // } // else if( ch == '8' ) // { // Debug.Assert((byte) sqr % File.Files == 0, "Illegal FEN format", "Wrong character"); // sqr -= File.Files; // if( sqr != SquareE.A1 ) // { // ch = fenString[ ++index ]; // if( ch != '/' ) // {// there another char than '/' throw exception // Debug.Assert(false, "Illegal FEN format", "Wrong character"); // } // } // } // else if( ch >= '1' && ch <= '7' ) // {// there is a number // byte emptySqr = (byte) (ch - '0'); // while( emptySqr != 0 ) // skip empty squares // { // Square.BackwardInc(ref sqr); // --emptySqr; // if( (byte) sqr % File.Files == 0 ) // break; // } // Debug.Assert(emptySqr == 0, "Illegal FEN format", "Wrong character"); // } // else if( ch != '/' ) // {// there another char than '/' throw exception // Debug.Assert(false, "Illegal FEN format", "Wrong character"); // } // ch = fenString[ ++index ]; // } // if( sqr != SquareE.NoSquare ) // { // Debug.Assert(false, "Illegal FEN format", "InComplete Position"); // } // while( ch == ' ' ) ch = fenString[ ++index ]; // //Active color. set side to move // if( ch == 'w' ) // { // OnMove = ColorE.White; // } // else if( ch == 'b' ) // { // OnMove = ColorE.Black; // } // else // { // OnMove = ColorE.NoColor; // Debug.Assert(false, "Illegal FEN format", "Active Color"); // } // ch = fenString[ ++index ]; // while( ch == ' ' ) ch = fenString[ ++index ]; // //Castle availability. set castle availability // if( ch == '-' ) // { // ch = fenString[ ++index ]; // } // else // { // while( ch != ' ' ) // { // switch( ch ) // { // case 'K': // { // Bitboard occupy = Occupies[ (byte) ColorE.White ]; // if( BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.King ], SquareE.E1) || // BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.Rook ], SquareE.H1) ) // { // Castle[ (byte) ColorE.White ].ShortCastle = true; // } // else // Debug.Assert(false, "Illegal FEN format", "Castle [White.ShortCastle]"); // } // break; // case 'Q': // { // Bitboard occupy = Occupies[ (byte) ColorE.White ]; // if( BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.King ], SquareE.E1) || // BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.Rook ], SquareE.A1) ) // { // Castle[ (byte) ColorE.White ].LongCastle = true; // } // else // Debug.Assert(false, "Illegal FEN format", "Castle [White.LongCastle]"); // } // break; // case 'k': // { // Bitboard occupy = Occupies[ (byte) ColorE.Black ]; // if( BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.King ], SquareE.E8) || // BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.Rook ], SquareE.H8) ) // { // Castle[ (byte) ColorE.Black ].ShortCastle = true; // } // else // Debug.Assert(false, "Illegal FEN format", "Castle [Black.ShortCastle]"); // } // break; // case 'q': // { // Bitboard occupy = Occupies[ (byte) ColorE.Black ]; // if( BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.King ], SquareE.E8) || // BitBoard.GetSquare(occupy & Pieces[ (byte) PieceE.Rook ], SquareE.A8) ) // { // Castle[ (byte) ColorE.Black ].LongCastle = true; // } // else // Debug.Assert(false, "Illegal FEN format", "Castle [Black.LongCastle]"); // } // break; // default: Debug.Assert(false, "Illegal FEN format", "Castle"); break; // } // ch = fenString[ ++index ]; // } // } // while( ch == ' ' ) ch = fenString[ ++index ]; // //En passant target square. set en passant target // if( ch == '-' ) // { // EnPassant = SquareE.NoSquare; // ch = fenString[ ++index ]; // } // else // { // checks if the square notation is correct // char fileEP = ch; // if( fileEP >= 'a' && fileEP <= 'h' ) // { // char rankEP = fenString[ ++index ]; // if( rankEP == '3' || rankEP == '6' ) // { // ++index; // if( rankEP == '3' && !BitBoard.GetSquare(Occupies[ (byte) ColorE.White ] & Pieces[ (byte) PieceE.Pawn ], Square._Square(fileEP, (char) (rankEP + 1))) || // rankEP == '6' && !BitBoard.GetSquare(Occupies[ (byte) ColorE.Black ] & Pieces[ (byte) PieceE.Pawn ], Square._Square(fileEP, (char) (rankEP - 1))) ) // { // Debug.Assert(false, "Illegal FEN format", "Pawn missing"); // } // EnPassant = Square._Square(fileEP, rankEP); // } // else // Debug.Assert(false, "Illegal FEN format", "En passant (rank)"); // ch = fenString[ index ]; // } // else // Debug.Assert(false, "Illegal FEN format", "En passant (file)"); // } // while( ch == ' ' ) ch = fenString[ ++index ]; // //Halfmove clock. set ply // try // { // int length = fenString.IndexOf(' ', index) - index; // HalfMoveClock = byte.Parse(fenString.Substring(index, length)); // if( HalfMoveClock >= 100 ) // Debug.Assert(false, "Fifty Move Draw"); // index += (ushort) length; // ch = fenString[ index ]; // } // catch // { // Debug.Assert(false, "Illegal FEN format", "HalfMove (Ply)"); // } // while( ch == ' ' ) ch = fenString[ ++index ]; // //Fullmove counter. set move number // try // { // int length = fenString.IndexOf(' ', index); // length = length != -1 ? length : fenString.Length - index; // FullMoveCount = byte.Parse(fenString.Substring(index, length)); // } // catch // { // Debug.Assert(false, "Illegal FEN format", "Moves"); // } // Console.Write(FEN.ToString(this)); // if( IsLegal() ) // { // Console.WriteLine(ToString()); // } //} internal void PutPiece(Piece piece, SquareE square) { byte color = (byte)piece.Color; byte type = (byte)piece.Type; BitBoard.SetSquare(ref Occupies[color], square); BitBoard.SetSquare(ref Pieces[type], square); ++PieceCount[color, type]; }
internal static SquareE[] GetSquares(Bitboard bb) { List <SquareE> square = new List <SquareE>(); for (SquareE sqr = SquareE.A1; sqr <= SquareE.H8; ++sqr) { if (GetSquare(bb, sqr)) { square.Add(sqr); } } return(square.ToArray()); }
public override void Reset() { base.Reset(); EnPassant = SquareE.NoSquare; IsWhiteShortCastling = true; IsWhiteLongCastling = true; IsBlackShortCastling = true; IsBlackLongCastling = true; IsEngineBlack = true; IsEngineOn = true; IsGameStart = true; IsMainline = true; }
public void MovePiece(SquareE origin, SquareE destiny, PieceE promote) { Debug.Assert(IsLegal()); Piece movePiece = PickPiece(origin); if (movePiece.Color == OnMove) { RemovePiece(movePiece, origin); Piece capturePiece = PickPiece(destiny); if (capturePiece.Type != PieceE.NoPiece) { RemovePiece(capturePiece, destiny); } PutPiece(movePiece, destiny); } }
public void SetFen(string fen) { if (string.IsNullOrEmpty(fen)) { return; } if (BeforeSetFen != null) { BeforeSetFen(this, EventArgs.Empty); } //GameValidator = new GameW(fen); GameValidator.SetFen(fen); if (Flags.IsOffline) { if (Flags.IsFirtMove) { MoveIdWhenFenIsSet = 0; } else { MoveIdWhenFenIsSet = CurrentMove.Id; } SwapPlayersIfNeeded(); } EnPassant = ChessLibrary.FenParser.GetEnpasantSqaure(fen); HalfMovesCounter = ChessLibrary.FenParser.GetHalfMovesCounter(fen); FullMovesCounter = ChessLibrary.FenParser.GetFullMovesCounter(fen); Flags.IsBlackShortCastling = ChessLibrary.FenParser.GetIsBlackShortCastling(fen); Flags.IsBlackLongCastling = ChessLibrary.FenParser.GetIsBlackLongCastling(fen); Flags.IsWhiteShortCastling = ChessLibrary.FenParser.GetIsWhiteShortCastling(fen); Flags.IsWhiteLongCastling = ChessLibrary.FenParser.GetIsWhiteLongCastling(fen); //PlayFenSound(); if (AfterSetFen != null) { AfterSetFen(this, EventArgs.Empty); } }
internal static SquareE BackwardInc(ref SquareE sqr) { switch (sqr) { case SquareE.H1: return(sqr = SquareE.NoSquare); case SquareE.H2: return(sqr = SquareE.A1); case SquareE.H3: return(sqr = SquareE.A2); case SquareE.H4: return(sqr = SquareE.A3); case SquareE.H5: return(sqr = SquareE.A4); case SquareE.H6: return(sqr = SquareE.A5); case SquareE.H7: return(sqr = SquareE.A6); case SquareE.H8: return(sqr = SquareE.A7); default: return(++sqr); // sqr = (SquareE) (sqr + 1); } }
private void ClearSquare(SquareE square) { //bool isPiece = false; for (ColorE color = ColorE.White; color <= ColorE.Black; ++color) { Bitboard occupy = Occupies[(byte)color]; if (BitBoard.GetSquare(occupy, square)) { for (PieceE type = PieceE.Pawn; type <= PieceE.King; ++type) { Bitboard piece = Pieces[(byte)type]; if (BitBoard.GetSquare(piece, square)) // occupy & piece { BitBoard.RstSquare(ref Occupies[(byte)color], square); BitBoard.RstSquare(ref Pieces[(byte)type], square); break; //Debug.Assert(!isPiece, "Piece Overlaps"); //isPiece = true; } } } } }
public Piece PickPiece(SquareE sqr) { Piece p = new Piece(); //bool isPiece = false; for (ColorE color = ColorE.White; color <= ColorE.Black; ++color) { Bitboard occupy = Occupies[(byte)color]; if (BitBoard.GetSquare(occupy, sqr)) { for (PieceE type = PieceE.Pawn; type <= PieceE.King; ++type) { Bitboard piece = Pieces[(byte)type]; if (BitBoard.GetSquare(piece, sqr)) // occupy & piece { //Debug.Assert(!isPiece, "Piece Overlaps"); //isPiece = true; return(new Piece(color, type)); } } } } return(p); }
internal static string ToString(Board board) { if (board == default(Board)) { Debug.Assert(false, "Null or Empty FEN"); return(string.Empty); } StringBuilder fenString = new StringBuilder(); #region Pieces for (RankE rank = RankE.Rank_8; ; --rank) { byte emptySqr = 0; for (FileE file = FileE.File_A; file <= FileE.File_H; ++file) { bool isPiece = false; for (ColorE color = ColorE.White; color <= ColorE.Black; ++color) { Bitboard occupy = board.Occupies[(byte)color]; SquareE sqr = Square._Square(file, rank); if (BitBoard.GetSquare(occupy, sqr)) { for (PieceE type = PieceE.Pawn; type <= PieceE.King; ++type) { Bitboard piece = board.Pieces[(byte)type]; if (BitBoard.GetSquare(piece, sqr)) // occupy & piece { isPiece = true; if (emptySqr > 0) { fenString.Append(emptySqr); emptySqr = 0; } fenString.Append(Piece.mapPiece[(byte)color, (byte)type]); break; } } } } if (!isPiece) { ++emptySqr; } } if (emptySqr > 0) { fenString.Append(emptySqr); emptySqr = 0; } if (rank == RankE.Rank_1) { break; } fenString.Append(rankSep); } #endregion fenString.Append(recordSep); #region OnMove switch (board.OnMove) { case ColorE.White: fenString.Append('w'); break; case ColorE.Black: fenString.Append('b'); break; case ColorE.NoColor: default: fenString.Append('-'); break; } #endregion fenString.Append(recordSep); #region Castle if (board.Castle[(byte)ColorE.White].AnyCastle || board.Castle[(byte)ColorE.Black].AnyCastle) { if (board.Castle[(byte)ColorE.White].ShortCastle) { fenString.Append('K'); } if (board.Castle[(byte)ColorE.White].LongCastle) { fenString.Append('Q'); } if (board.Castle[(byte)ColorE.Black].ShortCastle) { fenString.Append('k'); } if (board.Castle[(byte)ColorE.Black].LongCastle) { fenString.Append('q'); } } else { fenString.Append('-'); } #endregion fenString.Append(recordSep); #region EnPassant SquareE ep = board.EnPassant; if (Square.IsValid(ep)) { fenString.Append(ep.ToString().ToLower()); } else { fenString.Append('-'); } #endregion fenString.Append(recordSep); #region HalfMove Clock fenString.Append(board.HalfMoveClock); #endregion fenString.Append(recordSep); #region FullMove Counter fenString.Append(board.FullMoveCount); #endregion return(fenString.ToString()); }
/// Split Method internal static Board ToBoard(string fenString) { const Board emptyBoard = default(Board); if (string.IsNullOrEmpty(fenString)) { return(emptyBoard); } string[] records = fenString.Split(new char[] { recordSep }, StringSplitOptions.RemoveEmptyEntries); int numRecord = records.Length; // --- full fenString check //if( numRecord != 6 ) return emptyBoard; Board board = new Board(); #region Piece placement string[] ranks = records[0].Split(rankSep); if (ranks.Length != Rank.Ranks) { return(emptyBoard); } byte baseSqr = (byte)SquareE.A8; foreach (string rank in ranks) { byte offsetFile = 0; foreach (char achar in rank) { if (achar >= '1' && achar <= '8') { offsetFile += (byte)(achar - '0'); } else { Piece piece = Piece.Parse(achar); if (piece != default(Piece)) {// there is a piece ColorE color = piece.Color; PieceE type = piece.Type; if (color != ColorE.NoColor && type != PieceE.NoPiece) { if (offsetFile >= File.Files) { return(emptyBoard); } SquareE sqr = (SquareE)(baseSqr + offsetFile); switch (type) { case PieceE.Pawn: RankE pawnRank = Square._Rank(sqr); if (pawnRank == RankE.Rank_1 || pawnRank == RankE.Rank_8) { return(emptyBoard); } if (board.PieceCount[(byte)color, (byte)type] >= 8) { return(emptyBoard); } break; case PieceE.King: if (board.PieceCount[(byte)color, (byte)type] >= 1) { return(emptyBoard); } break; case PieceE.Knight: case PieceE.Bishop: case PieceE.Rook: case PieceE.Queen: if (board.PieceCount[(byte)color, (byte)PieceE.Pawn] + board.PieceCount[(byte)color, (byte)PieceE.Knight] + board.PieceCount[(byte)color, (byte)PieceE.Bishop] + board.PieceCount[(byte)color, (byte)PieceE.Rook] + board.PieceCount[(byte)color, (byte)PieceE.Queen] >= 15) { return(emptyBoard); } break; } board.PutPiece(piece, sqr); // put the piece on board } } else { return(emptyBoard); } ++offsetFile; } } if (offsetFile == 0) // Allow null lines = /8/ { offsetFile = File.Files; } if (offsetFile != File.Files) { return(emptyBoard); } baseSqr -= File.Files; } for (ColorE color = ColorE.White; color <= ColorE.Black; ++color) { Bitboard occupy = board.Occupies[(byte)color]; // check too many total pieces if (BitBoard.CountSets(occupy) > 16) { return(emptyBoard); } // check if the number of Pawns plus the number of extra Queens, Rooks, Bishops, Knights // (which can result only by promotion) exceeds 8 // check too many color pieces if (board.PieceCount[(byte)color, (byte)PieceE.Pawn] + Math.Max(board.PieceCount[(byte)color, (byte)PieceE.Knight] - 2, 0) + Math.Max(board.PieceCount[(byte)color, (byte)PieceE.Bishop] - 2, 0) + Math.Max(board.PieceCount[(byte)color, (byte)PieceE.Rook] - 2, 0) + Math.Max(board.PieceCount[(byte)color, (byte)PieceE.Queen] - 1, 0) > 8) { return(emptyBoard); } if (board.PieceCount[(byte)color, (byte)PieceE.Bishop] > 1) { Bitboard bishops = occupy & board.Pieces[(byte)PieceE.Bishop]; byte[] bishopCount = new byte[Color.Colors]; //SquareE[] square = BitBoard.GetSquares(occupy & board.Pieces[ (byte) PieceE.Bishop ]); //foreach( SquareE sqr in square ) // ++bishopCount[ (byte) Square._Color(sqr) ]; bishopCount[(byte)ColorE.White] = BitBoard.CountSets(BitBoard.LightSquares & bishops); bishopCount[(byte)ColorE.Black] = BitBoard.CountSets(BitBoard.DarkSquares & bishops); if (board.PieceCount[(byte)color, (byte)PieceE.Pawn] + Math.Max(bishopCount[(byte)ColorE.White] - 1, 0) + Math.Max(bishopCount[(byte)ColorE.Black] - 1, 0) > 8) { return(emptyBoard); } } // check for King byte king = board.PieceCount[(byte)color, (byte)PieceE.King]; if (king != 1) //Illegal King { return(emptyBoard); } } #endregion if (numRecord > 1) { #region Active color string aColor = records[1]; if (string.IsNullOrEmpty(aColor) || aColor.Length != 1) { return(emptyBoard); } char activeColor = char.ToLower(aColor[0]); if (activeColor == 'w') { board.OnMove = ColorE.White; } else if (activeColor == 'b') { board.OnMove = ColorE.Black; } else { board.OnMove = ColorE.NoColor; return(emptyBoard); } #endregion } if (numRecord > 2) { #region Castling privileges string castles = records[2]; if (string.IsNullOrEmpty(castles)) { return(emptyBoard); } if (castles == "-") { board.Castle[(byte)ColorE.White].AnyCastle = false; board.Castle[(byte)ColorE.Black].AnyCastle = false; } else { int length = castles.Length; if (length > 4) { return(emptyBoard); } for (byte i = 0; i < length - 1; ++i) { for (byte j = (byte)(i + 1); j < length; ++j) { if (castles[i] == castles[j]) { return(emptyBoard); } } } foreach (char castle in castles) { switch (castle) { case 'K': { Bitboard occupy = board.Occupies[(byte)ColorE.White]; if (BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.King], SquareE.E1) && BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.Rook], SquareE.H1)) { board.Castle[(byte)ColorE.White].ShortCastle = true; } else { return(emptyBoard); } } break; case 'Q': { Bitboard occupy = board.Occupies[(byte)ColorE.White]; if (BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.King], SquareE.E1) && BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.Rook], SquareE.A1)) { board.Castle[(byte)ColorE.White].LongCastle = true; } else { return(emptyBoard); } } break; case 'k': { Bitboard occupy = board.Occupies[(byte)ColorE.Black]; if (BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.King], SquareE.E8) && BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.Rook], SquareE.H8)) { board.Castle[(byte)ColorE.Black].ShortCastle = true; } else { return(emptyBoard); } } break; case 'q': { Bitboard occupy = board.Occupies[(byte)ColorE.Black]; if (BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.King], SquareE.E8) && BitBoard.GetSquare(occupy & board.Pieces[(byte)PieceE.Rook], SquareE.A8)) { board.Castle[(byte)ColorE.Black].LongCastle = true; } else { return(emptyBoard); } } break; default: return(emptyBoard); } } } #endregion } if (numRecord > 3) { #region EnPassant Target square string epSqr = records[3]; if (string.IsNullOrEmpty(epSqr)) { return(emptyBoard); } if (epSqr == "-") { board.EnPassant = SquareE.NoSquare; } else { if (epSqr.Length != 2) { return(emptyBoard); } char epFile = char.ToLower(epSqr[0]); if (!(epFile >= 'a' && epFile <= 'h')) { return(emptyBoard); } char epRank = epSqr[1]; if (!(epRank == '3' || epRank == '6')) { return(emptyBoard); } if (epRank == '3' && ( board.OnMove != ColorE.Black || !BitBoard.GetSquare(board.Occupies[(byte)ColorE.White] & board.Pieces[(byte)PieceE.Pawn], Square._Square(epFile, (char)(epRank + 1))) ) || epRank == '6' && ( board.OnMove != ColorE.White || !BitBoard.GetSquare(board.Occupies[(byte)ColorE.Black] & board.Pieces[(byte)PieceE.Pawn], Square._Square(epFile, (char)(epRank - 1))) ) ) { return(emptyBoard); } board.EnPassant = Square._Square(epFile, epRank); } #endregion } if (numRecord > 4) { #region HalfMove Clock (Ply) byte halfMoveClock; if (!byte.TryParse(records[4], out halfMoveClock)) { return(emptyBoard); } if (halfMoveClock > 100) { return(emptyBoard); } board.HalfMoveClock = halfMoveClock; #endregion } if (numRecord > 5) { #region FullMove Counter ushort fullMoveCount; if (!ushort.TryParse(records[5], out fullMoveCount)) { return(emptyBoard); } if (fullMoveCount == 0) { fullMoveCount = 1; } board.FullMoveCount = fullMoveCount; #endregion } return(board); }
public static string ToString(SquareE sqr) { return(string.Format("{0}{1}", File.FileNotation(_File(sqr)), Rank.RankNotation(_Rank(sqr)))); }
internal static Bitboard NortExMask(SquareE sqr) { const Bitboard fileA_1 = 0x0101010101010100;//File_A & ~Rank_1; return(fileA_1 << (byte)sqr); }
internal static bool IsValid(SquareE sqr) { return(((byte)sqr & 0xC0) == 0); //((byte) sqr & ~0x3F) == 0; // sqr >= SquareE.A1 && sqr <= SquareE.H8; }
internal static ColorE _Color(SquareE sqr) { return((ColorE)(((byte)_File(sqr) + (byte)_Rank(sqr) + 1) % 2)); }
internal static byte FileIndex(SquareE sqr) { Debug.Assert(Square.IsValid(sqr), "Not 0-3F"); return((byte)((byte)sqr & 0x07)); }
internal const byte Squares = 0x40; //File.Files * Rank.Ranks; #region Old //internal byte Sqr; //internal Piece Piece = default(Piece); //internal FileE File { get { return GetFile(Sqr); } } //internal RankE Rank { get { return GetRank(Sqr); } } //internal Square() //{ //} //internal Square( byte sqr ) //{ // SetSquare(sqr); //} //internal Square( SquareE sqr ) // : this((byte) sqr) //{ //} //internal Square( byte file, byte rank ) //{ // SetFileRank(file, rank); //} //internal Square( FileE file, RankE rank ) // : this((byte) file, (byte) rank) //{ //} //private void SetSquare( byte sqr ) //{ // //Debug.Assert(sqr < Square.Squares); // Sqr = sqr; //} //private void SetFileRank( byte file, byte rank ) //{ // //Debug.Assert(file < M.File.Files); // //Debug.Assert(rank < M.Rank.Ranks); // //SetSquare((byte) ((rank * M.File.Files) + file)); // SetSquare((byte) ((rank << 0x03) + file)); //} //internal bool IsEmpty //{ // get { return Piece == default(Piece); } //} //internal ColorE OccupiedBy //{ // get // { // if( !IsEmpty ) // { // if( Piece.Color == ColorE.White ) // return ColorE.White; // else if( Piece.Color == ColorE.Black ) // return ColorE.Black; // else // return ColorE.NoColor; // } // return ColorE.NoColor; // } //} //internal bool IsOccupiedBy( ColorE color ) //{ // return !IsEmpty && Piece.Color == color; //} //public override string ToString() //{ // return string.Format("{0}{1}", FileNotation, RankNotation); //} #endregion internal static FileE _File(SquareE sqr) { Debug.Assert(IsValid(sqr), "Not 0-3F"); return((FileE)((byte)sqr & 0x07)); }
internal static Bitboard SoutExMask(SquareE sqr) { const Bitboard fileH_8 = 0x0080808080808080;//File_H & ~Rank_8; return(fileH_8 >> ((byte)sqr ^ 0xFF)); }
// TODO:: //internal Bitboard AttacksTo( Bitboard occupied, SquareE sqr, ColorE side ) //{ // //Bitboard knights, kings, bishopsQueens, rooksQueens; // //knights = pieceBB[ nWhiteKnight ] | pieceBB[ nBlackKnight ]; // //kings = pieceBB[ nWhiteKing ] | pieceBB[ nBlackKing ]; // //rooksQueens = // //bishopsQueens = pieceBB[ nWhiteQueen ] | pieceBB[ nBlackQueen ]; // //rooksQueens |= pieceBB[ nWhiteRook ] | pieceBB[ nBlackRook ]; // //bishopsQueens |= pieceBB[ nWhiteBishop ] | pieceBB[ nBlackBishop ]; // //return (arrPawnAttacks[ nWhite ][ sqr ] & pieceBB[ nBlackPawn ]) // // | (arrPawnAttacks[ nBlack ][ sqr ] & pieceBB[ nWhitePawn ]) // // | (arrKnightAttacks[ sqr ] & knights) // // | (arrKingAttacks[ sqr ] & kings) // // | (bishopAttacks(occupied, sqr) & bishopsQueens) // // | (rookAttacks(occupied, sqr) & rooksQueens) // // ; // ColorE oppside = ColorE.NoColor; // if( side == ColorE.White ) // { // oppside = ColorE.Black; // } // else if( side == ColorE.Black ) // { // oppside = ColorE.White; // } // Bitboard sideOccupied = Occupies[ (byte) side ]; // Bitboard rooksQueens = Pieces[ (byte) PieceE.Rook ] | Pieces[ (byte) PieceE.Queen ]; // Bitboard bishopsQueens = Pieces[ (byte) PieceE.Bishop ] | Pieces[ (byte) PieceE.Queen ]; // return (MoveAttack._PawnAttacks[ (byte) sqr, (byte) side ] & (Pieces[ (byte) PieceE.Pawn ] & Occupies[ (byte) oppside ])) // | (MoveAttack._PawnAttacks[ (byte) sqr, (byte) oppside ] & (Pieces[ (byte) PieceE.Pawn ] & Occupies[ (byte) side ])) // | (MoveAttack._KnightMoves[ (byte) sqr ] & Pieces[ (byte) PieceE.Knight ]) // | (MoveAttack._KingMoves[ (byte) sqr ] & Pieces[ (byte) PieceE.King ]) // | (MoveAttack._RookMoves[ (byte) sqr ] & rooksQueens) // | (MoveAttack._BishopMoves[ (byte) sqr ] & bishopsQueens); //} public override string ToString() { StringBuilder sboard = new StringBuilder(); sboard.AppendLine(" +-+-+-+-+-+-+-+-+"); //SquareE begSqr = SquareE.A8; //SquareE endSqr = SquareE.H1; //for( SquareE sqr = begSqr; ; Square.BackwardInc(ref sqr) ) //{ // if( (byte) sqr % File.Files == 0 ) // { // if( sqr != begSqr ) sboard.AppendLine(); // sboard.Append(Rank.mapRank[ (byte) sqr / File.Files ]); // } // bool isPiece = false; // sboard.Append(" "); // for( ColorE color = ColorE.White; color <= ColorE.Black; ++color ) // { // Bitboard occupy = Occupies[ (byte) color ]; // for( PieceE type = PieceE.Pawn; type <= PieceE.King; ++type ) // { // Bitboard piece = Pieces[ (byte) type ]; // if( BitBoard.GetSquare(occupy & piece, sqr) ) // { // //if( isPiece ) sboard.Append('x'); // '*' // isPiece = true; // sboard.Append(Piece.mapPiece[ (byte) color, (byte) type ]); // break; // } // } // } // if( !isPiece ) // sboard.Append("."); // if( sqr == endSqr ) // break; //} for (RankE rank = RankE.Rank_8; ; --rank) { sboard.Append(Rank.mapRank[(byte)rank]); for (FileE file = FileE.File_A; file <= FileE.File_H; ++file) { bool isPiece = false; sboard.Append(" "); for (ColorE color = ColorE.White; color <= ColorE.Black; ++color) { Bitboard occupy = Occupies[(byte)color]; SquareE sqr = Square._Square(file, rank); if (BitBoard.GetSquare(occupy, sqr)) { for (PieceE type = PieceE.Pawn; type <= PieceE.King; ++type) { Bitboard piece = Pieces[(byte)type]; if (BitBoard.GetSquare(piece, sqr)) // occupy & piece { //if( isPiece ) sboard.Append('x'); // '*' isPiece = true; sboard.Append(Piece.mapPiece[(byte)color, (byte)type]); break; } } } } if (!isPiece) { sboard.Append("."); } } if (rank == RankE.Rank_1) { break; } sboard.AppendLine(); } sboard.AppendLine().Append(" +-+-+-+-+-+-+-+-+").AppendLine(); sboard.Append(" "); foreach (char file in File.mapFile) { sboard.Append(" " + file); } return(sboard.ToString()); }
internal static bool GetSquare(Bitboard bb, SquareE sqr) { return((bb & SquareMask(sqr)) != EmptySquares); }
internal static Bitboard DiagA8H1ExMask(SquareE sqr) { return(DiagA8H1Mask(sqr) ^ SquareMask(sqr)); }
internal static Bitboard SetSquare(ref Bitboard bb, SquareE sqr) { return(bb |= SquareMask(sqr)); }
//internal static Bitboard[ , ] _PassedPawnMask; //internal static Bitboard[ , ] _OutpostMask; internal static void InitBitboards() { #region //Constants //byte i; //for( i = 0; i < 0x08; ++i ) //{ // SquaresOfFile[ i ] = SquaresOfRank[ i ] = EmptySquares; //} //for( SquareE sqr = SquareE.A1; sqr <= SquareE.H8; ++sqr ) //{ // SquaresOfFile[ (byte) Square._File(sqr) ] |= _MinValue[ (byte) sqr ]; // SquaresOfRank[ (byte) Square._Rank(sqr) ] |= _MinValue[ (byte) sqr ]; //} //SquaresOfFileRange = new Bitboard[ File.Files, Rank.Ranks ]; //SquaresOfRankRange = new Bitboard[ File.Files, Rank.Ranks ]; //for( i = 0; i < 0x08; ++i ) //{ // SquaresOfLateralFiles[ i ] = SquaresOfLateralRanks[ i ] = EmptySquares; // if( i != (byte) FileE.File_A ) // SquaresOfLateralFiles[ i ] |= SquaresOfFile[ i - 1 ]; // if( i != (byte) FileE.File_H ) // SquaresOfLateralFiles[ i ] |= SquaresOfFile[ i + 1 ]; // if( i != (byte) RankE.Rank_1 ) // SquaresOfLateralRanks[ i ] |= SquaresOfRank[ i - 1 ]; // if( i != (byte) RankE.Rank_8 ) // SquaresOfLateralRanks[ i ] |= SquaresOfRank[ i + 1 ]; // for( byte j = 0; j < 0x08; ++j ) // { // SquaresOfFileRange[ i, j ] = SquaresOfRankRange[ i, j ] = EmptySquares; // for( byte k = 0; k < 0x08; k++ ) // { // if( (k >= i && k <= j) || (k >= j && k <= i) ) // { // SquaresOfFileRange[ i, j ] |= SquaresOfFile[ k ]; // SquaresOfRankRange[ i, j ] |= SquaresOfRank[ k ]; // } // } // } //} //File_NotA = ~SquaresOfFile[ (byte) FileE.File_A ]; //File_NotH = ~SquaresOfFile[ (byte) FileE.File_H ]; //WhiteSideSquares = SquaresOfRank[ (byte) RankE.Rank_1 ] | SquaresOfRank[ (byte) RankE.Rank_2 ] | SquaresOfRank[ (byte) RankE.Rank_3 ] | SquaresOfRank[ (byte) RankE.Rank_4 ]; //BlackSideSquares = SquaresOfRank[ (byte) RankE.Rank_5 ] | SquaresOfRank[ (byte) RankE.Rank_6 ] | SquaresOfRank[ (byte) RankE.Rank_7 ] | SquaresOfRank[ (byte) RankE.Rank_8 ]; //QueenSideSquares = SquaresOfFile[ (byte) FileE.File_A ] | SquaresOfFile[ (byte) FileE.File_B ] | SquaresOfFile[ (byte) FileE.File_C ] | SquaresOfFile[ (byte) FileE.File_D ]; //KingSideSquares = SquaresOfFile[ (byte) FileE.File_E ] | SquaresOfFile[ (byte) FileE.File_F ] | SquaresOfFile[ (byte) FileE.File_G ] | SquaresOfFile[ (byte) FileE.File_H ]; //CenterSquares = MinValue[ (byte) SquareE.D4 ] | MinValue[ (byte) SquareE.D5 ] | MinValue[ (byte) SquareE.E4 ] | MinValue[ (byte) SquareE.E5 ]; //ExpCenterSquares = // (SquaresOfFile[ (byte) FileE.File_C ] | SquaresOfFile[ (byte) FileE.File_D ] | // SquaresOfFile[ (byte) FileE.File_E ] | SquaresOfFile[ (byte) FileE.File_F ]) // & (SquaresOfRank[ (byte) RankE.Rank_3 ] | SquaresOfRank[ (byte) RankE.Rank_4 ] | // SquaresOfRank[ (byte) RankE.Rank_5 ] | SquaresOfRank[ (byte) RankE.Rank_6 ]); //CornerSquares = (BitBoard.File_A | BitBoard.File_H) & (BitBoard.Rank_1 | BitBoard.Rank_8); //BorderSquares = SquaresOfFile[ (byte) FileE.File_A ] | SquaresOfFile[ (byte) FileE.File_H ] | SquaresOfRank[ (byte) RankE.Rank_1 ] | SquaresOfRank[ (byte) RankE.Rank_8 ]; #endregion Bitboard min = 0x01UL; _MinValue = new Bitboard[Square.Squares]; _MaxValue = new Bitboard[Square.Squares]; for (SquareE sqr = SquareE.A1; sqr <= SquareE.H8; ++sqr, min <<= 1) { _MinValue[(byte)sqr] = min; _MaxValue[(byte)sqr] = ~min; } _SetCount = new byte[Max16 + 1]; _RankOverlay = new byte[Max16 + 1]; for (ushort s = 0; ; ++s) { _SetCount[s] = CountSets(s); _RankOverlay[s] = RankOverlay(s); if (s == Max16) { break; } } _BitShiftGap = new byte[Max08 + 1, File.Files]; for (byte occ = 0; ; ++occ) { for (byte file = 0; file < File.Files; ++file) { //_BitShiftGap[ occ, file ] = (byte) (occ == 0 ? 0 : 8); //for( byte index = 0; index < File.Files; ++index ) //{ // if( ((byte) _MinValue[ index ] & occ) != 0 ) // { // byte value = (byte) Math.Abs(file - index); // if( value < _BitShiftGap[ occ, file ] ) // { // _BitShiftGap[ occ, file ] = value; // if( index > file ) // break; // } // } //} if (occ == 0 || ((byte)_MinValue[file] & occ) != 0) { _BitShiftGap[occ, file] = 0; continue; } byte westCount = 8; if (file > 0) // west { westCount = 1; for (byte west = (byte)(file - 1); west != 0 && ((byte)_MinValue[west] & occ) == 0; --west) { //if( west == 0 || ((byte) _MinValue[ west ] & occ) != 0 ) break; ++westCount; } } byte eastCount = 8; if (file < 7) // east { eastCount = 1; for (byte east = (byte)(file + 1); east != 7 && ((byte)_MinValue[east] & occ) == 0; ++east) { //if( east == 7 || ((byte) _MinValue[ east ] & occ) != 0 ) break; ++eastCount; } } _BitShiftGap[occ, file] = Math.Min(westCount, eastCount); } if (occ == Max08) { break; } } //_PassedPawnMask = new Bitboard[ Color.Colors, Square.Squares ]; //_OutpostMask = new Bitboard[ Color.Colors, Square.Squares ]; //for( ColorE color = ColorE.White; color <= ColorE.Black; ++color ) //{ // for( SquareE sqr = SquareE.A1; sqr <= SquareE.H8; ++sqr ) // { // _PassedPawnMask[ (byte) color, (byte) sqr ] = FrontRank(color, sqr) & LateralThisFiles(sqr); // _OutpostMask[ (byte) color, (byte) sqr ] = FrontRank(color, sqr) & LateralFiles(sqr); // } //} }
internal static RankE _Rank(SquareE sqr) { Debug.Assert(IsValid(sqr), "Not 0-3F"); return((RankE)(((byte)sqr >> 3) & 0x07)); }
internal static bool IsSquareOn(Bitboard bb, SquareE sqr) { //return (bb & _MinValue[ (byte) sqr ]) != EmptySquares; return((bb & 0x01UL << (byte)sqr) != EmptySquares); }
internal static Bitboard RstFile(ref Bitboard bb, SquareE sqr) { return(bb &= ~FileMask(sqr)); }