Pac-Man HubNet Activity

Pac-Man HubNet Activity preview image

1 collaborator

Default-person Natalie Murray (Author)

Tags

(This model has yet to be categorized with any tags)
Model group MAM-2013 | Visible to everyone | Changeable by everyone
Model was written in NetLogo 5.0.4 • Viewed 908 times • Downloaded 42 times • Run 0 times
Download the 'Pac-Man HubNet Activity' modelDownload this modelEmbed this model

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


WHAT IS IT?

This is a participatory simulation that the reinforce the concept of collaborative diffusion for middle and high school students. Make sure you and the students are familiar with the Pac-Man and Collaborative Diffusion Demo models before using this HubNet Activity. Whoever is running the simulation runs controls the Pac-Man, and the students sign into the simulation as the ghosts. The goal is for the students to find the Pac-Man via collaborative diffusion. The students only have the view of their surrounding neighbors, so they can only see the scent color and navigate off of that. The idea is that once the simulation run stops, they wil be able to see that they were able to collaborate and take different paths by simply following the diffusion-scent.

HOW IT WORKS

Each student controls a single ghost. When the activity starts, they must navigate the map and find the Pac-Man by using the provided controls. The Up/Down/Left/Right buttons control the direction in which they move. The clients control the ghosts, and the person running the simulation controls the Pac-Man and tries to escape the ghosts.

HOW TO USE IT

Press setup, then wait for the students to sign into the server. The press go to start the simulation. Use the diffusion-speed slider to control how fast the scent diffuses. To play the game normally, set path-mode to off. From there, simply control the Pac-Man via the U/D/L/R buttons as in the normal Pac-Man model.

Path-mode: if you want to run path mode, turn path-mode on and set up the simulation. This puts the pen down for the ghosts so their paths are traced. For clarity in the visualization of paths, the pellets are removed. Press go to start the simulation and navigate the Pac-Man as before. After the run is done, show the students the paths that resulted to see how they worked together with limited information.

For students/clients: Sign into the game and wait for the simulation to start. Then use the Up/Down/Left/Right buttons to navigate the maze and find the Pac-Man. Use the color of the diffusion-scent to decide which direction to go next.

THINGS TO NOTICE

When in path mode, show the students at the end how they managed to collaborate and take different paths to find the Pac-Man even though they only knew about the neighboring region.

If controlling the Pac-Man, take note of how the student-ghosts move and follow the scent.

THINGS TO TRY

Try doing the simulation on and off path mode, with different diffusion speeds, and with different difficulties and see if/how results change.

EXTENDING THE MODEL

Try adding in multiple levels to the game, as this version only contains level one.

For situations where there are fewer clients than ghosts, add in 'android ghosts' that follow the same rules for collaborative diffusion. Most of the code should be in there.

NETLOGO FEATURES

This model uses scale-color to control the diffusion, and uses HubNet overrides to hide the Pac-Man, pellets, and bonuses from the view of the clients.

RELATED MODELS

Collaborative Diffusion Demo, Pac-Man

CREDITS AND REFERENCES

Adapted from the Pac-Man model in the NetLogo Models Library:

  • Wilensky, U. (2001). NetLogo Pac-Man model. http://ccl.northwestern.edu/netlogo/models/Pac-Man. Center for Connected Learning and Computer-Based Modeling, Northwestern Institute on Complex Systems, Northwestern University, Evanston, IL.
  • Wilensky, U. (1999). NetLogo. http://ccl.northwestern.edu/netlogo/. Center for Connected Learning and Computer-Based Modeling, Northwestern Institute on Complex Systems, Northwestern University, Evanston, IL.

For collaborative diffusion see: http://www.cs.colorado.edu/~ralex/papers/PDF/OOPSLA06antiobjects.pdf

Comments and Questions

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

Click to Run Model

;; create a breed of turtles that the students control through the clients
;; there will be one student turtle for each client.
turtles-own [ home-pos ]
patches-own [ 
  pellet-grid?  ;; true/false: is a pellet here initially?
  pacman-scent] ;; scent of pacman 

breed [ pellets pellet ]
pellets-own [ powerup? ]

