Exemple #1
0
        /*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());
        }
Exemple #2
0
        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) { }
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        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));
        }
Exemple #5
0
        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]);
                }
            }
        }
Exemple #6
0
        /// <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;
                }
            }
        }
Exemple #7
0
        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);
        }