コード例 #1
0
ファイル: Program.cs プロジェクト: adh2050/Chess
 public State(State copy)
 {
     Hash = copy.Hash;
     NextState = copy.NextState;
     DepthToMate = copy.DepthToMate;
     PlayerTurn = copy.PlayerTurn;
     Pieces = new byte[] { copy.Pieces[0], copy.Pieces[1], copy.Pieces[2], copy.Pieces[3] };
     PieceLocation = new byte[] { copy.PieceLocation[0], copy.PieceLocation[1], copy.PieceLocation[2], copy.PieceLocation[3] };
 }
コード例 #2
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        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;
        }
コード例 #3
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        private unsafe void SetupBoard(BoardStruct* b, State state, byte playerTurn)
        {
            b->Boards[0] = 0;
            b->Boards[1] = 0;
            b->Boards[2] = 0;
            b->Boards[3] = 0;
            b->Boards[4] = 0;
            b->Boards[5] = 0;
            b->Boards[6] = 0;
            b->Boards[7] = 0;
            b->Castle = 0;
            b->EnPassantTile = 0;
            b->Hash = 0;
            Board.SetPiece(b, state.PieceLocation[0], state.Pieces[0] & 0x0F, state.Pieces[0] & 0xF0);
            Board.SetPiece(b, state.PieceLocation[1], state.Pieces[1] & 0x0F, state.Pieces[1] & 0xF0);
            Board.SetPiece(b, state.PieceLocation[2], state.Pieces[2] & 0x0F, state.Pieces[2] & 0xF0);
            Board.SetPiece(b, state.PieceLocation[3], state.Pieces[3] & 0x0F, state.Pieces[3] & 0xF0);
            b->AttacksBlack = Board.AttackMap(b, Board.COLOR_BLACK);
            b->AttacksWhite = Board.AttackMap(b, Board.COLOR_WHITE);

            b->PlayerTurn = playerTurn;
            b->Hash = b->Hash ^ Zob.Keys[Zobrist.ZOBRIST_SIDE, b->PlayerTurn];

            Assert(b->Hash == state.Hash, "Hashes do not match");
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        private List<State> Generate4PieceMates(byte[] pieces)
        {
            var b = Board.Create();
            var states = new List<State>();

            byte p0 = pieces[0];
            byte p1 = pieces[1];
            byte p2 = pieces[2];

            int i = 0;

            for (byte l0 = 0; l0 < 64; l0++)
                for (byte l1 = 0; l1 < 64; l1++)
                    for (byte l2 = 0; l2 < 64; l2++)
                        for (byte l3 = 0; l3 < 64; l3++)
                            if (l0 != l1 && l0 != l2 && l0 != l3 && l1 != l2 && l1 != l3 && l2 != l3)
                            {
                                var state = new State();
                                state.Pieces = new byte[4];
                                state.PieceLocation = new byte[4];
                                state.PlayerTurn = Board.COLOR_BLACK;

                                // set pieces
                                state.Pieces[0] = p0;
                                state.PieceLocation[0] = l0;
                                state.Pieces[1] = p1;
                                state.PieceLocation[1] = l1;
                                state.Pieces[2] = p2;
                                state.PieceLocation[2] = l2;
                                state.Pieces[3] = p2;
                                state.PieceLocation[3] = l2;

                                state.DepthToMate = MAX; // set to max
                                state.Hash = CalcHash(state);
                                CheckIfMate(state, b);

                                if (state.DepthToMate != 255)
                                    states.Add(state);

                                i++;
                            }

            Assert(i == 64 * 63 * 62);

            Board.Delete(b);
            var mateCount = states.Count(x => x.DepthToMate == 0);
            var stalemateCount = states.Count(x => x.DepthToMate == STALEMATE);

            return states;
        }
コード例 #5
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        /*private bool IsValidState(State state)
        {
            SetupBoard(bs, state, state.PlayerTurn);
            if(AreKingsTouching(bs))
                return false;

            var oppositePlayer = (state.PlayerTurn == Board.COLOR_WHITE) ? Board.COLOR_BLACK : Board.COLOR_WHITE;

            if(Board.IsChecked(bs, oppositePlayer) == 1)
                return false;

            return true;
        }*/
        private bool Compare(State state1, State state2)
        {
            var a = state1.PieceLocation[0] == state2.PieceLocation[0];
            var b = state1.PieceLocation[1] == state2.PieceLocation[1];
            var c = state1.PieceLocation[2] == state2.PieceLocation[2];
            var d = true;

            if(state1.Pieces[3] != 0 && state2.Pieces[3] != 0)
                d = state1.PieceLocation[3] == state2.PieceLocation[3];

            var e = state1.PlayerTurn == state2.PlayerTurn;

            return a & b & c & d & e;
        }
コード例 #6
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        /// <summary>
        /// Calculate hash of position after a move
        /// </summary>
        /// <param name="state"></param>
        /// <param name="moveFrom"></param>
        /// <param name="moveTo"></param>
        /// <returns></returns>
        private ulong CalcHash(State state, byte moveFrom, byte moveTo)
        {
            if (state.PieceLocation[0] == moveFrom)
                state.PieceLocation[0] = moveTo;
            if (state.PieceLocation[1] == moveFrom)
                state.PieceLocation[1] = moveTo;
            if (state.PieceLocation[2] == moveFrom)
                state.PieceLocation[2] = moveTo;
            if (state.PieceLocation[3] == moveFrom)
                state.PieceLocation[3] = moveTo;

            var hash = CalcHash(state);

            if (state.PieceLocation[0] == moveTo)
                state.PieceLocation[0] = moveFrom;
            if (state.PieceLocation[1] == moveTo)
                state.PieceLocation[1] = moveFrom;
            if (state.PieceLocation[2] == moveTo)
                state.PieceLocation[2] = moveFrom;
            if (state.PieceLocation[3] == moveTo)
                state.PieceLocation[3] = moveFrom;

            return hash;
        }
コード例 #7
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        private ulong CalcHash(State state)
        {
            ulong hash = 0;
            hash ^= Zob.Keys[Zob.Index[state.Pieces[0]], state.PieceLocation[0]];
            hash ^= Zob.Keys[Zob.Index[state.Pieces[1]], state.PieceLocation[1]];
            hash ^= Zob.Keys[Zob.Index[state.Pieces[2]], state.PieceLocation[2]];

            if(state.Pieces[3] != 0)
                hash ^= Zob.Keys[Zob.Index[state.Pieces[3]], state.PieceLocation[3]];

            hash ^= Zob.Keys[Zobrist.ZOBRIST_SIDE, state.PlayerTurn];
            return hash;
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        public bool QueryStates(byte[] pieces)
        {
            Console.Write("Query Position (wK, wQ, bK):");
            var line = Console.ReadLine();
            if (line == "quit" || line == "exit")
                return false;

            var locations = line.Split(',').Select(x => Convert.ToByte(x.Trim())).ToArray();
            var stateTemp = new State();
            stateTemp.PieceLocation = locations;
            stateTemp.Pieces = pieces;
            stateTemp.PlayerTurn = Board.COLOR_WHITE;
            var hash = CalcHash(stateTemp);

            State state = null;

            if (States.ContainsKey(hash))
                state = States[hash];

            Console.WriteLine("Hash: " + state.Hash);
            Console.WriteLine("Depth to Mate: " + state.DepthToMate);
            Console.WriteLine("Position: " + state.PieceLocation[0] + ", " + state.PieceLocation[1] + ", " + state.PieceLocation[2] + ", " + state.PieceLocation[3]);

            if (States.ContainsKey(state.NextState))
            {
                var next = States[state.NextState];
                Console.WriteLine("Next Position: " + next.PieceLocation[0] + ", " + next.PieceLocation[1] + ", " + next.PieceLocation[2] + ", " + next.PieceLocation[3]);
            }

            Console.WriteLine("");
            return true;
        }
コード例 #9
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        public void MovePieceState(State state, byte moveFrom, byte moveTo)
        {
            if (state.PieceLocation[0] == moveFrom)
                state.PieceLocation[0] = moveTo;
            if (state.PieceLocation[1] == moveFrom)
                state.PieceLocation[1] = moveTo;
            if (state.PieceLocation[2] == moveFrom)
                state.PieceLocation[2] = moveTo;
            if (state.PieceLocation[3] == moveFrom)
                state.PieceLocation[3] = moveTo;

            state.Hash = CalcHash(state);
        }
コード例 #10
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        public byte[] GetMove(State a, State b)
        {
            if (a.PieceLocation[0] != b.PieceLocation[0])
                return new byte[] { a.PieceLocation[0], b.PieceLocation[0] };
            if (a.PieceLocation[1] != b.PieceLocation[1])
                return new byte[] { a.PieceLocation[1], b.PieceLocation[1] };
            if (a.PieceLocation[2] != b.PieceLocation[2])
                return new byte[] { a.PieceLocation[2], b.PieceLocation[2] };
            if (a.PieceLocation[3] != b.PieceLocation[3])
                return new byte[] { a.PieceLocation[3], b.PieceLocation[3] };

            return new byte[2]; // no move
        }
コード例 #11
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        /// <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;
            }
        }
