Marcello Gomitoni Alberto Guggiola Andrea Martini Francesco Palladino

Simulation models for economics

Project work on

"How to build the perfect museum."

 

The applet requires Java 1.4.1 or higher. It will not run on Windows 95 or Mac OS 8 or 9. Mac users must have OS X 10.2.6 or higher and use a browser that supports Java 1.4. (Safari works, IE does not. Mac OS X comes with Safari. Open Safari and set it as your default web browser under Safari/Preferences/General.) On other operating systems, you may obtain the latest Java plugin from Sun's Java site.


powered by NetLogo

view/download model file: How_to_build_the_perfect_museum.nlogo

WHAT IS IT?

In this model we perform an agent-based simulation of people visiting a museum. The environment has not a fixed geometry, but is easily modifiable using the mouse. Also a set of model parameters is changeable by interface. Our purpose is to evaluate the average degree of satisfaction of all the agents visiting the museum by varying environment and model parameters. It is also possible to implement an alarm dynamics via a switch you can find on the interface.


HOW IT WORKS

Each patch colour indicates a different property of the environmental object (walls are grey, the entrance is red, the exit is blue, artworks are yellow, doors are green, free spaces are black) which agents recognize and with which they interact.
Visitors access the museum by the red entrance in groups of randomly selected sizes separated by variable intervals of time.
The motion of the visitors is constrained by the colour of the patches and follows a few intuitive rules. Each agent possesses a tunable radius of vision and is attracted by doors and artworks he can see. At each time step, in absence of obstacles, each agent move one step (i.e. a patch) towards his target, either a door or an artwork; people that saw an artwork are dynamically stored in an individual list of that artwork, roughly simulating human memory, so that one visitor will not attend twice the same artwork. In presence of obstacles, walls or other people, agents try to avoid them going around, until they reach the following door or fruition area near to an artwork. A given agent has a random interest for each artwork, i.e. the time that he is willing to spend enjoying that artwork. The degree of interest is randomly selected within a fixed range. Once the visit is over, visitors exit through the blue door.


HOW TO USE IT

Starting to use this model you have two choices: if you click on the button 'Setup standard environment' you will achieve a simple configuration in which there are four rooms and an artwork in each of them; otherwise, if you click on the button 'Setup empty environment' you will get an empty closed environment. You can also click on 'Setup model X', where X goes from A to E, achieving different configurations,more complicated than the previous ones.
Anyway you can modify the environment simply using the mouse: you will be able to draw environmental objects just clicking on 'draw' and then selecting on a chooser what you wish to insert (namely a door, an artwork, an entrance, an exit or a wall). Moreover, if you want to delete an object you are allowed to do it. You can also export your world writing it on a .csv file using the 'export world' button; then you will be able to reimport it opening the NetLogo file and using the 'import world' button.

Before starting the simulation you can establish the values of the five model parameters by using the sliders present in the interface:
1) interval: set the time elapsed between the admission of two different visiting groups
2) num_max: set the maximum size of the visiting groups
3) visual_radius: set the agents' radius of vision
4) max_looking_time: set the maximum time each agent will spend enjoying an artwork
5) stray_time: set the maximum time with no object in a room necessary to let an agent escape from that room
Finally you can check the degree of satisfaction of the turtles already exited, number of turtles involved in the simulation and touring time of the turtles by looking the following plots:
1) 'satisfaction'
2) 'turtles'
3) 'life'

Then clicking on 'go' button, the simulation will run indefinitely until you re-click 'go'. Otherwise, a click on 'go once' give you the possibility to run the model only for one tick.


THINGS TO NOTICE AND TO TRY

We notice that modifying the structure of the environment and/or the parameters of the simulation it is possible to increase the average degree of satisfaction of the agentset.


EXTENDING THE MODEL

It could be interesting to introduce some genetic algorithms in order to better select the optimal model parameters.


NETLOGO FEATURES

We used a lot of NetLogo features in order to build this model but some of them were especially significant :
1) the possibility of defining turtles and patches-own variables.
2) the possibility of using dynamical lists to store some important tags.
3) the possibility of drawing environments just using the mouse and to export them.


RELATED MODELS

We started from the work 'Multi agent simulation of pedestrian behaviour in closed spatial environments' developed by Francesca Camillen, Salvatore Capr´┐Ż, Cesare Garofalo, Matteo Ignaccolo, Giuseppe Inturri, Alessandro Pluchino, Andrea Rapisarda and Salvatore Tudisco from the University of Catania ( Italy).


