Civ

No preview image

1 collaborator

Default-person Kay Ramey (Author)

Tags

(This model has yet to be categorized with any tags)
Model group LS426-2012 | Visible to everyone | Changeable by group members (LS426-2012)
Model was written in NetLogo 5.0RC7 • Viewed 314 times • Downloaded 25 times • Run 0 times
Download the 'Civ' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

patches-own [water]
globals [people-constant water-constant]

to setup
  clear-all
  draw-terrain 

  crt population
  [
    set color orange
    set size 2
    set shape "person"
    
    ; distribute randomly, making sure none of them are in the water
    setxy random-xcor random-ycor
    while [water = true] [ setxy random-xcor random-ycor ]
  ]
  
  set people-constant 0.0
  let counter 1
  while [counter <= population]
  [
    set people-constant (people-constant + (1.0 / counter))
    set counter (counter + 1)
  ]
  
  ; we don't want to count ourselves
  set people-constant (people-constant - 1)

  reset-ticks
end 


;; draw a fixed terrain

to draw-terrain
  ask patches
  [
    set pcolor 72  ; green
    set water false
  ]
  
  ; ocean along the top
  ask patches with [pycor > 70]
  [
    set pcolor blue
    set water true
  ]
  
  ; ocean along the bottom
  ask patches with [pycor < 3]
  [
    set pcolor blue
    set water true
  ]
  
  ; lake on the left
  ask patches with [distancexy 25 30 < 13]
  [
    set pcolor blue
    set water true
  ]
    
  ; another lake on the right
  ask patches with [distancexy 70 45 < 10]
  [
    set pcolor blue
    set water true
  ]
  
  ; river going down from the second lake  
  ask patches with [pxcor > 67 and pxcor < 73 and pycor < 45]
  [
    set pcolor blue
    set water true
  ]
end 

to go
  
  ask turtles
  [

    ;; the default probability of staying at the current
    ;; patch derives from laziness
    let p ((laziness / 100.0) + (get-happiness-adjustment xcor ycor))

    let r (random-float 1)
    ifelse (r > p)
    [
      move-intelligently
    ] [
      set r (random 100)
      if (impulsiveness > r) [ move-randomly ]
    ]
    
  ]
  
  tick
end 



;; calculate the people index, which we model to have decreasing
;; marginal utility. we go with a harmonic sum as a rough
;; approximation, i.e. the nth neighbor adds value 1/n

to-report get-people-index [x y]

  let people-index 0.0
  let people-count 0

  ask turtles with [(distancexy x y) < sphere-of-activity]
  [
    set people-count (people-count + 1)
    set people-index people-index + (1.0 / people-count)
  ]
  
  ;; we counted ourselves in the above, so take it back out
  set people-index (people-index - 1)
  
  ;; normalize the people-index against the maximum possible value
  ;; that occurs when everyone is all in the same place. after
  ;; this, people-index will be a number between 0 and 1.
  set people-index (people-index / people-constant)
  
  report people-index
end 


;; calculate the water index, which we model to have a sharply
;; decreasing marginal utility. we go with the nth neighboring
;; water patch adding value 1/n^2

to-report get-water-index [x y]
  let water-index 0.0
  let water-count 0
  ask patches with [(distancexy x y) < sphere-of-activity]
  [
    if (water = true)
    [
      set water-count (water-count + 1)
      set water-index water-index + (1.0 / (water-count * water-count))
    ]
  ]
  
  ;; normalize the water-index against the maximum possible value
  ;; after this, water-index will be a number between 0 and 1
  set water-index (water-index / 1.65)

  report water-index  
end 


;; reports the probability adjustment of staying, as influenced
;; by being close to water and people.

to-report get-happiness-adjustment [x y]
  let people-index (get-people-index x y)
  let water-index (get-water-index x y)
    
  ;; we define leeway to be the amount of influence either proximity
  ;; to water or proximity to people can have, and we give these
  ;; equal parts of the remaining probability. for example,
  ;; if the default probability of staying is 40%, then we allow
  ;; each of these two factors to increase the probability by up to 
  ;; 30%, so that if both of them were to be maxed out, and the person
  ;; had 100% affinity to both, then the probability
  ;; of staying would be 100%.
  let leeway ((100.0 - laziness) / 200.0)

  report (people-index * (affinity-to-people / 100.0) * leeway) + (water-index * (affinity-to-water / 100.0) * leeway)  
end 


;; checks the up/down/left/right squares and moves to the
;; one that makes you the happiest

to move-intelligently
  let x xcor
  let y ycor
  
  ; adjustments in the four directions
  let adj1 -1
  let adj2 -1
  let adj3 -1
  let adj4 -1
  
  
  ;; up, idx = 1
  set ycor (y + 1)
  if (water = false) [ set adj1 (get-happiness-adjustment xcor ycor) ]
  
  ;; down, idx = 2
  set ycor (y - 1)
  if (water = false) [ set adj2 (get-happiness-adjustment xcor ycor) ]
    
  ;; left, idx = 3
  set ycor y
  set xcor (x - 1)
  if (water = false) [ set adj3 (get-happiness-adjustment xcor ycor) ]
  
  ;; left, idx = 4
  set xcor (x + 1)
  if (water = false) [ set adj4 (get-happiness-adjustment xcor ycor) ]


  ;; figure out what the max adjustment is, and how many
  ;; of the four directions tie for max
  let max-adj adj1
  let max-count 1
  
  if (adj2 = adj1) [ set max-count (max-count + 1) ]
  if (adj2 > adj1) [ set max-adj adj2 set max-count 1 ]
  
  if (adj3 = adj2) [ set max-count (max-count + 1) ]
  if (adj3 > adj2) [ set max-adj adj3 set max-count 1 ]
  
  if (adj4 = adj3) [ set max-count (max-count + 1) ]
  if (adj4 > adj3) [ set max-adj adj4 set max-count 1 ]
  
  ;; now, randomly choose one of the directions that tie for
  ;; the max adjustment
  let max-idx (random max-count)
  
  if (adj1 = max-adj)
  [
    if (max-idx = 0) [ set xcor x set ycor (y + 1) stop ]
    set max-idx (max-idx - 1)
  ]
  
  if (adj2 = max-adj)
  [
    if (max-idx = 0) [ set xcor x set ycor (y - 1) stop ]
    set max-idx (max-idx - 1)
  ]  
  
  if (adj3 = max-adj)
  [
    if (max-idx = 0) [ set xcor (x - 1) set ycor y stop ]
    set max-idx (max-idx - 1)
  ]  
     
  if (adj4 = max-adj)
  [
    if (max-idx = 0) [ set xcor (x + 1) set ycor y stop ]
    set max-idx (max-idx - 1)
  ]  
end 

to move-randomly
  let legal-move false
  let r 0
  
  while [legal-move = false]
  [
    set r (random 360)
    rt r fd 1
    ifelse (water = true)
    [
      set legal-move false
      bk 1 lt r
    ] [
      set legal-move true
    ]
  ]
end 

There is only one version of this model, created almost 13 years ago by Kay Ramey.

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.