ID:50290
Title:GOGO 2
Author:DreadNox
Date:2008-11-07 11:59:44
Score:38323.3901
Result:36230.49 (cyc: 121, node: 1799)
CPU Time:148.4023
Status:Passed
Comments:
Based on:none
Code:
function [dRow,dCol,action,mark] = solver(mainMap,foodMap,myAntMap,opAntMap, ...
    myScentMap,opScentMap,myDeathMap,opDeathMap)

%% vs house_solver0
% results: 5807.58
% time: 151.59

%% vs house_solver1

%% vs self

% complexity: 121


%% movements
% (-1,-1) (-1, 0) (-1, 1)
% ( 0,-1) ( 0, 0) ( 0, 1)
% ( 1,-1) ( 1, 0) ( 1, 1)
%moves = [-1 -1; 0 -1; 1 -1; -1 0; 0 0; 1 0; -1 1; 0 1; 1 1];
%% ant view indices
%  1  6 11 16 21
%  2  7 12 17 22
%  3  8 13 18 23
%  4  9 14 19 24
%  5 10 15 20 25

% modified maps to exclude unreachable regions
[mainMap, foodMap, myScentMap, myAntMap, BAD, moveToLoc] = ...
    findReachable(mainMap, foodMap, myScentMap, myAntMap);

%% Food analysis %%%%%%
foodMap(mainMap == 1) = 0; % ignore food on my anthills
action = 0; % not carrying anything (default)
if foodMap(13) > 0 % sitting on food?
    % yes, and not in anthill => take it there
    % is there enough food for all ants in this place?
    % yes => each one will take one
    % too many ants => some should ignore this food
    isThereEnoughFood = foodMap(13) - myAntMap(13) >= 0;
    assignedAsCarrier = rand <= foodMap(13)/myAntMap(13);
    if isThereEnoughFood || assignedAsCarrier
        % carry this food
        if any(mainMap(:) == 1) % any of my anthills in sight?
            % yes => move to closest anthill
            [r, c] = find(mainMap == 1);
            dist = max(abs(r-3), abs(c-3));
            [ign, k] = min(dist);
            i = r(k) + 5*(c(k)-1);
        elseif any(myScentMap(:)) % any scent to guide me to anthill?
            % go to where scent is higher (ignore where I am)
            auxMyScentMap = myScentMap;
            auxMyScentMap(13) = 0;
            [ign, i] = max(auxMyScentMap(:));
        else
            % no anthill and no scent => wander aimlessly with food
            i = randomDest(BAD);
        end
        action = 1; % carry food
    end
    %else, this food is not for me => action stays equal to 0
    foodMap(13) = 0; % food in this place is assigned (ignore it from here on)
end

if action == 0 % i'm not carrying any food => find some
    % before going after it, take into account other ants
    foodMap = max(foodMap - myAntMap, 0);
    if any(foodMap(:)) % any food unattended?
        %[maxFood, i] = max(foodMap(:)); % go for biggest pile
        % go for closest pile
        [r, c] = find(foodMap > 0);
        dist = max(abs(r-3), abs(c-3));
        [ign, k] = min(dist);
        i = r(k) + 5*(c(k)-1);
    elseif any(myScentMap(:))
        % no food => move downhill of scent
        %auxMyScentMap = myScentMap;
        %auxMyScentMap(myScentMap == 0) = inf;
        %[ign, i] = min(auxMyScentMap);
        % find unscented spots
        [r, c] = find((myScentMap == 0) & ~BAD);
        if ~isempty(r)
            % move to the closest
            dist = max(abs(r-3), abs(c-3));
            p = find(dist == min(dist));
            k = ceil(numel(p)*rand);
            i = r(p(k)) + 5*(c(p(k))-1);
        else
            % move to lowest scented spot
            auxMyScentMap = myScentMap;
            auxMyScentMap(myScentMap == 0) = inf;
            p = find(auxMyScentMap(:) == min(auxMyScentMap(:)));
            k = ceil(numel(p)*rand);
            i = p(k);
        end
        if i == 13 % I have to move somewhere
            i = randomDest(BAD);
        end
    else
        % no food, no scent => wander aimlessly
        i = randomDest(BAD);
    end
end

% compute displacements to reach i
move = moveToLoc(i,:);
dRow = move(1);
dCol = move(2);