CREDITS AND REFERENCES

http://www.cesaregarofalo.it/pdf/Multiagentsimulationofpedestrianbehaviorinclosedspatialenvironments.pdf


PROCEDURES

patches-own [ tag
              escape_time
            ]

globals [ num_of_obj 
          coord
          visual
          list_turtles_in
          p
          satisfaction
          alarm_time
          p1
          get
        ] 

turtles-own [ 
              time_with_no_object
              looking_time
              control?
              direction
              dist
              see?
              stay?
              life
              time
              object?
              a
              b
            ] 

to setup_standard_environment
  
  ca
  set alarm false
  set visual visual_radius 
  ask patches [set tag [] set escape_time []]
  set list_turtles_in []
  set satisfaction []
  set-default-shape turtles "person" 
  ask patches with [pxcor = max-pxcor or pxcor = min-pxcor or pycor = max-pycor or pycor = min-pycor or pycor = 0 or pxcor = 0]
   [ set pcolor grey ]                                             
 
  ask patches with [(pxcor = round(max-pxcor / 2) or pxcor = round(min-pxcor / 2) and pycor = 0) or (pycor = round(max-pycor / 2) and pxcor = 0) ]
   [ set pcolor green ]                              
 
 ask patches with [pycor = min-pycor and pxcor = round(min-pxcor * 0.75)]
  [ set pcolor red ]                              
 
 ask patches with [pycor = min-pycor and pxcor = round(max-pxcor * 0.75)]
  [ set pcolor blue ]                            
 
 ask patches with [(pxcor = round(max-pxcor / 2) and pycor = round(max-pycor / 2)) or 
                   (pxcor = round(max-pxcor / 2) and pycor = round(min-pycor / 2)) or 
                   (pxcor = round(min-pxcor / 2) and pycor = round(max-pycor / 2)) or 
                   (pxcor = round(min-pxcor / 2) and pycor = round(min-pycor / 2)) 
                  ]
  [ set pcolor yellow ]
  
     
 end

to setup
  ca
  set alarm false
  set visual visual_radius 
  set list_turtles_in []
  set satisfaction []
  ask patches [set tag [] set escape_time []]  
  set-default-shape turtles "person"
  ask patches with [pxcor = max-pxcor or pxcor = min-pxcor or pycor = max-pycor or pycor = min-pycor]
   [ set pcolor grey ] 
                                       
end

to draw
  if mouse-down?
   [ ask patch mouse-xcor mouse-ycor 
     [ if drawing = "Door"  [ set pcolor green ]
       if drawing = "Artwork" [ set pcolor yellow ]
       if drawing = "Wall" [ set pcolor grey ]
       if drawing = "Entrance" [ set pcolor red ]
       if drawing = "Exit" [ set pcolor blue ]
       if drawing = "Delete" [ set pcolor black ]
     ]
   ]
end


to generate
  
 if remainder ticks interval = 0
  [ ifelse any? patches with [ pcolor = red ]
   [ crt random (Num_Max + 0.5)  [ move-to one-of patches with [ pcolor = red ] 
     set time random (max_looking_time) 
     set stay? false 
     set see? true
     set control? false
     set object? false
     set looking_time 0
     set time_with_no_object 0
    ] 
   ]
   [ user-message ( "NO ENTRANCE IN THE MUSEUM !!!" )
   ]
  ]
    
 ask turtles 
  [ if [ pcolor ] of patch-here = red
    [if [ pycor ] of patch-here = min-pycor
        [ set heading 0 fd (1 + random-float 1)
        ]
     if [ pycor ] of patch-here = max-pycor
        [ set heading 180 fd (1 + random-float 1) 
        ]
     if [ pxcor ] of patch-here = min-pxcor
        [ set heading 90 fd (1 + random-float 1)
        ]
     if [ pxcor ] of patch-here = max-pxcor
      [ set heading 270 fd (1 + random-float 1)
      ]
    ]
  ]  
  
 end

to update_door_lists
  
  ask patches with [ pcolor = green ] 
   [ ask turtles-here 
    [ ifelse not member? who [ tag ] of patch-here
     [ set tag fput who tag
       set tag remove-duplicates tag 
       set object? false
     ]
     [ set tag remove who tag ]
    ]
   ]
   
end

to update_artwork_lists   
  
