This page was automatically generated by NetLogo 5.0.4.

The applet requires Java 5 or higher. Java must be enabled in your browser settings. Mac users must have Mac OS X 10.4 or higher. Windows and Linux users may obtain the latest Java from Oracle's Java site.

The evaluation of this model was written up with Scott Weingart and submitted to a special issue of the Journal of Archaeological Method and Science, where it is currently under review. This instantiation presented here is for use with Graham's CLCV3202a, Fall 2013 term.

powered by NetLogo

view/download model file: Modeling Roman Bazaar.nlogo

This model is based on the ‘Wealth Distribution’ model by Uri Wilensky (copyright 1998), which is itself a reimplementation of the well-known Sugarscape model.

Creative Commons Licence
This extension to the wealth distribution model is licensed under a Creative Commons Attribution 3.0 Unported License Shawn Graham, Scott Weingart.

Model code was updated on September 25th 2013. Graham commented out some of the residual code snippets, especially those elements that print output to the command window.


  percent-best-land    ; maximum amount any patch can hold

patches-own ;; 
  resource-here      ; the current amount of resource on this patch
  max-resource-here  ; the maximum amount of resource this patch can hold
 ; impact

  age              ; how old a turtle is
  wealth           ; the amount of resource a turtle has
  life-expectancy  ; maximum age that a turtle can reach
  metabolism       ; how much resource a turtle eats each time. Think of this as 'transaction cost'.
  vision           ; how many patches ahead a turtle can see. Think of this as 'knowledge of the world'.


