% GNATS
%
% by Robert J. Marks II  "My software isn't pretty but it works".
%
% A very simple game.  Gnats, here called sheep (don't ask), are monitored by a sheepdog (again - don't ask)
% who looks at the gnat straying farthest from the center.  The sheepdog nudges the maverick gnat who starts
% to mosey in the direction of the centroid in a directed randon walk.
% 
% PARAMETERS must be changed in the Matlab code
%
% 	NX, NY = the domensions of the field.
% 	sheep = number of gnats
% 	p = parameter of the random walk = prob +1 = prob -1.  (Note:   prob(1)+prob(-1)+prob(0) = 1  ).
% 	generations = number of cycles
% 	flicks =			When the program is over, this is how many times the movie is played.
% 						If set to zero, there is no movie.  This saves memory.
%						If =1/2, movie is made but not played
% 	ss = number of generations before steady state (a guess).
% 	lambd = a smoothing coefficient for the 'smoothie' maverick plot (see below).  0.99 is a decent default.
%	initi = 0 puts all the initial gants at the center.  =1 distributes them randomly.
%
% OUTPUTS
% 	M = frames of gnats
% 	y = record of maximum gnat deviation
% 	smoothie = smoother version of y using "lambd" parameter.
%
close all 
clear all
%
% PARAMETERS
NX=300; NY=300;		% This is the size of the sheep pen.
sheep=100;				% Number of sheep.
generations=2500;		% The number of times the sheepdog interacts with the sheep.
p=0.5;					% Prob of drift of a sheep both up and down and right and left.
flicks=1;				% When the program is over, this is how many times the movie is played.
% 							% If set to zero, there is no movie.  This saves memory.
%							% If =1/2, movie is made but not played
ss=1; cc=0;			% Steady State & count.  
lambd=0.995;			% Smoothie is exponentially smoothed average
initi=1;					% = 0 puts all the initial gnats at the center.  =1 distributes them randomly.
%

%
% INITIALIZE
ave=zeros(generations-ss,1);y=zeros(generations,1);smoothie=zeros(generations-ss+1,1); smoothie(1)=NX;
sheeps=zeros(sheep,2); del=sheeps;
centr=zeros(2,1);centr(1)=ceil(NX/2); centr(2)=ceil(NY/2);
if(initi==0)
   sheeps(:,1)=centr(1)*ones(size(sheeps(:,1)));
   sheeps(:,2)=centr(2)*ones(size(sheeps(:,2)));
elseif(initi==1)
   sheeps(:,1)=ceil(NX*rand(sheep,1));
   sheeps(:,2)=ceil(NY*rand(sheep,1));
end
pen=zeros(NX,NY);
dsc=zeros(sheep,2);

%
% GENERATIONS
%
for g=1:generations 
   % Distance of sheep to centroid
   dsc(:,1) =sheeps(:,1)-centr(1)*ones(sheep,1);
   dsc(:,2) =sheeps(:,2)-centr(2)*ones(sheep,1);
   rsc=dsc(:,1).*dsc(:,1)+dsc(:,2).*dsc(:,2);
   % Finding Maverick
   [y(g) maverick]=max(rsc);
   if(g>=ss)
      cc=cc+1;smoothie(cc+1)=lambd*smoothie(cc)+(1-lambd)*y(g);
   end
   if(flicks>=0)
      imagesc(pen); hold on; plot(centr(1),centr(2),'yx'); hold on 
      plot(sheeps(maverick,1),sheeps(maverick,2),'ro'); hold on
   end
   del(maverick,1)= -sign(sheeps(maverick,1)-centr(1)*ones(size(sheeps(maverick,1))));
   del(maverick,2)= -sign(sheeps(maverick,2)-centr(2)*ones(size(sheeps(maverick,2))));
   rr=rand(sheep,2); 
   sheeps=sheeps+ceil(p-rr)-ceil(rr-1+p)+del;
   for n=1:sheep
      if(sheeps(n,1)>NX) ;sheeps(n,1)=NX; end; if(sheeps(n,1)<1); sheeps(n,1)=1; end
      if(sheeps(n,2)>NY) ;sheeps(n,2)=NY; end; if(sheeps(n,2)<1); sheeps(n,2)=1; end
      if(flicks>=0)
         plot(sheeps(n,1),sheeps(n,2),'k.'); hold on
      end
   end 
   title(g);if(g>=ss);xlabel(smoothie(cc));ylabel(y(g));end  
   if(flicks>=0)
      if(flicks==0)
         M=getframe;
      else
         if(g>=ss); M(cc)=getframe;end
      end
      hold off;
   end
end
figure; plot(y);title('Maximum Deviation'); 
figure; plot(smoothie);title('Smoothed');
e website templates.