Pac-Man HubNet Activity
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
;; 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.