%% Scent marking %%%%%%
mark = 0; % leave no scent (default)
if mainMap(13) == 1 % am I in one of my anthills?
    % mark with maximum scent possible
    mark = 100;
else
    % look for scent %in outer rim
    %outerRim = [1 2 3 4 5 6 10 11 15 16 20 21 22 23 24 25];
    if any(myScentMap(:)) % any scent
        % mark to form gradient (higher means closer to anthill)
        maxscent = max(myScentMap(:));
        % make scent in this place one unit smaller than max
        targetScent = maxscent - 1; % scent that should be in this location after all ants have dropped marks
        dScent = min(max(targetScent - myScentMap(13), 0), 100);
        % watchout for multiple marks by other ants in the same location
        mark = fix(dScent / myAntMap(13)); % divide over all ants in this location
    else
        % no scent
        if any(mainMap(:) == 1) % any anthill around?
            % yes (but I am not on top of it). If I leave a mark other ants
            % farther away might see it
            mark = 100;
        end
    end
end

end % solver

% ========================================================================
function [main,food,scent,ants,bad,moveToLoc] = ...
    findReachable(main,food,scent,ants)

% find reachable locations AND move to reach said locations
nextLoc = (1:25).'; % every location points to itself
                    % (all that matters is that it must be different from 0)
bad=isnan(main); % bad(i) = 1 => location i might not be reachacble 
                 % based on current (local) information

% find other unreachable regions AND assign to nextLoc the in-neighbor that
% should be used to get to reachable regions

if ~bad(1)
    if bad(7)
        if (bad(8) || bad(2))
            if (bad(12) || bad(6))
                bad(1) = 1;
            else
                nextLoc(1) = 12;
            end
        else
            nextLoc(1) = 8;
        end
    else
        nextLoc(1) = 7;
    end
end
if ~bad(2)
    if bad(7)
        if bad(8)
            if (bad(12) || bad(6))
                if (bad(3) || bad(9))
                    bad(2) = 1;
                else
                    nextLoc(2) = 9;
                end
            else
                nextLoc(2) = 12;
            end
        else
            nextLoc(2) = 8;
        end
    else
        nextLoc(2) = 7;
    end
end
if ~bad(3)
    if bad(7)
        if bad(8)
            if bad(9)
                if (bad(12) || bad(6) || bad(2))
                    if (bad(14) || bad(10) || bad(4))
                        bad(3) = 1;
                    else
                        nextLoc(3) = 14;
                    end
                else
                    nextLoc(3) = 12;
                end
            else
                nextLoc(3) = 9;
            end
        else
            nextLoc(3) = 8;
        end
    else
        nextLoc(3) = 7;
    end
end
if ~bad(4)
    if bad(8)
        if bad(9)
            if (bad(3) || bad(7))
                if (bad(10) || bad(14))
                    bad(4) = 1;
                else
                    nextLoc(4) = 14;
                end
            else
                nextLoc(4) = 7;
            end
        else
            nextLoc(4) = 9;
        end
    else
        nextLoc(4) = 8;
    end
end
if ~bad(5)
    if bad(9)
        if (bad(4) || bad(8))
            if (bad(10) || bad(14))
                bad(5) = 1;
            else
                nextLoc(5) = 14;
            end
        else
            nextLoc(5) = 8;
        end
    else
        nextLoc(5) = 9;
    end
end
if ~bad(6)
    if bad(7)
        if bad(12)
            if (bad(2) || bad(8))
                if (bad(11) || bad(17))
                    bad(6) = 1;
                else
                    nextLoc(6) = 17;
                end
            else
                nextLoc(6) = 8;
            end
        else
            nextLoc(6) = 12;
        end
    else
        nextLoc(6) = 7;
    end
end
if ~bad(11)
    if bad(7)
        if bad(12)
            if bad(17)
                if (bad(6) || bad(2) || bad(8))
                    if (bad(10) || bad(22) || bad(18))
                        bad(11) = 1;
                    else
                        nextLoc(11) = 18;
                    end
                else
                    nextLoc(11) = 8;
                end
            else
                nextLoc(11) = 17;
            end
        else
            nextLoc(11) = 12;
        end
    else
        nextLoc(11) = 7;
    end