ask patches with [ pcolor = yellow ] 
    [ let a1 ( [ who ] of turtles in-radius 3 with [ stay? = false ] )
      if not empty? a1 
        [ let b1 item 0 a1
          set tag fput b1 tag
          set tag remove-duplicates tag
        ]
     ]
       
end





to look_and_move

if not stay?
 [ ifelse not object? 
   [ set direction heading  
     set p 0
     while [ p < num_of_obj and control? = false ]   
     [ if item 2 item p coord = "angle" or item 2 item p coord = "end_wall" or item 2 item p coord = "exit"
       [ set dist (distance patch (item 0 item p coord) (item 1 item p coord) - 2) ]
       if item 2 item p coord = "artwork" or item 2 item p coord = "door"  
       [ set dist distance patch (item 0 item p coord) (item 1 item p coord) ]
       ifelse dist < visual_radius
         [ set see? true
           facexy (item 0 item p coord) (item 1 item p coord)
           check_walls
           if see? 
           [ if not member? who [ tag ] of patch (item 0 item p coord) (item 1 item p coord)
              [ set a (item 0 item p coord)
                set b (item 1 item p coord)
                move_to_object 
                set control? true
                set object? true
              ]
           ]
        ]
        [ set see? false ]
       set p (p + 1) 
     ]
    
     if p = num_of_obj  
      [ set heading direction 
        ifelse [ pcolor ] of patch a b = grey
          [ let a1 a
            let b1 b 
            ifelse any? patches with [ pcolor = black and count turtles-here = 0 and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) 
                              and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1)
                              and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ]  
           [ let a2 [pxcor ] of one-of patches with [ pcolor = black and count turtles-here = 0 and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) 
                              and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1)
                              and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ]
            let b2 [pycor ] of one-of patches with [ pcolor = black and count turtles-here = 0 and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) 
                              and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1)
                              and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0 ]
             ifelse not member? who [ tag ] of patch a2 b2
               [face patch a2 b2
                move_to_object
               ]
           [  move ]
          ]
           
          
          [ move ]
          ]
          [move]
        set time_with_no_object (time_with_no_object + 1)
      ]   
     set control? false
   ]  
   
   
      [ ifelse [ pcolor ] of patch a b = grey
       [ let a1 a
         let b1 b 
         ifelse any? patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) 
                              and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1)
                              and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0
                            ]
                            [ face one-of patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) 
                                                         and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1)
                                                         and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0
                                                       ]
                            ]
                            [ facexy a b ]
     ]
     [ facexy a b ]
     move_to_object 
   ]

 ]
  
end


to follow_walls
 
 let name who
 let a1 a
 let b1 b
 if object? = true and [pcolor] of patch a b = grey
  [ if distance patch a b <= 2
    [ set object? false
      look_and_move 
      ask patches with [pxcor = a1 and pycor = b1] 
      [ set tag fput name tag
        set tag remove-duplicates tag
      ]
    ]
  ]
 
end

to contemplate 
  
   if [ pcolor ] of patch a b = yellow and distance patch a b <= 3 and time > 0 and not member? who [ tag ] of patch a b 
      [ set stay? true 
        set time (time - 1) 
        set heading heading + (random 10 - 5)
      ]
   
   if time = 0 
    [ set stay? false
      look_and_move
      update_artwork_lists
      set object? false
      set time random max_looking_time
    ]
  
end 


