Build Simple Environments: environment_v6.sci

//**************************************************************
// File: environment_v6.sci
// Authors: Gerd Doeben-Henisch
// Version Start: May-18, 2010
//---------------------------------
// Last Change: Dec-3, 2012, 18:00h
//**********************************************************
// DIARIES
//
// 3.dec 12: added Tolman2 maze
// 3.dec 12: added new envronment-function running until goal is found
//******************************************************************
// CONTENT: 
// Code necessary to provide an environment
// in the style of WOOD1 from Wilson (1994)
//
// [GRID]=gridgen(YYMAX,XXMAX) := Generate a WOOD1-world
// SYSTEMS[] := Table with id's of systems with their X- and Y-coordinates
// MOVES[] := Table with moves of the sytems
//***********************************************************************


//**********************************
// GRID 'WOOD1' 
//
// Y = r=1...15, X = c=1...55
// The Y-axis is from above (north) to bottom (south), the X-axis is from left (west) to right (east)
// '.' := No Food; encoded '00'
// 'O' := Object (Rock); encoded '10'
// 'F' := Food; encoded '11'
// Attention: scilab assumes GRID(Y,X) rows first and then columns!


//********************************************************************
// DYNAMIC GRID GENERATION
// Using the wood1-structure as building blocks
//
// YYMAX := Max number of rows multiplied by 5
// XMAX := Max number of columns multiplied by 5


function[GRID]=gridgen(YYMAX,XXMAX)
  
  if (YYMAX < 1) | (XXMAX < 1) then printf("gridgen:ERROR WITH YYMAX, XXMAX\n\n"), end
  
  for k=1:5:5*YYMAX
  i=k
    for j=1:5*XXMAX, GRID(i+0,j)='.',end
  i=k+1
  for j=1:5:5*XXMAX, 
    GRID(i,j+0)='.'
    GRID(i,j+1)='O'
    GRID(i,j+2)='O'
    GRID(i,j+3)='F'
    GRID(i,j+4)='.'
  end
  i=k+2
  for j=1:5:5*XXMAX, 
    GRID(i,j+0)='.'
    GRID(i,j+1)='O'
    GRID(i,j+2)='O'
    GRID(i,j+3)='O'
    GRID(i,j+4)='.'
  end
  
  i=k+3
  for j=1:5:5*XXMAX, 
    GRID(i,j+0)='.'
    GRID(i,j+1)='O'
    GRID(i,j+2)='O'
    GRID(i,j+3)='O'
    GRID(i,j+4)='.'
  end
  i=k+4
  for j=1:5*XXMAX, GRID(i+0,j)='.',end
  end
  
  disp(GRID)
  
endfunction

//*************************************************************
// TOLMAN's MAZE 1
//
// An environment according to the paper 
// "COGNITIVE MAPS IN RATS AND MEN"
// by Edward C. Tolman (1948)
//First published in The Psychological Review, 55(4), 189-208. 
//
//
TOLMAN1=['O' 'O' 'O' 'O' 'O' 'O' 'O';'O' '.' 'O' 'O' 'O' 'F' 'O'; 'O' '.' 'O' 'O' 'O' '.' 'O'; 'O' '.' '.' '.' '.' '.' 'O'; 'O' 'O' 'O' '.' 'O' 'O' 'O'; 'O' 'O' 'O' 'O' 'O' 'O' 'O' ]

TOLMAN2=['.' '.' '.' '.' '.' '.' '.' '.' 'O' 'O' 'O' '.' '.' '.' '.' '.' '.' '.' '.' '.' '.';
'.' '.' '.' '.' '.' '.' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.' '.' '.' '.' '.' '.';
'.' '.' '.' '.' '.' '.' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.' '.' '.' '.' '.' '.';
'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' '.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O';
'O' '.' '.' '.' '.' '.' '.' '.' '.' '.' 'O' '.' '.' '.' '.' '.' '.' '.' '.' '.' 'O';
'O' 'O' 'O' 'O' '.' 'O' 'O' 'O' 'O' '.' 'O' 'O' 'O' 'O' '.' 'O' 'O' 'O' 'O' 'O' 'O';
'.' '.' '.' 'O' '.' 'O' '.' '.' 'O' '.' 'O' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.';
'.' '.' '.' 'O' '.' 'O' '.' '.' 'O' '.' 'O' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.';
'O' 'O' 'O' 'O' '.' 'O' 'O' 'O' 'O' '.' 'O' 'O' 'O' 'O' '.' 'O' '.' '.' '.' '.' '.';
'.' '.' '.' '.' '.' 'O' '.' '.' '.' '.' '.' '.' '.' '.' '.' 'O' '.' '.' '.' '.' '.';
'O' 'O' 'O' 'O' '.' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' 'O' '.' 'O' '.' '.' '.' '.' '.';
'.' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.';
'.' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.' '.' '.' 'O' '.' 'O' '.' '.' '.' '.' '.';
'.' '.' '.' 'O' 'O' 'O' '.' '.' '.' '.' '.' '.' '.' 'O' 'O' 'O' '.' '.' '.' '.' '.']