to setup
  ;; (for this model to work with NetLogo's new plotting features,
  ;; __clear-all-and-reset-ticks should be replaced with clear-all at
  ;; the beginning of your setup procedure and reset-ticks at the end
  ;; of the procedure.)
  if seed? [random-seed 1066] ;; if the 'seed?' switched is turned on, the same sequence of random numbers will be generated each run. This allows the user to test the effect of different settings, code changes etc.
  ;; set global variables to appropriate values
  set max-resource maximum-resources
  ;; call other procedures to set up various parts of the world

  ask turtles [set am-dead? false
               set am-competing false
               set my-clients []
               set prestigiousness []
               set global-class []
               set my-obligations []
  ;; plot the initial state of the world

;;;important to note that ticks does not map 1:1 to 'years'. Better to think of things in terms of generations; 

to setup-resources ;;; change these settings to better represent the resource under consideration.
  if Resource-Settings = "Wild Woodland"
     [set resource-growth-interval 4 ;; number of cycles between growth. the lower the number, the more 'permanent' this resource can be treated.
      set num-resource-grown 1 ;;how much resource is grown each time the resource-growth-interval allows that to happen
      set maximum-resources 100 ;;maximum amount a patch may hold
      set percent-best-land 4  ;; density of patches
      ;;so I'm saying that wild woodland regenerates slowly, and a limited productivity
 if Resource-Settings = "Coppiced Woodland"
     [set resource-growth-interval 2 ;; regenerates periodically
      set num-resource-grown 5
      set maximum-resources 1000  ;;managed woodland higher productivity, more uses, than wild woodland.
      set percent-best-land 4
      ;;in comparison to wild woodland, coppicing regenerates quicker, and more densely, with more uses, than wild woodland
if Resource-Settings = "Mines"
     [set resource-growth-interval 1; instant growback means that the seam does not get exhausted.
      set num-resource-grown 1000
      set maximum-resources 1000000000000000
      set percent-best-land 1 ; very rare
      ;; mines exist, they do not regenerate. *but* they don't get mined out either, in this model. but they can go out of production for other reasons.
if Resource-Settings = "Clay"
     [set resource-growth-interval 1; instant growback means that the seam does not get exhausted.
      set num-resource-grown 1000
      set maximum-resources 1000 ;; 
      set percent-best-land 3 ;; more common

;; set up the initial amounts of resource each patch has
to setup-patches
  ;; give some patches the highest amount of resource possible --
  ;; these patches are the "best land"
  ask patches
    [ set is-settlement? false
      set max-resource-here 0
      if (random-float 100.0) <= percent-best-land
        [ set max-resource-here max-resource
          set resource-here max-resource-here ] ]
  ;; spread that resource around the window a little and put a little back
  ;; into the patches that are the "best land" found above
  if Resource-Settings = "Wild Woodland" or Resource-Settings = "Coppiced Woodland" ;;smearing a bit different for these ones, in terms of how far.
   [repeat 5
    [ ask patches with [max-resource-here != 0]
        [ set resource-here max-resource-here ]
      diffuse resource-here 0.25 ]
  repeat 10
    [ diffuse resource-here 0.25 ]          ;; spread the resource around some more
  ask patches
    [ set resource-here floor resource-here    ;; round resource levels to whole numbers
      set max-resource-here resource-here      ;; initial resource level is also maximum
      recolor-patch ]

to recolor-patch  ;; patch procedure -- use color to indicate resource level
  if is-settlement? = false [set pcolor scale-color yellow resource-here 0 max-resource]

;;to visualize-land-impact  ;; snippet of code to get a visualization of where turtles have been wandering. currently turned off.
;; set pcolor scale-color red land-impact 1000 1
;;  end

;; set up the initial values for the turtle variables

;;;nb each turtle can be considered to represent a single family;;

to setup-turtles
  set-default-shape turtles "person"
  crt num-people
    [ move-to one-of patches  ;; put turtles on patch centers
      set size 1.5  ;; easier to see
      set age random life-expectancy ]

to set-initial-turtle-vars
  set age 0
  face one-of neighbors4
  set life-expectancy life-expectancy-min +
                        random (life-expectancy-max - life-expectancy-min + 1)
  set metabolism 5 + random metabolism-max
  ifelse wealth <= 0 [set wealth metabolism + random 50]
                    [set wealth wealth + (random-float 1 * wealth)];; some wealth carries on over the generations
  ifelse (color = blue) [set vision vision + random max-vision] 
                              [ifelse (color = green) [set vision (vision - 2) + random vision] 
                                                [set vision 1 + random max-vision]
  if (vision <= 0) [set vision 1 + random max-vision]  ;; blues have a better knowledge of the world, greens slightly less, reds poor. vision - knowledge - is inheritable
  set generation generation + 1
  if prestige < 0 [set prestige 1]
  if generation > 1 [set prestige (random-float 1 * prestige)] ;; not every generation carries the family name well.

;; Set the class of the turtles -- if a turtle has less than a third
;; the wealth of the richest turtle, color it red.  If between one
;; and two thirds, color it green.  If over two thirds, color it blue.
to recolor-turtles
ask turtles
  let local-turtles turtles in-radius (vision); + (vision * random-float 1))
  let max-wealth max [wealth] of local-turtles ;; local status per wealth set according to your local neighborhood. Of course, how far you can see also depends on your color.
     ifelse (wealth <= max-wealth / 3)
        [ set color red ]
        [ ifelse (wealth <= (max-wealth * 2 / 3))
            [ set color green ]
            [ set color blue ] ] 

ask turtles[let max-prestige max [prestige] of turtles ;; measuring global prestige. locally, wealth gives you your status. you enhance your prestige locally
                                                       ;; but you also go to a central place every so often to compete there. success/failure there has reprecussions
     ifelse (prestige <= max-prestige / 3)
        [ set prestigiousness "low" ]
        [ ifelse (prestige <= (max-prestige * 2 / 3))
            [ set prestigiousness "mid" ]
            [ set prestigiousness "high" ] ]   

ask turtles [let max-wealth max [wealth] of turtles ;; measuring global class per wealth
     ifelse (wealth <= max-wealth / 3)
        [ set global-class "low" ]
        [ ifelse (wealth <= (max-wealth * 2 / 3))
            [ set global-class "mid" ]
            [ set global-class "high" ] ] 


to-report generations
report mean ([generation] of turtles)

to go
  ;if count patches with [pcolor = blue] > (count patches * 1 / 10) [print " game over" stop]
  if generations >= 50 [print " game over" stop]
  ask turtles
   [if am-dead? [stop]]
  ask turtles
    [ turn-towards-resource
      ]  ;; choose direction holding most resource within the turtle's vision
  ask turtles
    [ move-eat-age-die ]

  ;; grow resource every resource-growth-interval clock ticks
  if ticks mod resource-growth-interval = 0
    [ ask patches [ grow-resource ] ]

 ask turtles
     if ticks mod resource-growth-interval = 0 [calculate-clients-worth 
                                             patron-compete];; at the end of each growing cycle, that's when the games of patronage are played; once a season.

  if ticks mod 25 = 0 [ask patches [grow-settlement]]

;; determine the direction which is most profitable for each turtle in
;; the surrounding patches within the turtles' vision
to turn-towards-resource  ;; turtle procedure
  set heading 0
  let best-direction 0
  let best-amount resource-ahead
  set heading 45
  if (resource-ahead > best-amount)
    [ set best-direction 45
      set best-amount resource-ahead ]
  set heading 90
  if (resource-ahead > best-amount)
    [ set best-direction 90
      set best-amount resource-ahead ]
set heading 135
  if (resource-ahead > best-amount)
    [ set best-direction 135
      set best-amount resource-ahead ]
  set heading 180
  if (resource-ahead > best-amount)
    [ set best-direction 180
      set best-amount resource-ahead ]
set heading 225
  if (resource-ahead > best-amount)
    [ set best-direction 225
      set best-amount resource-ahead ]
  set heading 270
  if (resource-ahead > best-amount)
    [ set best-direction 270
      set best-amount resource-ahead ]
  set heading 315
  if (resource-ahead > best-amount)
    [ set best-direction 315
      set best-amount resource-ahead ]
  set heading best-direction

to-report resource-ahead  ;; turtle procedure
  let total 0
  let how-far 1
  repeat vision
    [ set total total + [resource-here] of patch-ahead how-far
      set how-far how-far + 1 ]
  report total

to grow-resource  ;; patch procedure
  ;; if a patch does not have it's maximum amount of resource, add
  ;; num-resource-grown to its resource amount
  if pcolor = blue [set resource-here 0 stop]
  if (resource-here < max-resource-here)
    [ set resource-here resource-here + num-resource-grown
      ;; if the new amount of resource on a patch is over its maximum
      ;; capacity, set it to its maximum
      if (resource-here > max-resource-here)
        [ set resource-here max-resource-here ]  
      if is-settlement? = false [recolor-patch]

;; each turtle harvests the resource on its patch.  if there are multiple
;; turtles on a patch, divide the resource evenly among the turtles
to harvest
  ; have turtles harvest before any turtle sets the patch to 0
  diffuse magnifier .5 ;; 
  ask turtles
    [ifelse is-settlement? = true 
      [ ifelse resource-here > mean ([resource-here] of patches) or length my-obligations <= 1 ;; want a decision to be made to harvest, even when resource is on the decline. 
                                                                                   ;; this decision should be based on how embedded in social networks one is.
                                                                                   ;; so, if there's lots of resource, no problem
                                                                                   ;; but if there isn't, and we're socially embedded, we won't overexploit the resource
                                                                                   ;; but if we're not socially embedded (we have no obligations)
                                                                                   ;; we'll just go ahead and grab the resource anyway.
         [ set wealth floor (wealth + ((resource-here / (count turtles-here))) * magnifier)
           set land-impact land-impact + 1
           set resource-here 0
           ;show "I harvested!!"
         [ move-eat-age-die]       ] 
  ;;a code snippet for an alternative imagining:    
  ;; now that the resource has been harvested, have the turtles make the
  ;; patches which they are on have no resource
  ;set family-fortune .5 * wealth
  ;set wealth wealth - family-fortune  ;; we're having families save some coin.

;;;  ask turtles
;;;    [ set land-impact land-impact + 1
;;;      set resource-here 0
;;;      recolor-patch
;;;       ]
  diffuse land-impact 0.2  

to extract-wealth-from-clients
foreach my-clients
 [ ask ?
   [;show "I am a client"
     if wealth = 0 [set wealth 1] ;; we will not beggar our clients
     let amount-extracted (.1 * (wealth))
   set wealth ([wealth] of ? - amount-extracted)
   ;show amount-extracted show "wealth I've lost!"
   ask myself [set wealth ([wealth] of myself + amount-extracted)
 ;show wealth show "wealth I've gained!"
to move-eat-age-die  ;; turtle procedure
  fd 1
  ;; consume some resource according to metabolism
  set wealth (wealth - metabolism)
  ;; grow older
  set age (age + 1)

  if (wealth < metabolism) 
      [;show " is asking for help"

  ;; check for death conditions: if you have no resource or
  ;; you're older than the life expectancy or if some random factor
  ;; holds, then you "die" and are "reborn" (in fact, your variables
  ;; are just reset to new random values)
  if wealth < 0 or (age >= life-expectancy);; or (family-fortune < 0)
    [ set-initial-turtle-vars ]

to ask-for-help

ifelse random-float 1 > 0.99 [
let local-turtle one-of (turtles in-radius vision with [prestige >= ([prestige] of self) and self != myself]);; trying to find one of its betters
;show local-turtle 
;show wealth
if local-turtle != nobody 
  [ask local-turtle
      [; show "is giving help to " (print myself)
        let gift (0.1 * wealth) ; gives one tenth to those who ask
        set prestige prestige + gift  ;;; and he's getting some prestige
        set wealth wealth - gift;
        ;show gift
       ; show " gained some prestige by giving to " (print myself)
       ; show prestige ;; these three lines are useful for debugging
        ask myself [set wealth wealth + gift] ;;; the local turtle needs to set my wealth wealth + gift
        set my-clients fput myself my-clients]
       set my-obligations fput local-turtle my-obligations

      ]  ;;; so I'm getting a gift
  ;show  " got some help" 
  ;show wealth ;; these two lines are useful for debugging

;;;to-report top-prestige
;;;  let max-prestige max [prestige] of turtles
;;;  report count turtles with [prestige > max-prestige * 2 / 3]
;;;to-report low-prestige
;;;let max-prestige max [prestige] of turtles
;;;report count turtles with [prestige <= max-prestige / 3]
;;;to-report mid-prestige
;;;  let top top-prestige
;;;  let bottom low-prestige
;;;  report bottom - top
;;;end  ;; this routine is from the original model, and might be useful for visualizing outputs.

to euergetism
  let max-prestige max [prestige] of turtles
  if (prestige > (max-prestige * 1 / 2))
    [build-super-improvement]   ;;; global elites.
  if (color = blue) [build-improvement] ;; local elite   

to build-improvement
  let local-value prestige
  ask patch-here [set magnifier magnifier + (local-value * 0.1)]

to build-super-improvement
  let local-value prestige
  ask patch-here [set magnifier magnifier + (local-value * 0.5)]

to grow-settlement
  ;ask patches with [pcolor < 15] 
  ;[set pcolor blue
  ;  set is-settlement? true
   ; set resource-here 0]  ;; these five lines are an alternative approach, but not used in the runs discussed in the paper.
   let max-impact max [land-impact] of patches
   if (land-impact > (max-impact * (99 / 100)))
    [set is-settlement? true
     set resource-here 0
     set pcolor blue] 


to my-setup-plots
  ;set-current-plot "Class Plot"
  ;set-plot-y-range 0 num-people
  set-current-plot "Local Class Histogram"
  set-plot-y-range 0 num-people
  set-current-plot "Games of Patronage"
  ;set-plot-y-range 0 num-people
  set-current-plot "Global Class Histogram"
  ;set-plot-y-range 0 num-people

to my-update-plots

;; this does a line plot of the number of people of each class
to update-games-plot
  set-current-plot "Games of Patronage"

;;  set-plot-pen-color red
;;  plot count turtles with [prestigiousness = "low"]
  set-current-plot-pen "mid"
;  set-plot-pen-color green
  plot count turtles with [prestigiousness = "mid"]
 ; set-plot-pen-color blue
 set-current-plot-pen "high"
  plot count turtles with [prestigiousness = "high"]

to update-class-plot
  set-current-plot "Class Plot"
  set-current-plot-pen "low"
  plot count turtles with [color = red]
  set-current-plot-pen "mid"
  plot count turtles with [color = green]
  set-current-plot-pen "up"
  plot count turtles with [color = blue]

;; this does a histogram of the number of people of each class
to update-local-class-histogram
  set-current-plot "Local Class Histogram"
  set-plot-pen-color red
  plot count turtles with [color = red]
  set-plot-pen-color green
  plot count turtles with [color = green]
  set-plot-pen-color blue
  plot count turtles with [color = blue]

to update-global-class-histogram
  set-current-plot "Global Class Histogram"
  set-plot-pen-color red
  plot count turtles with [global-class = "low"]
  set-plot-pen-color green
  plot count turtles with [global-class = "mid"]
  set-plot-pen-color blue
  plot count turtles with [global-class = "high"]

to update-lorenz-and-gini-plots
  set-current-plot "Lorenz Curve"

  ;; draw a straight line from lower left to upper right
  set-current-plot-pen "equal"
  plot 0
  plot 100

  set-current-plot-pen "lorenz"
  set-plot-pen-interval 100 / num-people
  plot 0

  let sorted-wealths sort [wealth] of turtles
  let total-wealth sum sorted-wealths
  let wealth-sum-so-far 0
  let index 0
  let gini-index-reserve 0

  ;; now actually plot the Lorenz curve -- along the way, we also
  ;; calculate the Gini index.
  ;; (see the Information tab for a description of the curve and measure)
  repeat num-people [
    set wealth-sum-so-far (wealth-sum-so-far + item index sorted-wealths)
    plot (wealth-sum-so-far / total-wealth) * 100
    set index (index + 1)
    set gini-index-reserve
      gini-index-reserve +
      (index / num-people) -
      (wealth-sum-so-far / total-wealth)

  ;; plot Gini Index
  set-current-plot "Gini-Index v. Time"
  plot (gini-index-reserve / num-people) / 0.5

to open-file
  let file user-new-file
  if ( file != false )
    if ( file-exists? file )
      [ file-delete file ]
    file-open file

to write-to-file  
   file-show my-clients
  file-show my-obligations                

to patron-compete
  ;show length my-clients
  ifelse length my-clients > 1 ;; base line for the competition
  set my-home patch-here
  setxy 0 0
  ;show "i am about to compete"
  ;show length my-clients print " and these are how many supporters I have" ;;these two lines are useful whilst running the model to keep track of what's going on

to calculate-clients-worth
  foreach my-clients
 [ ask ?
   [ let dosh wealth
     ask myself [set clients-worth clients-worth + dosh]

to compete  
  let competitor one-of turtles-here with [color = [color] of myself and length my-clients > 0] ;; local elites come together, pair off against their peers
  ifelse competitor != nobody and competitor != self
     set am-competing true
     ;show "I'm competing against"
    ; ask competitor [show "...yes, against me" ]
     ifelse clients-worth >= ([clients-worth] of competitor) or (length my-clients) >= length [my-clients] of competitor   ;; quality first, then number of clients! (quality can trump number)
     [set prestige prestige + 8
       set games-won games-won + 1;;; 
           extract-wealth-from-clients ;;; this is where obligations are repaid.      
      ask competitor 
          [ ;show "I am the competitor, and I lost"
            ;show ([prestige] of self) ;; these two lines are useful for debugging the model
            set prestige ([prestige] of self - 10)
            ;show ([prestige] of self)
            set games-won games-won - 1
           ];; my prestige goes up, but yours goes down more because you lost.
     [set prestige prestige - 10
      set games-won games-won - 1
      ask competitor
       [;show "I am the competitor, and I won"
        ;show ([prestige] of self) ;; these two lines are useful for debugging the model
        set prestige ([prestige] of self + 8)
        ;show ([prestige] of self)
        extract-wealth-from-clients ;;; nb wealth is a proxy for their support, repaying the gifts that the patron has already given them 
        set games-won games-won + 1]


to go-home
  while [ patch-here != (my-home)]
      [set heading towards (my-home)
       ;set going-home? true
           jump 1
      set am-competing false 
      set clients-worth 0 
;;setxy my-home


; Original Wealth Distribution Model is Copyright 1998 Uri Wilensky. All rights reserved.
; This extension of the model is Creative Commons Licensed Graham & Weingart