breed [ bonuses bonus ]
bonuses-own [ value countdown ]

breed [ students student ]

breed [ ghosts ghost ]
ghosts-own  [ eaten? ]

breed [ pacmans pacman ]
pacmans-own  [ new-heading ]


students-own
[
  user-id   ;; students choose a user name when they log in whenever you receive a
            ;; message from the student associated with this turtle hubnet-message-source
            ;; will contain the user-id
  eat?      ;; true if the ghost has been eaten
]
globals [
  level            ;; current level
  score            ;; your score
  lives            ;; remaining lives
  extra-lives      ;; total number of extra lives you've won
  scared           ;; time until ghosts aren't scared (0 means not scared)
  level-over?      ;; true when a level is complete
  dead?            ;; true when Pac-Man is loses a life
  next-bonus-in    ;; time until next bonus is created
  tool which-ghost ;; variables needed to properly load levels 4 and above.
  test-list        ;; list of home positions for the ghosts
  user-count       ;; count of active users
  pellet-set       ;; set of patches where pellets belong
  powerup-set      ;; set of patches wher powerup pellets go
]

;; the STARTUP procedure runs only once at the beginning of the model
;; at this point you must initialize the system.

to startup
  hubnet-reset
end 

to setup
  clear-patches
  clear-drawing
  clear-output
  set level 1
  set user-count 0  
  load-map
  if path-mode [ask pellets[ die ]] ;; clear pellets if in path mode
  initialize-diffusion-values 
  set score 0
  set lives 3
  set extra-lives 0
  set scared 0
  set level-over? false
  ;; during setup you do not want to kill all the turtles
  ;; (if you do you'll lose any information you have about the clients)
  ;; so reset any variables you want to default values, and let the clients
  ;; know about the change if the value appears anywhere in their interface.
  
  ;; calling reset-ticks enables the 'go' button
  reset-ticks
end 

to load-map  ;; Observer Procedure
             ;; Filenames of Level Files
  let current-lives lives
  let current-extra-lives extra-lives
  
  import-pcolors "map.png" ;; import the patches
  setup-agents
  set lives current-lives
  set extra-lives current-extra-lives
  set dead? false
  ask pacmans
    [ set home-pos list xcor ycor ]
  ask ghosts
    [ set home-pos list xcor ycor ]
end 

;; places all agents on map and intitialize values

to setup-agents
  
  ;; kill all current non-student agents
  ask pacmans [die]
  ask ghosts [die]
  ask pellets [die]
  
  ;; put pellets on patches with a color = 1
  set pellet-set (patch-set patches with [pcolor = 1])
  foreach sort pellet-set
  [create-pellets 1 
    [
      setxy ([pxcor] of ?) ([pycor] of ?)
      set home-pos (list ([pxcor] of ?) ([pycor] of ?))
      set shape "pellet"
      set color white
      set powerup? false
    ]
  ]
  
  ;; put powerup pellets on patches with color = 2
  set powerup-set (patch-set patches with [pcolor = 2])
  foreach sort powerup-set
  [create-pellets 1
    [ 
      setxy ([pxcor] of ?) ([pycor] of ?)
      set home-pos (list ([pxcor] of ?) ([pycor] of ?))
      set shape "circle"
      set color white
      set powerup? true
    ]
  ]
  
  ;; create a pacman and place on the home tile
  create-pacmans 1
  [
    setxy 0 -5
    set home-pos (list 0 -5)
    set shape "pacman"
    set color yellow
    set heading 0
  ]
  
  ;; true if a pellet is there
  ask patches [ifelse any? pellets-here
    [set pellet-grid? true]
    [set pellet-grid? false]
  ]
  
  ;; make sure pen is up so a path is not drawn from old position of ghosts to new positon
  ask students [
    pen-up
    setxy item 0 home-pos item 1 home-pos
    set heading 0]
  
  ;; change view of clients and hide pacmans, pellets, and bonuses from view
  ask students [
    hubnet-send-follow user-id self 1
    hubnet-send-override hubnet-message-source pacmans "hidden?" [true]
    hubnet-send-override hubnet-message-source pellets "hidden?" [true]
    hubnet-send-override hubnet-message-source bonuses "hidden?" [true]
  ]
end 

to go
  ;; process incoming messages and respond to them (if needed)
  ;; listening for messages outside of the every block means that messages
  ;; get processed and responded to as fast as possible
  listen-clients
  ask students [ifelse path-mode [pen-down]
    [pen-up]]
  if dead? [ stop ]
  every 1 [ move-pacman ]
  every 1.6 [
    move-students2
    repeat diffusion-speed [set-diffusion-values]
    visualize-scent]
  if not path-mode [ every 0.25 [ update-bonuses ] ]
  if floor (score / 35000) > extra-lives
  [ set lives lives + 1
    set extra-lives extra-lives + 1 ]
  if dead?
  [ ifelse lives = 0
    [ user-message word "Game Over!\nScore: " score ]
    [ set lives lives - 1
      ifelse lives = 0
      [ user-message "You died!\nNo lives left." ]
      [ ifelse lives = 1
        [ user-message "You died!\nOnly 1 life left." ]
        [ user-message (word "You died!\nOnly " lives " lives left.") ]
      ]
      ask students [if path-mode [pen-up]]
      initialize-diffusion-values
      reset-colors
      ask pacmans
      [ setxy (item 0 home-pos) (item 1 home-pos)
        set heading 0
      ]
      ask ghosts
      [ setxy (item 0 home-pos) (item 1 home-pos)
        set heading 0
        set shape "ghost"
      ]
      ask students
      [ setxy (item 0 home-pos) (item 1 home-pos)
        set heading 0
        set shape "ghost"
      ]
      set dead? false
    ]
  stop
  ]
  if level-over? and not path-mode
  [ ask students [hubnet-reset-perspective user-id]
    user-message word "Level Complete!\nScore: " score  ;; \n means start a new line
    initialize-diffusion-values
    reset-colors
    load-map
    set level-over? false
    stop ]
  if not path-mode [ every next-bonus-in [ make-bonus ] ]
  every 0.1
  [
    ;ensure pellets, pacmans, and bonuses stay hidden (sometimes bonuses will pop up
    ;when they are created after the furst call to hubnet-send-override)
    ask students[
      hubnet-send-override hubnet-message-source pacmans "hidden?" [true]
      hubnet-send-override hubnet-message-source pellets "hidden?" [true]
      hubnet-send-override hubnet-message-source bonuses "hidden?" [true]]
    tick
  ]
end 

to gray-out-corners
  ask students [
    let my-patch-set (patch-set patch-left-and-ahead 45 1 patch-left-and-ahead 135 1 patch-left-and-ahead 225 1 patch-left-and-ahead 315 1)
    hubnet-clear-overrides user-id
    hubnet-send-override user-id my-patch-set "pcolor" [red]]
end 

;;;;;;;;;;;;;;;;;;;;;;;
;; HUBNET PROCEDURES ;;
;;;;;;;;;;;;;;;;;;;;;;;

to listen-clients
  ;; as long as there are more messages from the clients
  ;; keep processing them.
  while [ hubnet-message-waiting? ]
  [
    ;; get the first message in the queue
    hubnet-fetch-message
    ifelse hubnet-enter-message? ;; when clients enter we get a special message
    [ create-new-student ]
    [
      ifelse hubnet-exit-message? ;; when clients exit we get a special message
      [ remove-student ]
      [ ask students with [user-id = hubnet-message-source]
        [ execute-command hubnet-message-tag ] ;; otherwise the message means that the user has
      ]                                        ;; done something in the interface hubnet-message-tag
                                               ;; is the name of the widget that was changed
    ]
  ]
end 

;; when a new user logs in create a student turtle
;; this turtle will store any state on the client
;; values of sliders, etc.

to create-new-student
  set user-count user-count + 1
  if user-count < 5 [
    create-students 1
    [
      ;; store the message-source in user-id now
      ;; so when you get messages from this client
      ;; later you will know which turtle it affects
      set user-id hubnet-message-source
      ;; initialize turtle variables to the default
      ;; value of the corresponding widget in the client interface
      ;; place students depending on which order they sign on
      ;; messy but for some reason I was having trouble with using lists as globals
      if user-count = 1 [
        setxy 0 3
        set color red 
        set home-pos (list 0 3)]
      if user-count = 2 [
        setxy -1 1
        set color blue
        set home-pos (list -1 1)]
      if user-count = 3 [
        setxy 0 1
        set color pink 
        set home-pos (list 0 1)]
      if user-count = 4 [
        setxy 1 1
        set color orange 
        set home-pos (list 1 1)]
      set shape "ghost"
      set eat? false
      set heading 0
      ;; update the clients with any information you have set
      send-info-to-clients
      ;; set view and hide pacman, pellets, and bonuses
      hubnet-send-follow user-id self 1
      hubnet-send-override hubnet-message-source pacmans "hidden?" [true]
      hubnet-send-override hubnet-message-source pellets "hidden?" [true]
      hubnet-send-override hubnet-message-source bonuses "hidden?" [true]
    ]
    
  ]
end 

;; when a user logs out make sure to clean up the turtle
;; that was associated with that user (so you don't try to
;; send messages to it after it is gone) also if any other
;; turtles of variables reference this turtle make sure to clean
;; up those references too.

to remove-student
  ask students with [user-id = hubnet-message-source]
  [ die ]
end 

;; Other messages correspond to users manipulating the
;; client interface, handle these individually.

to execute-command [command]
  ;; you should have one if statement for each widget that
  ;; can affect the outcome of the model, buttons, sliders, switches
  ;; choosers and the view, if the user clicks on the view you will receive
  ;; a message with the tag "View" and the hubnet-message will be a
  ;; two item list of the coordinates
  if command = "up"
  [ execute-move 0 stop ]
  if command = "down"
  [ execute-move 180 stop ]
  if command = "right"
  [ execute-move 90 stop ]
  if command = "left"
  [ execute-move 270 stop ]
end 

;; whenever something in world changes that should be displayed in
;; a monitor on the client send the information back to the client

to send-info-to-clients ;; turtle procedure
                        ;hubnet-send user-id "location" (word "(" pxcor "," pycor ")")
end 

to execute-move [n-heading]
  set heading n-heading
  ;send-info-to-clients
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; PACMAN GAME PROCEDURES ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

to update-bonuses  ;; Observer Procedure
  ask bonuses
  [ set heading heading + 13
    set countdown countdown - 1
    if countdown = 0
    [ die ] ]
end 

to move-pacman  ;; Observer Procedure
  ask pacmans
  [ ;; move forward unless blocked by wall
    let old-heading heading
    set heading new-heading
    if [pcolor] of patch-ahead 1 = blue
    [ set heading old-heading ]
    if [pcolor] of patch-ahead 1 != blue
    [ fd 1 ]
    consume
    ;; Level ends when all pellets are eaten
    if not any? pellets
    [ set level-over? true ]
    ;; Animation
    ifelse shape = "pacman"
    [ set shape "pacman open" ]
    [ set shape "pacman" ]
  ]
end 

to consume  ;; Pacman Procedure
            ;; Consume Bonuses
  if any? bonuses-here
  [ set score score + sum [value] of bonuses-here
    ask bonuses-here [ die ] ]
  
  ;; Consume Pellets
  if any? pellets-here
  [ ifelse [powerup?] of one-of pellets-here
    [ set score score + 500
      set scared 40
      ask ghosts
      [ if not eaten?
        [ set shape "scared" ] ]
    ]
    [ set score score + 100 ]
  ask pellets-here [ die ] ]
  
  ;; Ghosts
  if any? ghosts-here with [not eaten?]
  [ ifelse scared = 0
    [ set dead? true ]
    [ ask ghosts-here with [not eaten?]
      [ set eaten? true
        set shape "eyes"
        set score score + 500 
      ]
    ]
  ]
  
  ;; Students
  if any? students-here with [not eat?]
  [ ifelse scared = 0
    [ set dead? true ]
    [ ask students-here with [not eat?]
      [ set eat? true
        set shape "eyes"
        hubnet-reset-perspective user-id
        set score score + 500 ]
    ]
  ]
end 

to make-bonus ;; Observer Procedure
  ifelse next-bonus-in = 0
  [ set next-bonus-in 10 ]
  [ let bonus-patch one-of patches with [pellet-grid? and
    not any? bonuses-here and
    not any? pellets-here]
  if bonus-patch != nobody
    [ ask bonus-patch
      [ sprout-bonuses 1
        [ set shape "star"
          set heading 0
          set color random 14 * 10 + 5
          set value (random 10 + 1) * 100
          set countdown random 200 + 50 ] ]
    set next-bonus-in 5 + random 10 ] ]
end 

to return-home  ;; Ghosts Procedure
  let dirs clear-headings
  let new-dirs remove opposite heading dirs
  let home-dir 0
  if pcolor != gray
    [ set home-dir towards one-of patches with [pcolor = gray] ]
  let home-path 90 * round (home-dir / 90)
  
  if length new-dirs = 1
  [ set heading item 0 new-dirs ]
  if length new-dirs > 1
  [ ifelse position home-path new-dirs != false
    [ set heading home-path ]
    [ set heading one-of new-dirs ]
  ]
  fd 1
end 

to-report clear-headings ;; ghosts procedure
  let dirs []
  if [pcolor] of patch-at 0 1 != blue
  [ set dirs lput 0 dirs ]
  if [pcolor] of patch-at 1 0 != blue
  [ set dirs lput 90 dirs ]
  if [pcolor] of patch-at 0 -1 != blue
  [ set dirs lput 180 dirs ]
  if [pcolor] of patch-at -1 0 != blue
  [ set dirs lput 270 dirs ]
  report dirs
end 

to-report opposite [dir]
  ifelse dir < 180
  [ report dir + 180 ]
  [ report dir - 180 ]
end 

to choose-heading  ;; Ghosts Procedure
  let dirs clear-headings
  let new-dirs remove opposite heading dirs
  let pacman-dir false
  
  if length dirs = 1
  [ set heading item 0 dirs ]
  if length dirs = 2
  [ ifelse see-pacman item 0 dirs
    [ set pacman-dir item 0 dirs ]
    [ ifelse see-pacman item 1 dirs
      [ set pacman-dir item 1 dirs ]
      [ set heading one-of new-dirs ]
    ]
  ]
  if length dirs = 3
  [ ifelse see-pacman item 0 dirs
    [ set pacman-dir item 0 dirs ]
    [ ifelse see-pacman item 1 dirs
      [ set pacman-dir item 1 dirs ]
      [ ifelse see-pacman item 2 dirs
        [ set pacman-dir item 2 dirs ]
        [ set heading one-of new-dirs ]
      ]
    ]
  ]
  if length dirs = 4
  [ ifelse see-pacman item 0 dirs
    [ set pacman-dir item 0 dirs ]
    [ ifelse see-pacman item 1 dirs
      [ set pacman-dir item 1 dirs ]
      [ ifelse see-pacman item 2 dirs
        [ set pacman-dir item 2 dirs ]
        [ ifelse see-pacman item 3 dirs
          [ set pacman-dir item 3 dirs ]
          [ set heading one-of new-dirs ]
        ]
      ]
    ]
  ]
  if pacman-dir != false
  [ ifelse scared = 0
    [ set heading pacman-dir ]
    [ set dirs remove pacman-dir dirs
      set heading one-of dirs
    ]
  ] 
  fd 1
end 

to-report see-pacman [dir] ;; ghosts procedure
  let saw-pacman? false
  let p patch-here
  while [[pcolor] of p = black]
  [ ask p
    [ if any? pacmans-here
      [ set saw-pacman? true ]
    set p patch-at sin dir cos dir ;; next patch in direction dir
    ]
  ;; stop looking if you loop around the whole world
  if p = patch-here [ report saw-pacman? ]
  ]
  report saw-pacman?
end 

to move-up
  ask pacmans [ set new-heading 0 ]
end 

to move-right
  ask pacmans [ set new-heading 90 ]
end 

to move-down
  ask pacmans [ set new-heading 180 ]
end 

to move-left
  ask pacmans [ set new-heading 270 ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; COLLABORATIVE DIFFUSION PROCEDURES ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;set initial diffusion values

to initialize-diffusion-values  
  ask patches [set pacman-scent 0] 
  ask pacmans [ask patch-here [set pacman-scent 1000]]
end 

;;update diffusion values

to set-diffusion-values
  ask students [if shape != "eyes" [ask patch-here [set pacman-scent 0]]]
  ask pacmans [ask patch-here [set pacman-scent 1000]]
  diffuse4 pacman-scent 1
  ask patches [if pcolor = blue or pcolor = gray [set pacman-scent 0]]
  ask students [if shape != "eyes" [ask patch-here [set pacman-scent 0]]] 
  ask pacmans [ask patch-here [set pacman-scent 1000]] 
end 

;;visualize the pacman-scent

to visualize-scent
  let min-log-dif min [log-val] of patches with [ pacman-scent > 0 ]
  let max-log-dif max [log-val] of patches with [ pacman-scent > 0 ]
  if min-log-dif != max-log-dif [
    ask patches [
      ifelse pacman-scent != 0
      [set pcolor scale-color green log-val min-log-dif max-log-dif ]
      [if pcolor != blue and pcolor != gray [set pcolor black]]
    ]]
end 

to reset-colors
  ask patches [if pcolor != blue and pcolor != gray [set pcolor black]]
end 

to-report log-val 
  report log (pacman-scent) 10
end 

;;get new heading for cd code

to get-heading
  let target max-one-of neighbors4 with 
    [not any? ghosts-here and pcolor != blue]
    [pacman-scent]
  if target != nobody [
    set heading towards target
    fd 1]
end 

;move ghosts for collaborative diffusion

to move-ghosts-cd  ;; Observer Procedure
  ask ghosts
  [ ifelse eaten?
    [ if [pcolor] of patch-at 0 1 = gray
      [ set eaten? false
        set shape "ghost" ]
    return-home
    ]
    [ ifelse scared > 0
      [choose-heading] ;;use the old method so the ghosts don't swarm the pacman when frightened
                       ;;going down the gradient not a good idea because of too many local minima 
                       ;;from pacman moving around
      [get-heading ]]]
  if scared > 0
  [ set scared scared - 1
    ifelse scared < 10 and scared mod 2 = 0
    [ ask ghosts with [not eaten?]
      [ set shape "ghost" ] ]
    [ ask ghosts with [not eaten?]
      [ set shape "scared" ] ]
    if scared = 0
    [ ask ghosts with [not eaten?]
      [ set shape "ghost" ]
    ]
  ]
end 

;;move students, hubnet

to move-students2
  ;;if student eaten, reset perspective so they can find their way home
  ask students [
    if eat?
    [ if [pcolor] of patch-at 0 1 = gray
      [ set eat? false
        set shape "ghost" 
        hubnet-send-follow user-id self 1 ]
    ]
    ;; move forward if not up against a wall or if an eaten ghost is ahead of you
    if [pcolor] of patch-ahead 1 != blue and ( not any? ((students-on patch-ahead 1) with [shape != "eyes"]) or shape = "eyes" )
    [fd 1] 
    
    ;; sent pacman scent to zero at the gray patch
    if [pcolor] of patch-here != gray [ask patch-here [set pacman-scent 0]]]
  
  if scared > 0
    [ set scared scared - 1
      ifelse scared < 10 and scared mod 2 = 0
      [ ask students with [ not eat? ]
        [ set shape "ghost" ] ]
      [ ask students with [ not eat? ]
        [ set shape "scared" 
        ] ]
      if scared = 0
      [ ask students with [ not eat? ]
        [ set shape "ghost" ]
      ]
      
    ]   
end 

; Public Domain:
; To the extent possible under law, Uri Wilensky has waived all
; copyright and related or neighboring rights to this model.

There is only one version of this model, created over 11 years ago by Natalie Murray.

Attached files

File Type Description Last updated
map.png data Map for Pac-Man, put in same directory as model over 11 years ago, by Natalie Murray Download
Pac-Man HubNet Activity.png preview Preview for 'Pac-Man HubNet Activity' over 11 years ago, by Natalie Murray Download

This model does not have any ancestors.

This model does not have any descendants.