//***********************************************************
// SYSTEMS[]
//
// Table with id's of systems with their X- and Y-coordinates
//************************************************************
//COLUMNS: 
// ID - OLD POS - DIR - NEW POS - CONT ENERGY ACTION - ENERGY-LOG
//
// ID := Id of system
// OLD POS := (Y,X)
// DIR := intended direction
// NEW POS := (Y',X')
// CONT := Content of intended new position
// ENERGY := Energy gain/ loss when realizing movement
// ACTION := '0' no movement, '1' movement


SYSTEMS=[1 2 5 0 0 0 0 0 0 0; 2 7 10 0 0 0 0 0 0 0; 3 9 15 0 0 0 0 0 0 0]

// ****************************************
// For Tolman1 Experiment

SYSTEMS2=[1 5 4 0 0 0 0 0 0 0]

// ****************************************
// For Tolman2 Experiment

SYSTEMS3=[1 10 1 0 0 0 0 0 0 0]

//*********************************************************
// EMBED SYSTEMS into GRID
//
// Idea:
// GRID(SYSTEMS1(1,2),SYSTEMS1(1,3))=strcat(["*",string(SYSTEMS1(1,1))])
//*********************************************************************

function [GRID]=embedSysGrid(GRID,SYSTEMS)
    
    sys='*'
    rows=size(SYSTEMS,"r")
    for i=1:rows
        GRID(SYSTEMS(i,2),SYSTEMS(i,3))=strcat([sys,string(SYSTEMS(i,1))])
    end
        
endfunction




//*************************************************
// NEW POSITION
// Having the OLD position POS and the intended movement as DIR, 
// the function computes the NEW Pos
//
// XO, YO := old X-Y-Position
// DIR := direction of move
// XN, XN := new X-Y-Position
//
// ATTENTION : scilab counts Y from 'top = north' downwards to 'down = south'
// Thus to move to the 'north' with '01' you have to subtract '1'
// The same with a move from 'right = east' to the 'left = west'
//



function [YN,XN] =newMove(YO, XO, DIR)
  
  
   //The cells will be searched from 'north' in clockwise order
   
   if DIR == 0 then XN=XO, YN=YO
   elseif DIR == 1 then YN=YO-1, XN=XO
     elseif DIR==2  then YN=YO-1, XN=XO+1
     elseif DIR==3  then YN=YO, XN=XO+1
     elseif DIR==4 then  YN=YO+1, XN=XO+1
     elseif DIR==5 then  YN=YO+1, XN=XO
     elseif DIR==6 then  YN=YO+1, XN=XO-1
     elseif DIR==7  then YN=YO, XN=XO-1
     elseif DIR==8 then  YN=YO-1, XN=XO-1
     else printf("mover:ERROR WITH MOVEMENT AT = (YO,XO) = ( %d,%d)\n",YO,XO)
       end
    
  endfunction


//*************************************************
// RANDOM DIRECTIONS
// Generates movements based on  uniform random numbers from 0 ... 8
//


function [R] =moveRand()
  
  R=floor(9*rand())  
  //printf("mover:RANDOM NUMBER R= %d\n\n",R)
  
    
  endfunction

//***************************************************
// contEncode()
//
// Function to encode the content of a GRID-cell into numbers
// The encoding is as follows:
// '.' := Empty space encoded '0'
// 'O' := Object Rock encoded '2'
// 'F' := Object Food encoded '3'
// '*i' := Other system encoded '4'
// The 'Border' is encoded as '1'

function[SYSTEMS]=contEncode(Y,X,GRID, i,SYSTEMS)
  
  [YMAX, XMAX]=size(GRID)
  
  if (X > XMAX) | (X < 1) | (Y > YMAX) | (Y <1) then SYSTEMS(i,7)=1
    elseif GRID(Y,X) =='.' then SYSTEMS(i,7)=0
    elseif GRID(Y,X) =='O' then SYSTEMS(i,7)=2
    elseif  GRID(Y,X) =='F' then SYSTEMS(i,7)=3
    elseif  part(GRID(Y,X),1:1)=='*' then SYSTEMS(i,7)=4
    else printf("contEncode:ERROR AT CELL =( %d,%d)\n",Y,X)
    end
    
