zsc2_functions

 //**************************************************************
// File: zcs2-functions.sce
// Authors: Gerd Doeben-Henisch
// Version Start: May-18, 2010
//---------------------------------
// Update May-19-2010-1459
// Update May-19-10-2343
// Update May-27-10-1825
// Update May-31-10-2005
// Update June-1-10-1743
// Update June-1-10-2119
// Update June-6-10-1552
//**********************************************************
// diary('H:\FH\SCILAB\HISTORIES\Date.txt')
//diary('/home/gerd/public_html/uffmm/science-technology/single/themes/computer-science/personal-sites/doeben-henisch/KNOW/GBBLT/SCILAB/HISTORIES/May20-10-1032.txt')
//******************************************************************
// CONTENT: Necessary code for an ANIMAT2-agent, the successor of the
// ANIMAT0- and ANIMAT1-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)
// [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]=makeCAND(MATCHSET,SHOW)
// [ACT]=action2(IDXM,CAND, MATCHSET)
// [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)

//***************************************************
//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(4)= ANIMAT(10)
    else   ANIMAT(4)=ANIMAT(11)
    end
   
    ANIMAT(3) = ANIMAT(3)+ANIMAT(4)
 
 // Update the VITAL state
 if (ANIMAT(3) > ANIMAT(12)) then ANIMAT(6) = 1,
 else ANIMAT(6) = 0
 end
 
endfunction

//*************************************************
// matchV: VITAL x CLASSIFIERS ---> {0,1}
//
// matchV matches the V-part of a classifier and the V parameter
// of the system
//
// Does match : '0'
// Does not match : '1'


function [MATCHV]=matchV(CLASSIF,j,ANIMAT,SHOW)
  
  MATCHV = strcmp(CLASSIF(j,2), sci2exp(ANIMAT(6)))
  
  if (MATCHV <> 0) then MATCHV=1,end
  
  if (SHOW==1) then
     printf("matchV: CLASSIF(j) <--> VITAL = %d : %d\n",j,MATCHV)
   end
endfunction

//*************************************************
// matchP: PERC x CLASSIFIERS ---> {0,1}
//
// matchP matches the P-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 iton 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


//*************************************************
// MATCH2
// match2: PERC x VITALl X CLASSIF ---> {0,1}
//
// match2 = matchV o matchP
//   

function [MATCHVP]=match2(CLASSIF,j,PERC, ANIMAT,SHOW)
  
  
  if(matchV(CLASSIF,j,ANIMAT,SHOW)==0 & matchP(CLASSIF,j, PERC, SHOW)==0) then MATCHVP=0, else MATCHVP=1,
  end
  
  if(SHOW == 1) & (MATCHVP==0) then
       printf("match2: YES=%d\n",j), 
       elseif (SHOW==1) &  (MATCHVP==1) then printf("match2: NO j= %d\n",j),end
   
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 (match2(CLASSIF,j,PERC,ANIMAT,SHOW) == 0) then MATCHSET(k,:)=CLASSIF(j,:), 
      
       if(SHOW == 1) then
       printf("selectM: selected=%d, k=%d\n",j,k), end
       
      k=k+1,
      end// IF MATCH2
    end// FOR
    
    ANIMAT(13) = MATCHSET
    
endfunction


//***************************************************
// makeCAND
// 
// makeCAND : MATCHSET ---> IDXCAND
// 

function [IDXM,CAND, MATCHSET]=makeCAND(MATCHSET,SHOW)
  
  [r,c]=size(ANIMAT(13))
  MAX=-1
  IDXM=-1
  
  //Searches for the HIGHEST value of REW
  
  for i=1:r,
    if(eval(MATCHSET(i,4)) > MAX) then MAX=eval(MATCHSET(i,4)), IDXM=0, 
      
        if(SHOW == 1) then
          printf("makeCAND: i=%d has MAX=%f\n",i,MAX), 
          end
      
      end
   
 end
 
 // Identifies all elements of MATCHSET which have the highest REW-value
 
 k=1
 CAND=[]
 
   for i=1:r,
    if(eval(MATCHSET(i,4)) == MAX) then CAND(k)=i, k=k+1, 
      
        if(SHOW == 1) 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
 
 //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
  

endfunction

//***************************************************
// Function to fetch the action out of the classifier set
// The actual action will be positioned at position 1, the predecessors are shifted back 1 position each
// Log the action with classifier index in ANIMAT

function [ACT,ACTIONSET,ANIMAT]=action2(IDXM,CAND, MATCHSET,ACTIONSET,ANIMAT)
  
  [r,c]=size(ACTIONSET)
  
  // Shift all classifiers one position 'down' to free position 1
  
  
  i=ANIMAT(9)
  while(i>1),ACTIONSET(i)=ACTIONSET(i-1),i=i-1,end
  
  ACT=MATCHSET(CAND(IDXM),3)
  
  //For the Log in MATCHSET we deliver the whole classifier
  
  ACTIONSET(1,:) = MATCHSET(CAND(IDXM),:) 
  ANIMAT(7) = ACT

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



Gerd Doeben-Henisch 2012-03-31