| 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
|