to create_lists_of_objects
  
  let num_turt count turtles with [ life = 1 ]
  set list_turtles_in fput num_turt list_turtles_in
  set list_turtles_in remove 0 list_turtles_in
   
  ask patches [ set coord (list (list 0 0 0 0) (list 0 0 0 0)) ]
  set num_of_obj 0
  ifelse alarm = false
  [
  ask patches with [ pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor) ]
   [ if patch-at 1 0 != nobody and patch-at 0 1 != nobody 
     [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and 
       count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
       [ let a1 (list pxcor pycor "angle" num_of_obj)
         set num_of_obj (num_of_obj + 1)
         set coord remove (list 0 0 0 0) coord
         set coord fput a1 coord
       ]
     ]
 
      if patch-at 1 0 != nobody and patch-at 0 -1 != nobody 
      [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor]  of patch-at 0 -1 = grey and 
        count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
        [ let a1 (list pxcor pycor "angle" num_of_obj)
          set num_of_obj (num_of_obj + 1)
          set coord remove (list 0 0 0 0) coord
          set coord fput a1 coord
        ]
      ]

      if patch-at -1 0 != nobody and patch-at 0 1 != nobody 
       [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and 
         count (neighbors4 with [ pcolor = grey ]) = 2  and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
         [ let a1 (list pxcor pycor "angle" num_of_obj)
           set num_of_obj (num_of_obj + 1)
           set coord remove (list 0 0 0 0) coord
           set coord fput a1 coord
         ]
       ]

      if patch-at -1 0 != nobody and patch-at 0 -1 != nobody 
       [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 -1 = grey and 
         count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
         [ let a1 (list pxcor pycor "angle" num_of_obj)
           set num_of_obj (num_of_obj + 1)
           set coord remove (list 0 0 0 0) coord
           set coord fput a1 coord
         ]  
       ]
 ]
 
  ask patches with [pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor)]
  [  if count neighbors4 with [pcolor = grey] = 1 and count (neighbors4 with [pcolor = blue or pcolor = red or pcolor = green]) = 0
     [ let a1 (list pxcor pycor "end_wall" num_of_obj)
       set num_of_obj (num_of_obj + 1)
       set coord remove (list 0 0 0 0) coord
       set coord fput a1 coord
     ]
  ]
ask patches with [pcolor = blue]
[let a1 (list pxcor pycor "exit" num_of_obj)
 set num_of_obj (num_of_obj + 1)
 set coord remove (list 0 0 0 0) coord
  set coord fput a1  coord
  ]

ask patches with [pcolor = green]
[  let a1 (list pxcor pycor "door" num_of_obj)
  set num_of_obj (num_of_obj + 1)
  set coord fput a1 coord
]

ask patches with [pcolor = yellow]
[ let a1 (list pxcor pycor "artwork" num_of_obj)
  set num_of_obj (num_of_obj + 1)
  set coord fput a1 coord
]
  ]
  
  
  
  
  [
    
        ask patches with [ pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor) ]
   [ if patch-at 1 0 != nobody and patch-at 0 1 != nobody 
     [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and 
       count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
       [ let a1 (list pxcor pycor "angle" num_of_obj)
         set num_of_obj (num_of_obj + 1)
         set coord remove (list 0 0 0 0) coord
         set coord fput a1 coord
       ]
     ]
 
      if patch-at 1 0 != nobody and patch-at 0 -1 != nobody 
      [ if [ pcolor ] of patch-at 1 0 = grey and [ pcolor]  of patch-at 0 -1 = grey and 
        count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
        [ let a1 (list pxcor pycor "angle" num_of_obj)
          set num_of_obj (num_of_obj + 1)
          set coord remove (list 0 0 0 0) coord
          set coord fput a1 coord
        ]
      ]

      if patch-at -1 0 != nobody and patch-at 0 1 != nobody 
       [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 1 = grey and 
         count (neighbors4 with [ pcolor = grey ]) = 2  and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
         [ let a1 (list pxcor pycor "angle" num_of_obj)
           set num_of_obj (num_of_obj + 1)
           set coord remove (list 0 0 0 0) coord
           set coord fput a1 coord
         ]
       ]

      if patch-at -1 0 != nobody and patch-at 0 -1 != nobody 
       [ if [ pcolor ] of patch-at -1 0 = grey and [ pcolor ] of patch-at 0 -1 = grey and 
         count (neighbors4 with [ pcolor = grey ]) = 2 and count (neighbors4 with [ pcolor = blue or pcolor = red or pcolor = green ]) = 0
         [ let a1 (list pxcor pycor "angle" num_of_obj)
           set num_of_obj (num_of_obj + 1)
           set coord remove (list 0 0 0 0) coord
           set coord fput a1 coord
         ]  
       ]
 ]
    
    
    
    
        ask patches with [pcolor = grey and (pxcor != max-pxcor) and (pxcor != min-pxcor) and (pycor != max-pycor) and (pycor != min-pycor)]
  [  if count neighbors4 with [pcolor = grey] = 1 and count (neighbors4 with [pcolor = blue or pcolor = red or pcolor = green]) = 0
     [ let a1 (list pxcor pycor "end_wall" num_of_obj)
       set num_of_obj (num_of_obj + 1)
       set coord remove (list 0 0 0 0) coord
       set coord fput a1 coord
     ]
  ]
    
    
    
    
        ask patches with [pcolor = green]
