def perft(board, depth):
    """
    Returns the number of nodes (depth)-ply deep from the given (board).

    Parameters
    ----------
    board : Board
        the board to search nodes from
    depth : int
        the depth to search nodes for

    Returns
    -------
    int
        the number of nodes (depth)-ply deep from the given (board).
    """
    # check for terminal node (i.e. checkmate, stalemate)
    moves = board.move_gen()
    if len(moves) == 0:
        return 0

    if depth == 1:
        return len(board.move_gen())
    if depth == 0:
        return 1

    nodes = 0
    for move in moves:
        captured_piece, castling, ep_square, half_move_count = board.make_move(move)
        nodes += perft(board, depth-1)
        board.undo_move(move, captured_piece, castling, ep_square, half_move_count)

    return nodes