Beispiel #1
0
        /// <summary>
        /// Calculate and return the boards fitness value.
        /// </summary>
        /// <param name="max">Who's side are we viewing from.</param>
        /// <returns>The board fitness value, what else?</returns>
        public int fitness(Player max)
        {
            int fitness = 0;

            int[] blackPieces = { 0, 0, 0, 0, 0, 0 };
            int[] whitePieces = { 0, 0, 0, 0, 0, 0 };
            int   blackMoves  = 0;
            int   whiteMoves  = 0;

            // sum up the number of moves and pieces
            foreach (position_t pos in Pieces[Player.BLACK])
            {
                blackMoves += LegalMoveSet.getLegalMove(this, pos).Count;
                blackPieces[(int)Grid[pos.number][pos.letter].piece]++;
            }

            // sum up the number of moves and pieces
            foreach (position_t pos in Pieces[Player.WHITE])
            {
                whiteMoves += LegalMoveSet.getLegalMove(this, pos).Count;
                whitePieces[(int)Grid[pos.number][pos.letter].piece]++;
            }

            // if viewing from black side
            if (max == Player.BLACK)
            {
                // apply weighting to piece counts
                for (int i = 0; i < 6; i++)
                {
                    fitness += pieceWeights[i] * (blackPieces[i] - whitePieces[i]);
                }

                // apply move value
                fitness += (int)(0.5 * (blackMoves - whiteMoves));
            }
            else
            {
                // apply weighting to piece counts
                for (int i = 0; i < 6; i++)
                {
                    fitness += pieceWeights[i] * (whitePieces[i] - blackPieces[i]);
                }

                // apply move value
                fitness += (int)(0.5 * (whiteMoves - blackMoves));
            }

            return(fitness);
        }
Beispiel #2
0
        /// <summary>
        /// Get all legal moves for the player on the current board.
        /// </summary>
        /// <param name="b">The state of the game.</param>
        /// <param name="player">The player whose moves you want.</param>
        /// <returns>A 1-to-many dictionary of moves from one position to many</returns>
        public static Dictionary <position_t, List <position_t> > getPlayerMoves(ChessBoard b, Player player)
        {
            Dictionary <position_t, List <position_t> > moves = new Dictionary <position_t, List <position_t> >();

            foreach (position_t pos in b.Pieces[player])
            {
                if (b.Grid[pos.number][pos.letter].piece != Piece.NONE)
                {
                    if (!moves.ContainsKey(pos))
                    {
                        moves[pos] = new List <position_t>();
                    }
                    moves[pos].AddRange(LegalMoveSet.getLegalMove(b, pos));
                }
            }
            return(moves);
        }
Beispiel #3
0
        public List <position_t> Select(position_t pos)
        {
            // has previously selected something
            if (this.Board.Grid[this.Selection.number][this.Selection.letter].piece != Piece.NONE &&
                this.Turn == this.Board.Grid[this.Selection.number][this.Selection.letter].player &&
                (this.m_nPlayers == 2 ||
                 this.Turn == Player.WHITE))
            {
                // get previous selections moves and determine if we chose a legal one by clicking
                List <position_t> moves = LegalMoveSet.getLegalMove(this.Board, this.Selection);
                foreach (position_t move in moves)
                {
                    if (move.Equals(pos))
                    {
                        // we selected a legal move so update the board
                        MakeMove(new move_t(this.Selection, pos));

                        // If piece that was just moved is a king and it moved anyhthing other than 1 square, it was
                        // a castling move, so we need to move the rook
                        if (this.Board.Grid[pos.number][pos.letter].piece == Piece.KING && Math.Abs(pos.letter - this.Selection.letter) == 2)
                        {
                            int row = (this.Turn == Player.WHITE) ? 0 : 7;

                            // Left rook
                            if (pos.letter < 4)
                            {
                                LegalMoveSet.move(this.Board, new move_t(new position_t(0, row), new position_t(3, row)));
                            }
                            // right rook
                            else
                            {
                                LegalMoveSet.move(this.Board, new move_t(new position_t(7, row), new position_t(5, row)));
                            }
                        }

                        // finish move
                        switchPlayer();
                        if (detectCheckmate())
                        {
                            return(new List <position_t>());
                        }

                        if (this.m_nPlayers == 1)         // start ai
                        {
                            new Thread(AISelect).Start(); // thread turn
                        }
                        return(new List <position_t>());
                    }
                }
            }

            // first click, let's show possible moves
            if (this.Board.Grid[pos.number][pos.letter].player == this.Turn && (this.m_nPlayers == 2 || this.Turn == Player.WHITE))
            {
                List <position_t> moves = LegalMoveSet.getLegalMove(this.Board, pos);
                this.Selection = pos;
                return(moves);
            }

            // reset
            this.Selection = new position_t();
            return(new List <position_t>());
        }
Beispiel #4
0
        private static int mimaab(ChessBoard board, Player turn, int depth, int alpha, int beta)
        {
            // base case, at maximum depth return board fitness
            if (depth >= DEPTH)
            {
                return(board.fitness(MAX));
            }
            else
            {
                List <ChessBoard> boards = new List <ChessBoard>();

                // get available moves / board states from moves for the current player
                foreach (position_t pos in board.Pieces[turn])
                {
                    if (STOP)
                    {
                        return(-1);      // interupts
                    }
                    List <position_t> moves = LegalMoveSet.getLegalMove(board, pos);
                    foreach (position_t move in moves)
                    {
                        if (STOP)
                        {
                            return(-1);      // interupts
                        }
                        ChessBoard b2 = LegalMoveSet.move(board, new move_t(pos, move));
                        boards.Add(b2);
                    }
                }

                int a = alpha, b = beta;
                if (turn != MAX) // minimize
                {
                    foreach (ChessBoard b2 in boards)
                    {
                        if (STOP)
                        {
                            return(-1);      // interupt
                        }
                        b = Math.Min(b, mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, depth + 1, a, b));
                        if (a >= b)
                        {
                            return(a);
                        }
                    }
                    return(b);
                }
                else // maximize
                {
                    foreach (ChessBoard b2 in boards)
                    {
                        if (STOP)
                        {
                            return(-1);      // interupt
                        }
                        a = Math.Max(a, mimaab(b2, (turn == Player.WHITE) ? Player.BLACK : Player.WHITE, depth + 1, a, b));
                        if (a >= b)
                        {
                            return(b);
                        }
                    }
                    return(a);
                }
            }
        }