endfunction


//*************************************************
// MOVEMENT EVALUATION
// DEPENDING FROM CONTENT OF NEW PROPOSED POSITION SELECT ACTION
//
// Borderline '1':= -3 (negative reward)
// Object '2'    := -2 (negative reward)
// Empty cell '0':= -1 (move into it, but looses energy)
// Food '3'      := (move into it, reward +1000)
//
// FOODVAL := Global value for energy when intakte of food




function [SYSTEMS] =moveEval(SYSTEMS, i,FOODEVAL)
  
   //CONT = SYSTEMS(i,7)
   //REW = SYSTEMS(i,8)
   //ACT = SYSTEMS(i,9)
   
   if SYSTEMS(i,7) == 1 then SYSTEMS(i,8)=-1, SYSTEMS(i,9)=0
   elseif SYSTEMS(i,7) == 0 then SYSTEMS(i,8)=-2, SYSTEMS(i,9)=1
   elseif SYSTEMS(i,7) == 2 then SYSTEMS(i,8)=-1, SYSTEMS(i,9)=0
   elseif SYSTEMS(i,7) == 3 then SYSTEMS(i,8)=FOODEVAL, SYSTEMS(i,9)=1
   elseif SYSTEMS(i,7) == 4 then SYSTEMS(i,8)=-1, SYSTEMS(i,9)=0
     else printf("moveEval:ERROR WITH MOVEEVAL\n\n")
     end
     
  endfunction
  
  

//*************************************************
// MOVEMENT REALIZATION
//
//
// If the SYSTEMS table shows after the move evaluation a '1' then the new move 
// has to be realized, otherwise not.
// The realization of a move involves the following actions:
//  (1) delete the old position in GRID
//  (2) insert the new position in SYSTEMS by replacing the old one


function [GRID,SYSTEMS] = moveRealization(i,GRID,SYSTEMS)
  
   
   if SYSTEMS(i,9) == 1 then GRID(SYSTEMS(i,2),SYSTEMS(i,3))='.', SYSTEMS(i,2)=SYSTEMS(i,5), SYSTEMS(i,3)=SYSTEMS(i,6)
     end
     
  endfunction
  
  
  
//*************************************************
// ENERGY LOG
//
// Summing up the energy level
// Assuming an initial value for every system

ENERGYSTART=100
FOODEVAL=1000

function [SYSTEMS]=energyLog(SYSTEMS,ENERGYSTART)
    
    [r,c]=size(SYSTEMS)
    
    //Summing the final colum with  the changes of column 8
    for i=1:r, SYSTEMS(i,10)=SYSTEMS(i,10)+SYSTEMS(i,8)
    end
    
endfunction

  
//**********************************************************
// PARTIAL ZEROING
//
// Reset of SYSTEMS forcolumns 5-9
//

function [SYSTEMS]=movesZeroing(SYSTEMS)
    
    [r,c]=size(SYSTEMS)
    for i=1:r
        for j=4:c-1
            SYSTEMS(i,j)=0
            
        end
    end
endfunction

//**********************************************************
// ENVIRONMENT FUNCTION PSI
//
//----------------------------------
// INITIALIZE: 
// - GRID with initial space and objects. 
// - SYSTEMS with initial positions of systems.
// - Embed SYSTEMS in GRID with embedSysGrid()
// 
// LOOP:
// (1) Get new directions from systems (randomly)
// e.g.: for i=1:3,[SYSTEMS(i,4)] =moveRand(),end
// (2) Compute resulting new Positions
//  e.g.: for i=1:3, [SYSTEMS(i,6), SYSTEMS(i,5)]=newMove(SYSTEMS(i,3),SYSTEMS(i,2),SYSTEMS(i,4)), end
// (3) Evaluate possible effects
// (4) Realize movements
// (6) Go to (1)