[  let a1 (list pxcor pycor "door" num_of_obj)
  set num_of_obj (num_of_obj + 1)
  set coord fput a1 coord
]
    
    
    
     ask patches with [pcolor = blue]
[let a1 (list pxcor pycor "exit" num_of_obj)
 set num_of_obj (num_of_obj + 1)
 set coord remove (list 0 0 0 0) coord
  set coord fput a1  coord
  ]
  
   
    
  ]
    end


to escape_room
  
  let name who
  set p1 0 
  while [ p1 < num_of_obj ]
   [ if (item 2 item p1 coord) = "door" 
     [ set direction heading
        set dist distance patch (item 0 item p1 coord) (item 1 item p1 coord)
        facexy (item 0 item p1 coord) (item 1 item p1 coord)
      set see? true
      check_walls
      if see? = true
      [ ask patch (item 0 item p1 coord) (item 1 item p1 coord)
        [ set tag remove name tag ]
      ]
    ]
    set p1 (p1 + 1) 
    set heading direction
  ] 
  set time_with_no_object 0
  look_and_move
 
end

to check_alarm
  
    if alarm
    [ ask turtles 
          [ set num_max 0 
            set stay? false]
      
       if alarm_time = 0 
          [ ask turtles [ clear_doors ] ]
       set alarm_time (alarm_time + 1)
   ]

end


to clear_doors
  
  let ausiliaria who
  ask patches with [ pcolor = green ] 
    [ set tag remove ausiliaria tag ]
  set time_with_no_object 0
    
end


to go 

random-seed new-seed

generate                                                                   

 tick
 ask turtles [ set life (life + 1) ]

create_lists_of_objects

ask patches with [ pcolor = green ] 
   [ ask turtles-here 
    [ ifelse not member? who [ tag ] of patch-here
     [ set tag fput who tag
       set tag remove-duplicates tag 
       set object? false
     ]
     [ set tag remove who tag ]
    ]
   ]
check_alarm                                                              

ask turtles
[ let a1 a
  let b1 b
  if any? patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) 
                              and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1)
                              and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0] 
     [ ask patches with [ pcolor = black and (count neighbors with [ pcolor = grey ] = 1) and (count neighbors4 with [ pcolor = grey ] = 0) 
                              and (pxcor = a1 + 1 or pxcor = a1 - 1) and (pycor = b1 + 1 or pycor = b1 - 1)
                              and count neighbors with [pcolor = green or pcolor = red or pcolor = blue] = 0] 
     [ ask turtles-here 
       [if not member? who [tag] of patch-here
         [ set tag fput who tag
           set tag remove-duplicates tag 
         ]
       ]
     ]
     ]
]   
ask turtles 
 [ look_and_move ]

ask turtles with [ time_with_no_object >= stray_time ]
 [ ifelse alarm   [ clear_doors ]
   [ escape_room ]
 ]


ask turtles [ contemplate ]
 
 
 ask patches with [ pcolor = blue ]                                  
  [ ask turtles-here
    [ set escape_time fput life escape_time ]
  ]

ask turtles 
 [ if stay? = true 
   [ set looking_time looking_time + 1 ]
 ]

 
 ask patches with [ pcolor = blue ]                                       
  [ ask turtles-here 
    [ set satisfaction fput ( looking_time / life ) satisfaction ]
  ]
   
   ask turtles 
     [ if [ pcolor ] of patch-here = blue 
       [ die ]
     ]  
   
   
   ask turtles 
    [ if [ pcolor ] of patch-here = green
      [ update_door_lists
        set object? false
        look_and_move
      ]
    ]
    ask patches with [ pcolor = blue ]                                
      [ do-plots ]                         

ask turtles
  [ follow_walls ]
  
  

end



to move   
  ifelse patch-ahead 1 != nobody    
    [ ifelse not any? turtles-on patch-ahead 1                  
      [ ifelse [ pcolor ] of patch-ahead 1 != grey and [ pcolor ] of patch-ahead 1 != yellow 
        [ fd random-float 1 ]                                                                                                                             
        [ ifelse (random 2) - 0.5 > 0  
          [ set heading heading + (100 + random-float 10) 
            move
          ]
          [ set heading heading - (100 + random-float 10) 
            move
          ]
        ]
     ]    
     [turn_and_go]
   ]
   [ set heading heading + 90 ]
        
 end

