%% Lab 4 -- Trials and Tribble-ations
%% Warm up round
% After you've familiarized yourself with the basic setup in the pre-lab (where everything is working correctly), the technician insist that you practice a few times to to show you know what you are doing.
% He tells you: "You should be able to use no more than 10 scans for a building this size."
% (Select the code-block below, hit Ctrl-Enter or Cmd-Enter to run the game. It may help to use the Supplementary Handout to keep track of your progress.)

% Find the tribble and irradiate it!
tribble = 800*rand;
DlgTtl = 'Find the tribble!';
ctltkn = 0;
DefaultOpts.Interpreter='tex';
DefaultOpts.WindowStyle='modal';
DefaultOpts.Default='Scan';
while ctltkn==0
    UserResponse = inputdlg('Where in [0,800] do you want to scan? (type in your response as two numbers separated by a comma. If you want to scan between the 100 ft and 300 ft marks, type in "100,300".)', DlgTtl, 1, {''}, DefaultOpts);
    [ScanRange, Sanity] = str2num(UserResponse{1});
    if Sanity && (length(ScanRange)==2)
        ctltkn=1;
        ScanRange = sort(ScanRange);
    else
        ErrorDia = errordlg('Error parsing input, make sure entry is comma separate list of two numbers.', DlgTtl, DefaultOpts);
        uiwait(ErrorDia);
    end
end

gameend = 0;
while gameend==0
    if (tribble >= ScanRange(1)) && (tribble <= ScanRange(2))
        ScanResult = strcat('Tribble is in range scanned:',num2str(ScanRange))
    else
        ScanResult = strcat('Tribble is NOT in range scanned:' , num2str(ScanRange))
    end
    NextMove = questdlg({'The technician reports:';ScanResult; 'What next?'},DlgTtl,'Scan','Irradiate', DefaultOpts);
    switch NextMove
        case 'Scan'
            ctltkn = 0;
            while ctltkn==0
                UserResponse = inputdlg('Where in [0,800] do you want to scan? (type in your response as two numbers separated by a comma. If you want to scan between the 100 ft and 300 ft marks, type in "100,300".)', DlgTtl,1, UserResponse, DefaultOpts);
                [ScanRange, Sanity] = str2num(UserResponse{1});
                if Sanity && (length(ScanRange)==2)
                    ctltkn=1;
                    ScanRange = sort(ScanRange);
                else
                    ErrorDia = errordlg('Error parsing input, make sure entry is comma separate list of two numbers.', DlgTtl, DefaultOpts);
                    uiwait(ErrorDia);
                end
            end
        case 'Irradiate'
            gameend = 1;
            ctltkn=0;
            while ctltkn==0
                UserResponse = inputdlg('Where do you want to irradiate? (type in your response as a single number, if you enter "10" the section between the 10 ft mark and the 11 ft mark will be irradiated.)', DlgTtl, 1, {''}, DefaultOpts);
                [IrrLB, Sanity] = str2num(UserResponse{1});
                if Sanity && (length(IrrLB)==1)
                    ctltkn=1;
                else
                    ErrorDia = errordlg('Error parsing input, make sure entry is a single number.', DlgTtl, DefaultOpts);
                    uiwait(ErrorDia);
                end
            end
            FinalMsg1 = 'You pushed the big red button on your widget, starting the count down. You hightail out of the hallway.';
            if (tribble >= IrrLB) && (tribble <= IrrLB + 1)
                FinalMsg2 = '10 seconds later, you hear a gentle ping followed by a high pitched wail.';
                FinalMsg3 = 'Congratulations. Mission accomplished!';
            else
                FinalMsg2 = '10 seconds later, you hear a gentle ping followed by eerie silence.';
                FinalMsg3 = 'The tribble was not where you thought it was. You have failed your mission and doomed us all to cuteness overload.';
            end
            EndDia = warndlg({FinalMsg1; FinalMsg2; FinalMsg3},DlgTtl, DefaultOpts);
            uiwait(EndDia);
    end
end

