//**************************************************************
// File: A1_reactive_functions.sci
// Authors: Gerd Doeben-Henisch
// Version Start: May-18, 2010
//---------------------------------
// Last Change: Nov-26, 2012, 19:20h
//**********************************************************
// diary
//******************************************************************
// CONTENT: Necessary code for an A1-reactive-agent, the successor of the
// ANIMAT0-agent.
// ANIMAT = list(Xanimat, Yanimat, RewTotal, RewActual, CLASSIF, Energy)
// HISTORY =[]
// [CELLVALUE]=decode(YI,X,GRID,SHOW)
// [PERC]=ainp(YI,X,GRID,SHOW)
// [ANIMAT]=impact(CELLVALUE,ANIMAT,SHOW)
// [ANIMAT]=feedback(CLASSIF, ANIMAT, SHOW)
// Matchset, 2 cases:
// VITAL==1: then look for free space and the highest reward
// VITAL==0: look first for food and hifhest reward; if not then for space
// [MATCHV]=matchV(CLASSIF,j, VITALNOW,SHOW)
// [MATCHP]=matchP(CLASSIF,j, PERC, SHOW)
// [MATCHSET]=selectM(CLASSIF,PERC, VITALNOW,SHOW)
// [MATCHVP]=match2(CLASSIF,j,PERC, VITALNOW,SHOW)
// [IDXM,CAND, MATCHSET,ACTIONSET]=makeCAND(MATCHSET,SHOW)
// [ANIMAT,OLDACTIONS]=manageOldActs(IDXM,CAND,OLDACTIONS,ACTIONSET,ANIMAT,FOODIDX)
// [YN, XN]=aout(ACT,SHOW, YO, XO)
// [ANIMAT,HISTORY,GRID,FOOD]=liveR2(ANIMAT,GRID, RUNS,SHOW)
// [FOODHITS,MEAN, STD]=experiment1(ANIMAT,YS, XS,ENERGYS, GRID, RUNS,HISTORY,SHOW,N)
// [HISTORY]=updateHIST(HISTORY,k, CELLVALUE,XN,YN,ANIMAT)
// [FOOD]=FOOD(HISTORY,RUNS)
// [ANIMAT]=zeroCLASSIFFEEDB(ANIMAT,CLASSIF)
// Set OLDACTIONS to zero
// [ANIMAT, OLDACTIONS]=oldActZero(ANIMAT,OLDACTIONS)
//***************************************************
//The Generation of ENVIRONMENTS as GRIDS will be done by another PREPARATORY
// SCRIPT
// Here we have only a few special TEST GRIDS
//****************************************************
// HISTORY
// Collecting data during one life-cycle
// 1 := Cycle number k
// 2 := Object before move
// 3 := YI-Pos
// 4 := X-Pos
// 5 := REWTotal
// 6 := eNERGY
HISTORY =[]
//***************************************************
// Function to decode the content of a cell
//
// Only change: Border 'BB' is replaced by value '01'
function[CELLVALUE]=decode(YI,X,GRID,SHOW)
[YMAX, XMAX]=size(GRID)
if (SHOW==1) then printf("decode: SIZE OF GRID (X,Y) = (%d,%d)\n",XMAX,YMAX),end
CELLVALUE=[]
if (SHOW==1) then printf("decode: YMAX=%d, XMAX=%d,YI= %d, X= %d\n",YMAX, XMAX,YI,X),end
if (X > XMAX) | (X < 1) | (YI > YMAX) | (YI <1) then CELLVALUE='01'
elseif GRID(YI,X) =='.' then CELLVALUE='00'
elseif GRID(YI,X) =='O' then CELLVALUE='10'
elseif GRID(YI,X) =='F' then CELLVALUE='11'
else printf("decode:ERROR AT CELL =( %d,%d)\n",X,YI)
end
endfunction
//*************************************************
// SENSING ENVIRONMENT
// Function ainpe(POS,DISTANCE) from ANIMAT1-agent
//
// Loocking to the 'north' the Animat can see the content of all it's neighbouring cells clockwise around.
// Enhancing the distance by 1 extends the field to the next 'circle'
// The encoding is as follows:
// '.' := Empty space encoded '00'
// Border BB := has to be encoded as '01'
// 'O' := Object Rock encoded '10'
// 'F' := Object Food encoded '11'
function [PERC]=ainp(YI,X,GRID,SHOW)
//Having a 'number' version of the input
SENSINPUT=[]
PERC=""
//The cells will be searched from 'north' in clockwise order
// The coordinates below are relativ to the actual position of the ANIMAT
P=[-1,0; -1,1; 0,1; 1,1; 1,0; 1, -1; 0,-1; -1,-1 ]
[r,c]=size(P)
for j=1:r, SENSINPUT(j)=decode(YI+P(j,1),X+P(j,2),GRID, SHOW),
PERC=PERC+string(SENSINPUT(j))
end
if (SHOW==1) then
printf("ainp: PERC = %s\n\n",PERC)
end
endfunction
//*************************************************
// IMPACT
// impact: PERC x ENERGY ---> ENERGY x VITAL
//
// Depending on the actual state of ENERGY will the perception PERC
// eventually change the state of ENERGY and thereby of VITAL.
// FOOD will increase the state of ENERGY and NON-FOOD
// will decrease the state.
function [ANIMAT]=impact(CELLVALUE,ANIMAT,SHOW)
// Get new energy
if(CELLVALUE == '11') then
ANIMAT(15)=1
ANIMAT(4)= ANIMAT(10) //Input Food
else ANIMAT(4)=ANIMAT(11) // Input No-Food
end
ANIMAT(3) = ANIMAT(3)+ANIMAT(4)
// Update the VITAL state; compare Threshold ANIMAT(12)= 0.5* FOODIDX
if (ANIMAT(3) > ANIMAT(12)) then ANIMAT(6) = 1,
else ANIMAT(6) = 0
end
endfunction
//*************************************************
// matchP: PERC x CLASSIFIERS ---> {0,1}
//
// matchP matches the PERCEPTION-part of a classifier and the P parameter
// of the system
//
// Does match : '0'
// Does not match : '1'
// j := IDX of Classifier
function [MATCHP]=matchP(CLASSIF,j,PERC, SHOW)
[r,c]=size(CLASSIF)
l = length(PERC)
m=0
i=1
// Strings have to be converted into vectors first
[pc]=strsplit(CLASSIF(j,1))
pr=pc'
[percc]=strsplit(PERC)
percr=percc'
while(( i<l+1) & (m==0))
if (percr(i) == '0') & ((pr(i) == '0') | (pr(i) == '#')) then m=0,
if(SHOW == 1) then
printf("matchP: Case 0, i = %d\n ",i),end
elseif (percr(i) == '1') & ((pr(i) == '1') | (pr(i) == '#')) then m=0,
if(SHOW == 1) then
printf("matchP: Case 1, i = %d\n ",i),end
else m=1,
if(SHOW == 1) then
printf("matchP: NO-Case, i = %d\n ",i),end
end //IF
i=i+1
end //WHILE
MATCHP=m
endfunction
//*************************************************
// SELECTM
// selectM: PERC x VITALl X CLASSIF ---> MATCHSET
//
//
function [ANIMAT,MATCHSET]=selectM(ANIMAT, CLASSIF,PERC,MATCHSET,SHOW)
MATCHSET=[], k=1
[r,c]=size(CLASSIF)
for j=1:r,
if(matchP(CLASSIF,j, PERC, SHOW)==0) then MATCHSET(k,:)=CLASSIF(j,:),
if(SHOW == 5) then
printf("selectM: selected=%d, k=%d\n",j,k), end
k=k+1,
end// IF matchP
end// FOR
ANIMAT(13) = MATCHSET
disp('MATCHSET END OF selectM')
disp(MATCHSET)
endfunction
//***************************************************
// makeCANDpath
//
// searches all classifiers from the matchset with a path option,
// then takes that option with highest reward
// makeCAND : MATCHSET ---> IDXCAND, ACTIONSET
//
function [IDXM,CAND, MATCHSET,ACTIONSET,ACT]=makeCANDpath(MATCHSET,SHOW)
[mr,mc]=size(MATCHSET)
// Searches for classifiers with path option
j=0 // Index for ACTSET, copy if path matches
needle='00' //Hint for path
for i=1:mr,
if grep(MATCHSET(i,1),needle)<>[] then
j=j+1,
ACTIONSET(j,:)=MATCHSET(i,:)
end
end
MATCHSET=[]
MATCHSET=ACTIONSET
[mr,mc]=size(MATCHSET)
MAX=0
//Searches for the HIGHEST value of REW
for i=1:mr,
if(eval(MATCHSET(i,4)) > MAX) then MAX=eval(MATCHSET(i,4)),
end
end
disp('MATCHSET MIDDLE OF makeCANDpath')
disp(MATCHSET)
// Identifies all elements of MATCHSET which have the highest REW-value
k=1
CAND=[]
for i=1:mr,
if(eval(MATCHSET(i,4)) == MAX) then CAND(k)=i, k=k+1,
if or([SHOW==5 SHOW==6]) then
printf("makeCAND: i=%d has MAX\n",i),
end
end
end
// Selects an element of CAND by random
IDXM=(floor(length(CAND)*rand()) )+1
if or([SHOW==5 SHOW==6]) then
disp(MATCHSET(CAND(IDXM),:))
end
//The index IDXM points into CAND and the IDXM-element of CAND points to the element of MATCHSET
// CAND(IDXM) ---> element of MATCHSET
// MATCHSET(CAND(IDXM),:) is the whole element
// MATCHSET(CAND(IDXM),3) is the ACT-element
ACTIONSET(1,:) = MATCHSET(CAND(IDXM),:)
if or([SHOW==5 SHOW==6]) then
disp('NEW ACTIONSET = ')
disp(ACTIONSET)
end
ACT=MATCHSET(CAND(IDXM),3)
endfunction
//***************************************************
// makeCANDfood
//
// searches all classifiers from the matchset with a food option,
// then takes that option with highest reward
// makeCAND : MATCHSET ---> IDXCAND, ACTIONSET
//
function [IDXM,CAND, MATCHSET,ACTIONSET,ACT]=makeCANDfood(MATCHSET,SHOW)
[mr,mc]=size(MATCHSET)
ACTIONSET=[]
// Searches for classifiers with food option
j=0 // Index for ACTSET, copy if path matches
needle='11' //Hint for path
for i=1:mr,
if grep(MATCHSET(i,1),needle)<>[] then
j=j+1,
ACTIONSET(j,:)=MATCHSET(i,:)
end
end
if ACTIONSET==[] then [IDXM,CAND, MATCHSET,ACTIONSET,ACT]=makeCANDpath(MATCHSET,SHOW)
else
MATCHSET=ACTIONSET
disp('MATCHSET MIDDLE OF makeCANDfood')
disp(MATCHSET)
[mr,mc]=size(MATCHSET)
MAX=0
//Searches for the HIGHEST value of REW
for i=1:mr,
if(eval(MATCHSET(i,4)) > MAX) then MAX=eval(MATCHSET(i,4)),
end
end
// Identifies all elements of MATCHSET which have the highest REW-value
k=1
CAND=[]
for i=1:mr,
if(eval(MATCHSET(i,4)) == MAX) then CAND(k)=i, k=k+1,
if or([SHOW==5 SHOW==6]) then
printf("makeCAND: i=%d has MAX\n",i),
end
end
end
// Selects an element of CAND by random
IDXM=(floor(length(CAND)*rand()) )+1
if or([SHOW==5 SHOW==6]) then
disp(MATCHSET(CAND(IDXM),:))
end
//The index IDXM points into CAND and the IDXM-element of CAND points to the element of MATCHSET
// CAND(IDXM) ---> element of MATCHSET
// MATCHSET(CAND(IDXM),:) is the whole element
// MATCHSET(CAND(IDXM),3) is the ACT-element
ACTIONSET(1,:) = MATCHSET(CAND(IDXM),:)
if or([SHOW==5 SHOW==6]) then
disp('NEW ACTIONSET = ')
disp(ACTIONSET)
end
ACT=MATCHSET(CAND(IDXM),3)
end
endfunction
//*************************************************
// MAP ACT into POS
// Function aout: ACT --> POS
function [YN, XN]=aout(ACT,SHOW, YO, XO)
// The coordinates below are relativ to the actual position of the ANIMAT
//They work 'clockwise' around beginning with 'north'
// Because 'no move' is encoded as '0' and the indices of the vectors
// in scilab start with '1' we encode '0,...,8' as '1,...,9'
P=[0,0; -1,0; -1,1; 0,1; 1,1; 1,0; 1, -1; 0,-1; -1,-1 ]
YN=YO+P(evstr(ACT)+1,1),
XN=XO+P(evstr(ACT)+1,2)
endfunction
//*************************************************
// UPDATE HISTORY
function [HISTORY]=updateHIST(HISTORY,k, CELLVALUE,XN,YN,ANIMAT)
[r,c]=size(HISTORY)
//INDEX
HISTORY(r+1,1)=k
//CONTENT
HISTORY(r+1,2)=evstr(CELLVALUE)
// POSITION
HISTORY(r+1,3)=YN, HISTORY(r+1,4)=XN
//REWARDTOTAL
HISTORY(r+1,5)=ANIMAT(3)
//ENERGY
HISTORY(r+1,6)=ANIMAT(4)
//VITAL
HISTORY(r+1,7)=ANIMAT(6)
endfunction
//*************************************************
// Compute FOOD
function [FOOD]=food(HISTORY,RUNS)
// FOOD(1) := Occurences of food
// FOOD(2) := Number of runs
// FOOD(3) := Occurence/Number = Density
// FOOD(4) := Mean number of actions
FOOD=[0 0 0 0]
[r,c]=size(HISTORY)
for i=1:r
if (HISTORY(i,6)> -1) then FOOD(1)=FOOD(1)+1
end
end
FOOD(2)=RUNS
if (FOOD(1) > 0) then FOOD(3) = FOOD(1)/FOOD(2), else FOOD(3)=0,end
if (FOOD(1) > 0) then FOOD(4) = FOOD(2)/FOOD(1), else FOOD(3)=0,end
endfunction
//*************************************************
// Set CLASSIF Feedback Values to zero-string '000'
function [ANIMAT]=zeroCLASSIFFEEDB(ANIMAT,CLASSIF)
[r,c]=size(CLASSIF)
for i=1:r
CLASSIF(i,4)='000'
end
ANIMAT(8) = CLASSIF
endfunction
//*******************************************************
// Set OLDACTIONS to zero
function [ANIMAT, OLDACTIONS]=oldActZero(ANIMAT,OLDACTIONS)
for i=1:ANIMAT(9)
OLDACTIONS(i,1)=0
OLDACTIONS(i,2)=0
end
ANIMAT(7)=OLDACTIONS
endfunction