예제 #1
0
    /** Return a heuristic value for BOARD. This can be improved. */
    private int StaticScore(Board board)
    {
        BoardStatus status = board.status;

        if (status == BoardStatus.Checkmate)
        {
            if (board.whoseTurn == PieceColor.White)
            {
                return(WIN_VALUE);
            }
            else
            {
                return(-WIN_VALUE);
            }
        }
        else if (status != BoardStatus.Playing) // AI shouldn't need to think about the promote state
        {
            return(0);
        }

        // TODO: quantify threats
        int score = 0;

        foreach (Square s in Square.squares)
        {
            PieceData?p = board.GetPiece(s);
            if (p == null)
            {
                continue;
            }

            PieceType type = p.Value.type;
            if (type == PieceType.King)
            {
                continue;
            }

            if (p.Value.color == PieceColor.White)
            {
                score += PIECE_VALUES[(int)type];
            }
            else
            {
                score -= PIECE_VALUES[(int)type];
            }
        }

        return(score);
    }
예제 #2
0
    private IEnumerator <int?> FindMove(Board board, int depth, bool saveMove, bool max, int alpha, int beta)
    {
        BoardStatus status = board.status;

        if (depth == 0 || (status != BoardStatus.Playing)) // AI shouldn't need to think about the promote state
        {
            yield return(StaticScore(board));

            yield break;
        }

        List <Move> moves = new List <Move>(board.legalMoves);

        if (saveMove)
        {
            Shuffle(moves);
        }

        if (max)
        {
            int bestVal = -INFINITY;
            foreach (Move move in moves)
            {
                board.MakeMove(move);
                int moveVal = 0;
                IEnumerator <int?> enumerator = FindMove(board, depth - 1, false, false, alpha, beta);
                yield return(null);

                while (enumerator.MoveNext())
                {
                    if (enumerator.Current != null)
                    {
                        moveVal = enumerator.Current.Value;
                    }
                    yield return(null);
                }
                bestVal = Math.Max(bestVal, moveVal);
                board.Undo();

                if (bestVal > beta) // prune; black would never let this happen
                {
                    yield return(bestVal);

                    yield break;
                }

                if (bestVal > alpha) // this is the best option for white on the path to root (overall)
                {
                    alpha = bestVal;
                    if (saveMove)
                    {
                        foundMove = move;
                    }
                }
            }
            yield return(bestVal); // the best (maximal) value for white from this board position (not necessarily overall)
        }
        else
        {
            int bestVal = INFINITY;
            foreach (Move move in moves)
            {
                board.MakeMove(move);
                int moveVal = 0;
                IEnumerator <int?> enumerator = FindMove(board, depth - 1, false, true, alpha, beta);
                yield return(null);

                while (enumerator.MoveNext())
                {
                    if (enumerator.Current != null)
                    {
                        moveVal = enumerator.Current.Value;
                    }
                    yield return(null);
                }
                bestVal = Math.Min(bestVal, moveVal);
                board.Undo();

                if (bestVal < alpha) // prune; white would never let this happen
                {
                    yield return(bestVal);

                    yield break;
                }

                if (bestVal < beta) // this is the best option for black on the path to root (overall)
                {
                    beta = bestVal;
                    if (saveMove)
                    {
                        foundMove = move;
                    }
                }
            }
            yield return(bestVal); // the best (minimal) value for black from this board position (not necessarily overall)
        }
    }