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.
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.
globals [ max-resource num-resource-grown resource-growth-interval maximum-resources 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 land-impact magnifier cluster is-settlement? ; impact ] turtles-own [ 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'. generation prestige am-dead? my-clients my-home am-competing prestigiousness global-class clients-worth games-won my-obligations ] ;;; ;;; SETUP AND HELPERS ;;; 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.) __clear-all-and-reset-ticks 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. setup-resources ;; set global variables to appropriate values set max-resource maximum-resources ;; call other procedures to set up various parts of the world setup-patches setup-turtles ask turtles [set am-dead? false set am-competing false set my-clients  set prestigiousness  set global-class  set my-obligations  ] my-setup-plots ;; plot the initial state of the world my-update-plots end ;;;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 ] end ;; 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 ] end 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] end ;;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-initial-turtle-vars set age random life-expectancy ] recolor-turtles end 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. end ;; 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" ] ] ] end ;;; ;;; GO AND HELPERS ;;; to-report generations report mean ([generation] of turtles) end 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 harvest ask turtles [ move-eat-age-die ] recolor-turtles ;; grow resource every resource-growth-interval clock ticks if ticks mod resource-growth-interval = 0 [ ask patches [ grow-resource ] ] ask turtles [euergetism 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]] tick my-update-plots end ;; 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 end 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 end 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] ] end ;; 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 [move-eat-age-die] [ 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 recolor-patch ;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 end 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!" end 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" ask-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 ] end 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 ] [stop] end ;;;to-report top-prestige ;;; let max-prestige max [prestige] of turtles ;;; report count turtles with [prestige > max-prestige * 2 / 3] ;;;end ;;; ;;;to-report low-prestige ;;;let max-prestige max [prestige] of turtles ;;;report count turtles with [prestige <= max-prestige / 3] ;;;end ;;; ;;;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 end to build-improvement let local-value prestige ask patch-here [set magnifier magnifier + (local-value * 0.1)] end to build-super-improvement let local-value prestige ask patch-here [set magnifier magnifier + (local-value * 0.5)] end to grow-settlement ;visualize-land-impact ;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] end ;;; ;;; PLOTTING ;;; 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 end to my-update-plots ;update-class-plot update-local-class-histogram update-lorenz-and-gini-plots update-games-plot update-global-class-histogram end ;; 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"] end 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] end ;; this does a histogram of the number of people of each class to update-local-class-histogram set-current-plot "Local Class Histogram" plot-pen-reset 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] end to update-global-class-histogram set-current-plot "Global Class Histogram" plot-pen-reset 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"] end to update-lorenz-and-gini-plots set-current-plot "Lorenz Curve" clear-plot ;; 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 end to open-file let file user-new-file if ( file != false ) [ if ( file-exists? file ) [ file-delete file ] file-open file ] end to write-to-file file-show my-clients file-show my-obligations end 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 compete ] [stop] end to calculate-clients-worth foreach my-clients [ ask ? [ let dosh wealth ask myself [set clients-worth clients-worth + dosh] ] ] end 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. go-home ] [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] go-home ] ] [go-home] end 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 end ; Original Wealth Distribution Model is Copyright 1998 Uri Wilensky. All rights reserved. ; This extension of the model is Creative Commons Licensed Graham & Weingart