A simple pipeline can adjust raw readings and clamp each derived value before reporting.

Program

Play the program to choose an offset and watch each score pass through the same transform.

normalize_scores_pipeline.f90
program normalize_scores_pipeline_demo
    implicit none
    integer :: raw(3)
    integer :: offset
    integer :: normalized(3)
    integer :: i

    raw = [2, 5, 9]
    offset = 
    do i = 1, 3
        normalized(i) = max(0, raw(i) + offset)
    end do
    print '(I0, 1X, I0, 1X, I0)', normalized(1), normalized(2), normalized(3)
end program normalize_scores_pipeline_demo
program normalize_scores_pipeline_demo
    implicit none
    integer :: raw(3)
    integer :: offset
    integer :: normalized(3)
    integer :: i

    raw = [2, 5, 9]
    offset = 
    do i = 1, 3
        normalized(i) = max(0, raw(i) + offset)
    end do
    print '(I0, 1X, I0, 1X, I0)', normalized(1), normalized(2), normalized(3)
end program normalize_scores_pipeline_demo
program normalize_scores_pipeline_demo
    implicit none
    integer :: raw(3)
    integer :: offset
    integer :: normalized(3)
    integer :: i

    raw = [2, 5, 9]
    offset = 
    do i = 1, 3
        normalized(i) = max(0, raw(i) + offset)
    end do
    print '(I0, 1X, I0, 1X, I0)', normalized(1), normalized(2), normalized(3)
end program normalize_scores_pipeline_demo
transform Each raw reading is adjusted by the same offset.
clamp `max(0, raw(i) + offset)` prevents negative normalized scores.
pipeline The loop applies one transformation step to every element.