%
%% The real enchilada
% As a reminder of the faulty zoom lens setup, remember the three different possibilities of a scan:
% If there is a tribble in the scanned interval, the scanner returns a positive result.
% If the tribble is farther from the scanned interval by a length of 50% of the scanned interval, the scanner returns a negative result.
% It the tribble is close enough to the scanned interval within 50% of the length of the scanned interval, the scanner will randomly give either a (false) positive or a negative result. You won't know which one you receive.
%
%% Exercise 1
% Why is it that the faulty zoom lens can cause the strategy given in the section of the pre-lab titled "Mathematical Explanation" to fail? Provide a starting position for the tribble and a sequence of scans that would lead you to the wrong conclusion.
% (A version of the game with the faulty zoom lens is included below, after Exercise 2. You can play with it a little bit to see what's going on if you are not sure where to start.)
%
%% Exercise 2
% Give the technician an estimate of how many scans you will need from him before you can confidently neuter the tribble.
% Justify your answer by
% Describing the algorithm you are going to use to choose which intervals to scan.
% Analyze your algorithm to show that the level of uncertainty remaining can be made to be less than 1 foot after the right number of scans.
% (Hint: imitate the analysis and format your answer like what is shown in the "Mathematical Explanation" section of the pre-lab. What is the uncertainty after n scans in the worst case scenario?)
% A version of the game with the error-prone detector is included below for you to try out your idea.

% Find the tribble and irradiate it!
tribble = 800*rand;
DlgTtl = 'Find the tribble!';
ctltkn = 0;
DefaultOpts.Interpreter='tex';
DefaultOpts.WindowStyle='modal';
DefaultOpts.Default='Scan';
while ctltkn==0
    UserResponse = inputdlg('Where in [0,800] do you want to scan? (type in your response as two numbers separated by a comma. If you want to scan between the 100 ft and 300 ft marks, type in "100,300".)', DlgTtl, 1, {''}, DefaultOpts);
    [ScanRange, Sanity] = str2num(UserResponse{1});
    if Sanity && (length(ScanRange)==2)
        ctltkn=1;
        ScanRange = sort(ScanRange);
    else
        ErrorDia = errordlg('Error parsing input, make sure entry is comma separate list of two numbers.', DlgTtl, DefaultOpts);
        uiwait(ErrorDia);
    end
end

gameend = 0;
while gameend==0
    if (tribble >= ScanRange(1)) && (tribble <= ScanRange(2))
        ScanResult = strcat('Tribble is in range scanned:',num2str(ScanRange))
    elseif (tribble <= 1.5 * ScanRange(1) - 0.5*ScanRange(2)) || (tribble >= 1.5*ScanRange(2) - 0.5*ScanRange(1))
        ScanResult = strcat('Tribble is NOT in range scanned:' , num2str(ScanRange))
    else
        if rand >=0.5
            ScanResult = strcat('Tribble is in range scanned:',num2str(ScanRange))
        else
            ScanResult = strcat('Tribble is NOT in range scanned:',num2str(ScanRange))
        end
    end
    NextMove = questdlg({'The technician reports:';ScanResult; 'What next?'},DlgTtl,'Scan','Irradiate', DefaultOpts);
    switch NextMove
        case 'Scan'
            ctltkn = 0;
            while ctltkn==0
                UserResponse = inputdlg('Where in [0,800] do you want to scan? (type in your response as two numbers separated by a comma. If you want to scan between the 100 ft and 300 ft marks, type in "100,300".)', DlgTtl,1, UserResponse, DefaultOpts);
                [ScanRange, Sanity] = str2num(UserResponse{1});
                if Sanity && (length(ScanRange)==2)
                    ctltkn=1;
                    ScanRange = sort(ScanRange);
                else
                    ErrorDia = errordlg('Error parsing input, make sure entry is comma separate list of two numbers.', DlgTtl, DefaultOpts);
                    uiwait(ErrorDia);
                end
            end
        case 'Irradiate'
            gameend = 1;
            ctltkn=0;
            while ctltkn==0
                UserResponse = inputdlg('Where do you want to irradiate? (type in your response as a single number, if you enter "10" the section between the 10 ft mark and the 11 ft mark will be irradiated.)', DlgTtl, 1, {''}, DefaultOpts);
                [IrrLB, Sanity] = str2num(UserResponse{1});
                if Sanity && (length(IrrLB)==1)
                    ctltkn=1;
                else
                    ErrorDia = errordlg('Error parsing input, make sure entry is a single number.', DlgTtl, DefaultOpts);
                    uiwait(ErrorDia);
                end
            end
            FinalMsg1 = 'You pushed the big red button on your widget, starting the count down. You hightail out of the hallway.';
            if (tribble >= IrrLB) && (tribble <= IrrLB + 1)
                FinalMsg2 = '10 seconds later, you hear a gentle ping followed by a high pitched wail.';
                FinalMsg3 = 'Congratulations. Mission accomplished!';
            else
                FinalMsg2 = '10 seconds later, you hear a gentle ping followed by eerie silence.';
                FinalMsg3 = 'The tribble was not where you thought it was. You have failed your mission and doomed us all to cuteness overload.';
            end
            EndDia = warndlg({FinalMsg1; FinalMsg2; FinalMsg3},DlgTtl, DefaultOpts);
            uiwait(EndDia);
    end
end

%
% Addendum to Exercise 2
% Given the errors described by the technician, the best possible algorithm can guarantee to produce an uncertainty of less than 1 foot after 14 scans.
% You don't have to find this best algorithm to receive full credit on this lab. But if you have time left after finishing Exercise 2, try to see if you can figure out how this best algorithm works.
% (Hint: the best algorithm does not start by scanning [0,400] as the first interval.)
%
%% Appendix
% Digital sensors often operate in the same way as described here: the sensor detects whether a "target" is or is not within a "range" scanned. Each subsequent scan refines the result by scanning smaller and smaller intervals, based on a control algorithm programmed in the software.
% The type of errors exhibited by the second game is a typical quantization error, where targets near the edge of the range can exhibit false positives and/or false negatives.
% Efficient reconstruction of the actual target from error-prone scans is a field of active research. The problem you solved in the exercise for this week's lab is one of the simplest versions. For more information on this, a good starting point is the paper "The Golden Ratio Encoder" by Daubechies et al.