function [GRID1]=envFunction(GRID,SYSTEMS,RUN, FOODEVAL,ENERGYSTART)
    
    //Initialization
    
    [GRID1]=embedSysGrid(GRID,SYSTEMS)
    disp(GRID1)
    [r,c]=size(SYSTEMS)
    for i=1:r, SYSTEMS(i,10)=ENERGYSTART
    end
    
    //Loop
    
    for k=1:RUN
        
        disp('----------------------------------------------------') 
        disp('CYCLE = ')
        disp(k)
        disp('----------------------------------------------------') 
        
        
        //Insert new move commands randomly
        for i=1:r,[SYSTEMS(i,4)] =moveRand(),end
       
        //if SHOW>0 then disp(SYSTEMS),end
        
        //Compute new resulting positions
        for i=1:r, [SYSTEMS(i,5), SYSTEMS(i,6)]=newMove(SYSTEMS(i,2),SYSTEMS(i,3),SYSTEMS(i,4)), end
        
        //disp(MOVES)
        
        
        //Inspect content of new positions
        for i=1:r, Y=SYSTEMS(i,5), X=SYSTEMS(i,6), [SYSTEMS]=contEncode(Y,X,GRID1, i,SYSTEMS),end
        
        //disp(MOVES)
        
        //Evaluation for Energy and Actions
        // Problems: 
        // More than one system can move on the same Position!
        // The food can disappear without replacement
        for i=1:r, [SYSTEMS] =moveEval(SYSTEMS, i,FOODEVAL), end
        
        //disp(MOVES)
        
        //Realizing the moves
        for i=1:r, [GRID1,SYSTEMS] = moveRealization(i,GRID1,SYSTEMS), end
        //disp(SYSTEMS)
        //disp('-----------------')
        [GRID1]=embedSysGrid(GRID1,SYSTEMS)
        //disp('-----------------')
        //if SHOW>0 then disp(SYSTEMS),end
        
        //Log Energy
        [SYSTEMS]=energyLog(SYSTEMS,ENERGYSTART)
        
        disp(SYSTEMS)
        disp(GRID1)
        
        [SYSTEMS]=movesZeroing(SYSTEMS)
    end
    
    
    
endfunction




//**********************************************************
// ENVIRONMENT FUNCTION now for search of Food
//
//----------------------------------
// INITIALIZE: 
// - GRID with initial space and objects. 
// - SYSTEMS with initial positions of systems.
// - Embed SYSTEMS in GRID with embedSysGrid()
// 
// LOOP:
// (1) Get new directions from systems (randomly)
// e.g.: for i=1:3,[SYSTEMS(i,4)] =moveRand(),end
// (2) Compute resulting new Positions
//  e.g.: for i=1:3, [SYSTEMS(i,6), SYSTEMS(i,5)]=newMove(SYSTEMS(i,3),SYSTEMS(i,2),SYSTEMS(i,4)), end
// (3) Evaluate possible effects
// (4) Realize movements
// (5) When food is found set FOUND=1 and stop while-loop
// (6) Go to (1)

function [GRID1,k]=envFunction(GRID,SYSTEMS, FOODEVAL,ENERGYSTART)
    
    //Initialization
    
    [GRID1]=embedSysGrid(GRID,SYSTEMS)
    disp(GRID1)
    [r,c]=size(SYSTEMS)
    for i=1:r, SYSTEMS(i,10)=ENERGYSTART
    end
    
    //Loop
    FOUND=0, k=0
    while(FOUND<1) //Will become '1' if food has been found
        k=k+1
        
        disp('----------------------------------------------------') 
        disp('CYCLE = ')
        disp(k)
        disp('----------------------------------------------------') 
        
        
        //Insert new move commands randomly
        for i=1:r,[SYSTEMS(i,4)] =moveRand(),end
       
        //disp(SYSTEMS)
        
        //Compute new resulting positions
        for i=1:r, [SYSTEMS(i,5), SYSTEMS(i,6)]=newMove(SYSTEMS(i,2),SYSTEMS(i,3),SYSTEMS(i,4)), end
        
        //disp(MOVES)
        
        
        //Inspect content of new positions
        for i=1:r, Y=SYSTEMS(i,5), X=SYSTEMS(i,6), [SYSTEMS]=contEncode(Y,X,GRID1, i,SYSTEMS),
            if SYSTEMS(i,7) == 3 then FOUND=1,end, 
            end
        
        //disp(MOVES)
        
        //Evaluation for Energy and Actions
        // Problems: 
        // More than one system can move on the same Position!
        // The food can disappear without replacement
        for i=1:r, [SYSTEMS] =moveEval(SYSTEMS, i,FOODEVAL), end
        
        //disp(MOVES)
        
        //Realizing the moves
        for i=1:r, [GRID1,SYSTEMS] = moveRealization(i,GRID1,SYSTEMS), end
        //disp(SYSTEMS)
        //disp('-----------------')
        [GRID1]=embedSysGrid(GRID1,SYSTEMS)
        //disp('-----------------')
        //disp(SYSTEMS)
        
        //Log Energy
        [SYSTEMS]=energyLog(SYSTEMS,ENERGYSTART)
        
        disp(SYSTEMS)
        disp(GRID1)
        
        [SYSTEMS]=movesZeroing(SYSTEMS)
    end
    
    
    
endfunction



Gerd Doeben-Henisch 2013-01-14