end
if ~bad(16)
    if bad(12)
        if bad(17)
            if (bad(7) || bad(11))
                if (bad(18) || bad(22))
                    bad(16) = 1;
                else
                    nextLoc(16) = 18;
                end
            else
                nextLoc(16) = 7;
            end
        else
            nextLoc(16) = 17;
        end
    else
        nextLoc(16) = 12;
    end
end
if ~bad(20)
    if bad(14)
        if bad(19)
            if (bad(9) || bad(15))
                if (bad(18) || bad(24))
                    bad(20) = 1;
                else
                    nextLoc(20) = 18;
                end
            else
                nextLoc(20) = 9;
            end
        else
            nextLoc(20) = 19;
        end
    else
        nextLoc(20) = 14;
    end
end
if ~bad(15)
    if bad(9)
        if bad(14)
            if bad(19)
                if (bad(8) || bad(4) || bad(10))
                    if (bad(18) || bad(24) || bad(20))
                        bad(15) = 1;
                    else
                        nextLoc(15) = 18;
                    end
                else
                    nextLoc(15) = 8;
                end
            else
                nextLoc(15) = 19;
            end
        else
            nextLoc(15) = 14;
        end
    else
        nextLoc(15) = 9;
    end
end
if ~bad(10)
    if bad(9)
        if bad(14)
            if (bad(4) || bad(8))
                if (bad(15) || bad(19))
                    bad(10) = 1;
                else
                    nextLoc(10) = 19;
                end
            else
                nextLoc(10) = 8;
            end
        else
            nextLoc(10) = 14;
        end
    else
        nextLoc(10) = 9;
    end
end
if ~bad(21)
    if bad(17)
        if (bad(12) || bad(16))
            if (bad(18) || bad(22))
                bad(21) = 1;
            else
                nextLoc(21) = 18;
            end
        else
            nextLoc(21) = 12;
        end
    else
        nextLoc(21) = 17;
    end
end
if ~bad(22)
    if bad(17)
        if bad(18)
            if (bad(12) || bad(16))
                if (bad(23) || bad(19))
                    bad(22) = 1;
                else
                    nextLoc(22) = 19;
                end
            else
                nextLoc(22) = 12;
            end
        else
            nextLoc(22) = 18;
        end
    else
        nextLoc(22) = 17;
    end
end
if ~bad(23)
    if bad(17)
        if bad(18)
            if bad(19)
                if (bad(12) || bad(16) || bad(22))
                    if (bad(14) || bad(20) || bad(24))
                        bad(23) = 1;
                    else
                        nextLoc(23) = 12;
                    end
                else
                    nextLoc(23) = 12;
                end
            else
                nextLoc(23) = 19;
            end
        else
            nextLoc(23) = 18;
        end
    else
        nextLoc(23) = 17;
    end
end
if ~bad(24)
    if bad(18)
        if bad(19)
            if (bad(23) || bad(17))
                if (bad(20) || bad(14))
                    bad(24) = 1;
                else
                    nextLoc(24) = 14;
                end
            else
                nextLoc(24) = 17;
            end
        else
            nextLoc(24) = 19;
        end
    else
        nextLoc(24) = 18;
    end
end
if ~bad(25)
    if bad(19)
        if (bad(24) || bad(18))
            if (bad(20) || bad(14))
                bad(25) = 1;
            else
                nextLoc(25) = 14;
            end
        else
            nextLoc(25) = 18;
        end
    else
        nextLoc(25) = 19;
    end
end

% moves to reach locations
moves = [-1 -1; 0 -1; 1 -1; -1 0; 0 0; 1 0; -1 1; 0 1; 1 1];
inNeigh = [7 8 9 12 13 14 17 18 19];
nextLoc(inNeigh) = inNeigh;
moveToLoc = zeros(25,2);
moveToLoc(inNeigh,:) = moves;
moveToLoc = moveToLoc(nextLoc,:);

% modify current board based on reachable regions
main(bad)=NaN;
food(bad)=0;
scent(bad)=0;
ants(bad)=0;

bad(13) = 1;

end % findReachable

% ========================================================================
function i = randomDest(BAD)

possibleDest = find(~BAD);
k = ceil(numel(possibleDest)*rand);
i = possibleDest(k);

end % randomDest