コード例 #12
0
ファイル: Program.cs プロジェクト: adh2050/Chess
        public List<State> CalculateWhite(List<State> stateSet)
        {
            // find all states where white can transition from a state into one of the input states in stateSet

            var newStates = new List<State>();
            var b = Board.Create();

            foreach(var state in stateSet)
            {
                var originalHash = state.Hash;

                state.PlayerTurn = Board.COLOR_WHITE;
                state.Hash = CalcHash(state);
                SetupBoard(b, state, Board.COLOR_WHITE);
                var moves = GetMovesReverse(b, Board.COLOR_WHITE);

                for (int i = 0; i < moves.Length; i++)
                {
                    var from = moves[i][0];
                    var to = moves[i][1];

                    // set player to white and set the position to the "precursor" state
                    state.PlayerTurn = Board.COLOR_WHITE;
                    MovePieceState(state, to, from);
                    SetupBoard(b, state, Board.COLOR_WHITE);
                    b->CurrentMove = 0;

                    // we must see the the position we are moving from already had black in check
                    // Such a position could never actually occur, since can't enter check by himself
                    bool wasChecked = Board.IsChecked(b, Board.COLOR_BLACK) == 1;

                    if (!wasChecked)
                    {
                        var valid = Board.Make(b, from, to);

                        if (valid)
                        {
                            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_BLACK;
                    MovePieceState(state, from, to);
                }

                if (originalHash != state.Hash)
                    throw new Exception("State was altered");
            }

            Board.Delete(b);
            return newStates;
        }