to check_walls
  
     if dist > 0 
      [ ifelse patch-ahead dist != nobody
        [ ifelse [ pcolor ] of patch-ahead dist = grey 
          [ set see? false ]      
          [ set dist (dist - 1)
            check_walls
          ]
        ]
        [ set see? false ]
     ]
     
end

to move_to_object
  ifelse [ pcolor ] of patch a b = green 
     [ set direction heading  
       set p 0
       while [ p < num_of_obj and control? = false ]   
        [ if item 2 item p coord = "artwork" 
          [ set dist distance patch (item 0 item p coord) (item 1 item p coord) 
            ifelse dist < visual_radius
            [ set see? true
              facexy (item 0 item p coord) (item 1 item p coord)
              check_walls
              if see? 
              [ if not member? who [ tag ] of patch (item 0 item p coord) (item 1 item p coord)
                [ set a (item 0 item p coord)
                   set b (item 1 item p coord)
                   if [ pcolor ] of patch-here = blue [ die ] 
                   move_to_object 
                   set control? true
                   set object? true
                 ]
              ]
           ]
         [ set see? false ]
         ]
       
       set p (p + 1) 
        ]
        
       if p = num_of_obj  
      [ set heading direction 
        if patch-ahead 1 != nobody 
         [ ifelse not any? other turtles-on patch-ahead 1 and ([pcolor] of patch-ahead 1 != yellow and [pcolor] of patch-ahead 1 != grey)
           [ fd 1 ]
           [ turn_and_go ]
         ]   
     set control? false
      ]  
    ] 
    [ 
      if patch-ahead 1 != nobody 
      [ ifelse not any? other turtles-on patch-ahead 1 and ([pcolor] of patch-ahead 1 != yellow and [pcolor] of patch-ahead 1 != grey)
         [ fd 1 ]  
         [ turn_and_go ] 
      ] 
    ] 
     
end


to turn_and_go
  
   set heading heading + (random 60 - 30)  
     ifelse patch-ahead 1 != nobody
       [ ifelse not any? other turtles-on patch-ahead 1  and ([ pcolor ] of patch-ahead 1 != grey and [ pcolor ] of patch-ahead 1 != yellow) 
            [ fd 1 ]
            [ set object? false 
              ifelse (random 2) - 0.5 > 0  
              [ let h random-float 10 
                if  patch-at-heading-and-distance (heading + 100 + h)  1 != nobody
                [if not any? other turtles-on patch-at-heading-and-distance (heading + 100 + h)  1 and 
                   [ pcolor ] of patch-at-heading-and-distance (heading + 100 + h)  1 != grey and 
                   [ pcolor ] of patch-at-heading-and-distance (heading + 100 + h)  1 != yellow
                [set heading (heading + 100 + h) fd 1]]
         
                
             ]
              [ let h random-float 10 
                if  patch-at-heading-and-distance (heading - 100 + h)  1 != nobody
                [if not any? other turtles-on patch-at-heading-and-distance (heading - 100 + h)  1 and 
                   [ pcolor ] of patch-at-heading-and-distance (heading - 100 + h)  1 != grey and 
                   [ pcolor ] of patch-at-heading-and-distance (heading - 100 + h)  1 != yellow
                [set heading (heading - 100 + h) fd 1]]
              
                
             ]
            ]
       ]
        [ ifelse (random 2) - 0.5 > 0 
         [ set heading heading + (100 + random-float 10) ]
         [ set heading heading - (100 + random-float 10) ]
       ]
      
end


to do-plots
  
  set-current-plot "Turtles"         
  
  set-current-plot-pen "inside"
  plot count turtles                
  
  set-current-plot-pen "escaped"
  plot sum [length escape_time] of patches
  
  set-current-plot-pen "entered"
  plot sum list_turtles_in
  
  
  
  
  set-current-plot "Satisfaction"
  set-current-plot-pen "time_view_artwork"
  set-plot-y-range 0 (sum [length escape_time] of patches + 1)
  set-histogram-num-bars number_of_bars
   
  histogram satisfaction
  
   
  
  
  set-current-plot "Life"
  set-current-plot-pen "lifetime"
  set-plot-y-range 0 (sum [length escape_time] of patches + 1)
  if escape_time != []
  [set-plot-x-range 0 max escape_time + 1
   set-histogram-num-bars (max escape_time + 1) / interval_width
   ]
  
  histogram escape_time
  set get escape_time
end