//generate bitboard of moves public static ulong PseudomoveBitboard(int piece, int[] board) { bool isWhite = Util.IsWhite(piece); int position = Util.GetPieceOffset(piece); int positionX = Util.GetXForPosition(position); int positionY = Util.GetYForPosition(position); ulong result = 0; ulong one = 1; if (isWhite) { if (positionY < 6) { if (board[position + 8] == 0) { result |= (one << (position + 8)); } //captures if (positionX > 0) { result |= (one << (position + 7)); } if (positionX < 7) { result |= (one << (position + 9)); } //initial double move if (positionY == 1) { result |= (one << (position + (2 * 8))); } } else if (positionY == 6) { //pawn promotion result |= QueenMoveGenerator.PseudomoveBitboard((PieceTypeFENMap.PieceValue('Q') + position + 8)); if (positionX > 0) { result |= QueenMoveGenerator.PseudomoveBitboard((PieceTypeFENMap.PieceValue('Q') + position + 7)); } if (positionX < 7) { result |= QueenMoveGenerator.PseudomoveBitboard((PieceTypeFENMap.PieceValue('Q') + position + 9)); } } } else { if (positionY > 1) { if (board[position - 8] == 0) { result |= (one << (position - 8)); } //captures if (positionX < 7) { result |= (one << (position - 7)); } if (positionX > 0) { result |= (one << (position - 9)); } //initial double move if (positionY == 6) { result |= (one << (position - (2 * 8))); } } else if (positionY == 1) { //pawn promotion result |= QueenMoveGenerator.PseudomoveBitboard((PieceTypeFENMap.PieceValue('q') + position - 8)); if (positionX < 7) { result |= QueenMoveGenerator.PseudomoveBitboard((PieceTypeFENMap.PieceValue('q') + position - 7)); } if (positionX > 0) { result |= QueenMoveGenerator.PseudomoveBitboard((PieceTypeFENMap.PieceValue('q') + position - 9)); } } } return(result); }
public Game(string fen) { _theBoard = new int[64]; history = new Stack <Move>(); //split the sections of the FEN string with spaces string[] fenParts = fen.Trim().Split(' '); //first part is for piece positions if (fenParts.Length > 0) { int[] positions = new int[64]; int index = 0; //rows are delimited by / //Row order reversed because the convention I am using is bottom-left=0,0, but FEN starts with rank 8 for some stupid reason string[] positionRows = fenParts[0].Trim().Split('/').Reverse().ToArray(); for (int y = 0; y < 8; y++) { string row = positionRows[y]; //and we have to reverse the row itself too. char[] charArray = row.ToCharArray(); row = new string(charArray); for (int x = 0; x < row.Length; x++) { //if we see a number, that means n spots are empty in this row, skip over them if (char.IsNumber(row[x])) { //-'0' char trick to offset ascii number index += row[x] - '0'; } else { positions[index] = (PieceTypeFENMap.PieceValue(row[x]) + index); index++; } } } _theBoard = positions; } if (fenParts.Length > 1) { if (fenParts[1] == "b") { _whiteToMove = false; } } if (fenParts.Length > 2) { if (!fenParts[2].Contains("K")) { _whiteOOCastle = false; } if (!fenParts[2].Contains("Q")) { _whiteOOOCastle = false; } if (!fenParts[2].Contains("k")) { _blackOOCastle = false; } if (!fenParts[2].Contains("q")) { _blackOOOCastle = false; } } if (fenParts.Length > 3 && fenParts[3][0] != '-') { //file + (8 * rank) //ascii offset -'1' instead of -'0' because FEN is 1 indexed instead of 0 indexed _enPassantSquare = (Util.FileToInt(fenParts[3][0]) + (8 * (fenParts[3][1] - '1'))); } foreach (int p in _theBoard) { if (Util.IsWhiteKing(p)) { whiteKing = p; } else if (Util.IsBlackKing(p)) { blackKing = p; } } }
//generate real moves based on board state public static List <int> PossiblePositions(int piece, int[] board) { bool isWhite = Util.IsWhite(piece); List <int> tempResult = new List <int>(); List <int> result = new List <int>(); int position = Util.GetPieceOffset(piece); int depositionedPiece = Util.DepositionPiece(piece); int positionX = Util.GetXForPosition(position); int positionY = Util.GetYForPosition(position); if (isWhite) { if (positionY < 6) { if (board[position + 8] == 0) { result.Add((piece + 8)); } //captures if (positionX > 0 && board[position + 7] > 0 && Util.IsWhite(board[position + 7]) != isWhite) { result.Add((piece + 7)); } if (positionX < 7 && board[position + 9] > 0 && Util.IsWhite(board[position + 9]) != isWhite) { result.Add((piece + 9)); } if (positionY == 1) { if (board[position + 8] == 0 && board[position + (2 * 8)] == 0) { result.Add((piece + (2 * 8))); } } } else if (positionY == 6) { //pawn promotion if (board[position + 8] == 0) { result.Add((PieceTypeFENMap.PieceValue('Q') + position + 8)); } if (positionX > 0 && board[position + 7] > 0 && Util.IsWhite(board[position + 7]) != isWhite) { result.Add((PieceTypeFENMap.PieceValue('Q') + position + 7)); } if (positionX < 7 && board[position + 7] > 0 && Util.IsWhite(board[position + 9]) != isWhite) { result.Add((PieceTypeFENMap.PieceValue('Q') + position + 9)); } } } else { if (positionY > 1) { if (board[position - 8] == 0) { result.Add((piece - 8)); } if (positionX < 7 && board[position - 7] > 0 && Util.IsWhite(board[position - 7]) != isWhite) { result.Add((piece - 7)); } if (positionX > 0 && board[position - 9] > 0 && Util.IsWhite(board[position - 9]) != isWhite) { result.Add((piece - 9)); } if (positionY == 6) { if (board[position - 8] == 0 && board[position - (2 * 8)] == 0) { result.Add((piece - (2 * 8))); } } } else if (positionY == 1) { //pawn promotion if (board[position - 8] == 0) { result.Add((PieceTypeFENMap.PieceValue('q') + position - 8)); } if (positionX < 7 && board[position - 7] > 0 && Util.IsWhite(board[position - 7]) != isWhite) { result.Add((PieceTypeFENMap.PieceValue('q') + position - 7)); } if (positionX > 0 && board[position - 9] > 0 && Util.IsWhite(board[position - 9]) != isWhite) { result.Add((PieceTypeFENMap.PieceValue('q') + position - 9)); } } } return(result); }