Diffing "thinkspread" and "HJ115"

Title: thinkspread HJ115
Author: snowman the cyclist
Submitted: 2008-11-12 11:43:24 UTC 2008-11-12 11:59:36 UTC
Status: Passed Passed
Score: 27294.0 27590.4
Result: 22869.38 (cyc: 30, node: 1093) 22869.38 (cyc: 30, node: 1097)
CPU Time: 160.391 161.368
Code:
function [dy,dx,action,mark]=solver(main,food,ants,opant,scent,opscent,death,opdeath)

center=13;
hillScent = 300;
threatScent = 600;
via=[ 1  1  2  2  3  1  1  2  3  3  4  4  5  6  6  4  7  8  9  6  7  7  8  8  9;
    1  2  2  3  3  4  1  2  3  6  4  4  5  6  6  7  7  8  9  9  7  8  8  9  9];
n1 = [7; 8;9;12;13;14;17;18;19];

%adjust map for reachability
origscent = scent(13);
origscent = scent(center);
rocked = isnan(main);
scent(rocked) = -1e5; %rockScent;
nbrock = rocked(n1); % neighboring rocks
unreachable = all(nbrock(via));% unreachable due to rocks
hills = main(:)==1;
if any(unreachable)
    hills(unreachable) = false;
    food(unreachable) = 0;
    scent(unreachable) = -1e5;
    opant(unreachable) = 0;
end
% adjust scent for rocks & hills & threats
if any(hills)
    scent(hills) = hillScent;
    food(hills) = 0;
    if any(opant(hills)>0) % ignore food next to occupied hills
        adj = [2 6 2 6; 1 3 7 7; 2 4 8 8; 3 5 9 9; 4 10 4 10;
            1 7 7 11; 2 6 8 12; 3 7 9 13; 4 8 10 14; 5 9 9 15;
            6    12    12    16;  7    11    13    17
            8    12    14    18;  9    13    15    19
            10    14    14    20; 11    17    17    21
            12    16    18    22; 13    17    19    23
            14    18    20    24; 15    19    19    25
            16    22    22    16; 17    21    23    17
            18    22    24    18; 19    23    25    19
            20    24    24    20];
        food(adj(hills(opant(hills)>0),:)) = 0;
    end
end
myants = ants(13);
myants = ants(center);
maxs = max(scent(:)); % max reachable scent determines mark value
[y,x] = find(maxs == scent); % location(s) of maxs so we can find distance
bx = sum(x-3)/numel(x);
by = sum(y-3)/numel(y);
scent(13) = maxs-abs(bx+j*by); % new scent value desired
mark = (scent(13)-origscent)/myants-0.5; % raise mark
scent(center) = maxs-abs(bx+j*by); % new scent value desired
mark = (scent(center)-origscent)/myants-0.5; % raise mark

adjop = opant(n1);
nop = sum(adjop);
numop = sum(opant(:));
if numop
    threat = opant(:)+min(adjop(via))'; % direct & blocking threats
    threat(threat>myants(:)/2) = threatScent;
    scent = abs(scent(:))+threatScent*threat;
    mins = min(scent);
    % defend?
    if mins >= threatScent || rand < (opant(13)+.06*nop)/myants
        dx = 0;
        dy = 0;
        action = -1;
        return
    end
else
    threat = 0;
    scent = abs(scent(:));
    mins = min(scent);
end

numant = sum(ants(:));
agress = numant > 3 && numant > numop+2 ...
    && (numant > 3*(numop+1) || sum(death(:))==0);

to = [];
up = food(13);
up = food(center);
fao = max(food(:)-ants(:)-threat,0);
X = [-1    -1    -1     0     0     0     1     1     1];
Y = [-1     0     1    -1     0     1    -1     0     1];
d2b = (X-bx).^2+(Y-by).^2; 
d2b(nbrock) = inf;
if up % food to carry up
    target = adjop;%+d2b';
    target(d2b >= d2b(5)) = Inf;
    mu = min(target);
    to = find(target == mu);
    if mu==0
        if up == 1
            fao([-2 -2 -2 -2 -2 -1 -1 -1 -1 -1  0  0  0  0  0  1  1  1  1  1  2  2  2  2  2]*bx + [-2 -1  0  1  2 -2 -1  0  1  2 -2 -1  0  1  2 -2 -1  0  1  2 -2 -1  0  1  2]*by >=0) = 0; % first check if more food is down
            sumf = sum(fao);
            if sumf>0
                to = []; % go down for more food
            end
        elseif rand^2 < max(1/up, (1-up/myants)^2)
            to = []; % leave a few ants behind
        end
    elseif (~agress || myants<3*mu+1 || rand > 2/3)
        to = []; % don't attack
    end
    if numel(to)>1
        to = to(ceil(rand*numel(to)));
    end
end

if isempty(to)% we've decided not to carry
    maxf = max(fao);
    if maxf==0 % no excess food; go by scent
        dto = via(:,scent<mins+2);
    else
        dto = via(:, fao >= .75*maxf); % go toward excess food
        dto = [dto(:); find(food(n1)>0 & ~ants(n1))]; % also like any untouched food
    end
    adjop(5) = 1-(up>0)*(myants<3); % we're willing to stay if we guard food
    sto = dto(adjop(dto)==0); % safe destinations
    if ~isempty(sto) % there are safe places
        to = sto(ceil(rand*numel(sto))); % go via any safe
    else
        to = dto(ceil(numel(dto)/2)); % attack?
        if ~agress || myants<=2*opant(to)+2 || rand > (2*opant(to)+1)/myants
            to = 5; % defend
        end
    end
end
if isempty(to) || (to==5 && nop==0)
    dto = find(~nbrock); % reachable one-ring neighbors
    to = dto(ceil(rand*numel(dto)));
end
dx = X(to);
dy = Y(to);
if to==5
    action = -1;
elseif d2b(to) < d2b(5) % carry going uphill
    action = 1;
else
    action = 0;
end