/*private bool AreKingsTouching(State s) * { * var x1 = s.PieceLocation[0] % 8; * var y1 = s.PieceLocation[0] >> 3; * * var x2 = s.PieceLocation[2] % 8; * var y2 = s.PieceLocation[2] >> 3; * * return (Math.Abs(x1 - x2) <= 1 && Math.Abs(y1 - y2) <= 1); * }*/ /// <summary> /// Gets all moves that a piece can make that will RESULT IN the given position. /// All pieces can reverse their own move, so backwards move are the same as forwards /// except for pawns, they only move one way. /// </summary> /// <param name="b"></param> /// <param name="playerColor"></param> /// <returns></returns> private unsafe byte[][] GetMovesReverse(BoardStruct *b, byte playerColor) { var moves = new List <byte[]>(); byte[] locations = null; if (playerColor == Board.COLOR_WHITE) { locations = Bitboard.Bitboard_BitList(b->Boards[Board.BOARD_WHITE]); } else { locations = Bitboard.Bitboard_BitList(b->Boards[Board.BOARD_BLACK]); } for (byte i = 0; i < locations.Length; i++) { var to = locations[i]; var pieceMoves = Moves.GetMoves(b, to); // filter out all captures.. remember, this is in reverse! pieceMoves = pieceMoves & ~(b->Boards[Board.BOARD_WHITE] | b->Boards[Board.BOARD_BLACK]); var sources = Bitboard.Bitboard_BitList(pieceMoves); for (int j = 0; j < sources.Length; j++) { moves.Add(new byte[] { sources[j], to }); } } return(moves.ToArray()); }
protected override unsafe void OnMouseClick(MouseEventArgs e) { try { int x = (e.X / TileSize); int y = 7 - (e.Y / TileSize); int index = x + y * 8; if (index == SelectedTile) { SelectedTile = -1; } else { SelectedTile = index; } if (SelectedTile != -1 && State[SelectedTile] > 0) { Move *moveList = stackalloc Move[100]; ulong moves = Moves.GetMoves((BoardStruct *)BoardStruct, SelectedTile); MoveArray = Bitboard.Bitboard_BitList(moves).Select(n => (int)n).ToArray(); } else { MoveArray = new int[0]; } RefreshBuffer(); } catch (Exception) { } }
public void TestBitList2() { ulong val = (ulong)0xC430044A20001204; var list = Bitboard.Bitboard_BitList(val); var list2 = new byte[] { 2, 9, 12, 29, 33, 35, 38, 42, 52, 53, 58, 62, 63 }.Select(x => Convert.ToByte(x)).ToList(); Assert.IsTrue(list2.SequenceEqual(list)); }
public void TestBitList() { ulong val = (ulong)0xC004003000020003; var list = Bitboard.Bitboard_BitList(val); var list2 = new byte[] { 0, 1, 17, 36, 37, 50, 62, 63 }.Select(x => Convert.ToByte(x)).ToList(); Assert.IsTrue(list2.SequenceEqual(list)); }
public void TestBishopMovesAll() { for (int i = 0; i < 64; i++) { var b = new Chess.Base.Board(false); b.State[i] = Chess.Base.Colors.Val(Chess.Base.Piece.Bishop, Chess.Base.Color.White); var movesBasic = Chess.Base.Moves.GetMoves(b, i); movesBasic = movesBasic.OrderBy(x => x).ToArray(); var movesFast = Bishop.Read(i, 0); var list = Bitboard.Bitboard_BitList(movesFast); list = list.OrderBy(x => x).ToArray(); Assert.AreEqual(movesBasic.Length, list.Length); for (int j = 0; j < movesBasic.Length; j++) { Assert.AreEqual((int)movesBasic[j], (int)list[j]); } } }
/// <summary> /// Checks a position and determines if black is mated /// </summary> /// <param name="state"></param> /// <param name="b"></param> public void CheckIfMate(State state, BoardStruct *b) { SetupBoard(b, state, Board.COLOR_BLACK); var from = state.PieceLocation[2]; var moveBoard = Moves.GetMoves(b, from); var moves = Bitboard.Bitboard_BitList(moveBoard); // make sure the black king can't directly attack the white king, that's an illegal position if (AreKingsTouching(b)) { return; } bool isMate = true; for (int j = 0; j < moves.Length; j++) { var valid = Board.Make(b, from, moves[j]); if (valid) { Board.Unmake(b); isMate = false; break; } } if (isMate) { if (Board.IsChecked(b, Board.COLOR_BLACK) == 1) { state.DepthToMate = 0; } else { state.DepthToMate = STALEMATE; } } }
public List <State> CalculateBlack(List <State> stateSet) { // find only moves where black MUST move to a state in the stateSet var newStates = new List <State>(); var b = Board.Create(); foreach (var state in stateSet) { var originalHash = state.Hash; state.PlayerTurn = Board.COLOR_BLACK; state.Hash = CalcHash(state); SetupBoard(b, state, Board.COLOR_BLACK); var moves = GetMovesReverse(b, Board.COLOR_BLACK); for (int i = 0; i < moves.Length; i++) { var from = moves[i][0]; var to = moves[i][1]; // set player to black and set the position to the "precursor" state state.PlayerTurn = Board.COLOR_BLACK; MovePieceState(state, to, from); SetupBoard(b, state, Board.COLOR_BLACK); b->CurrentMove = 0; if (AreKingsTouching(b)) { // revert the state back to the original state state.PlayerTurn = Board.COLOR_WHITE; MovePieceState(state, from, to); continue; } // get moves from precursor state to any other available states var moveBitboard = Moves.GetMoves(b, from); var movesFromPreviousPos = Bitboard.Bitboard_BitList(moveBitboard); // We see if there is a way for black to get out of a forced mate by looking // for any moves that escape it. If white has a forced mate, the input state (original state) // is supposedly the best move black could make. // IF black can make moves tho states that aren't already explored, then they lead to a better // state for black, thus he can escape bool canEscape = false; for (int j = 0; j < movesFromPreviousPos.Length; j++) { var backTo = movesFromPreviousPos[j]; var valid = Board.Make(b, from, backTo); if (valid) { Board.Unmake(b); // Check if this is a capture. We can't "un-capture" pieces so this would be a way out // for black. if (Bitboard.Get(b->Boards[Board.BOARD_WHITE], backTo)) { canEscape = true; break; } // find the hash for the next possible state state.PlayerTurn = Board.COLOR_WHITE; MovePieceState(state, from, backTo); var nextHash = state.Hash; state.PlayerTurn = Board.COLOR_BLACK; MovePieceState(state, backTo, from); // check if that is a known position if (!States.ContainsKey(nextHash)) { canEscape = true; break; } } } // If black can not escape the then moving to the original state is the best option black has. if (!canEscape) { var newState = new State(state); newState.NextState = originalHash; newState.DepthToMate++; newStates.Add(newState); } // revert the state back to the original state state.PlayerTurn = Board.COLOR_WHITE; MovePieceState(state, from, to); } // We messed with the state... alot. // Make sure there isn't a bug in the code and we just corrupted something :) if (originalHash != state.Hash) { throw new Exception("State was altered"); } } Board.Delete(b); return(newStates); }