Pacman with Collabrative Diffusion

Pacman with Collabrative Diffusion 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 668 times • Downloaded 37 times • Run 0 times
Download the 'Pacman with Collabrative Diffusion' 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 the classic arcade game, Pac-Man. The game involves navigating Pac-Man through a maze. Your objective is that Pac-Man eat all of the pellets (white circles), while avoiding the ghosts that pursue him.

The catch to this version is that the ghosts are implemented using collaborative diffusion. See the collaborative diffusion demo to learn about collaborative diffusion.

If a ghost ever catches Pac-Man then Pac-Man is defeated. If this occurs, the level will reset, but this will happen only if Pac-Man still has some lives remaining. (The pellets already collected on the level remain collected.)

However, when Pac-Man eats a Power-Pellet (large white circle) he can turn the tide, and the ghosts will turn scared and flee from him, for with the power of the Power-Pellet, Pac-Man can eat the ghosts! Once a ghost is eaten it will return to its base, where it is born again, immune to the Power-Pellet until Pac-Man can find a new one to consume. Pac-Man had better do just that, because unfortunately, the power of the Power-Pellet does not last forever, and will begin to wear off over time. (You will see the ghosts start to flash back to their normal appearance during the last few seconds of the Power-Pellet's effectiveness.)

Finally, occasionally a bonus (rotating star) will appear in the maze. This bonus gives Pac-Man extra points if he eats it, but it will disappear if Pac-Man doesn't get it within a limited amount of time.

HOW TO USE IT

Monitors -- SCORE shows your current score. You get points for collecting pellets, eating ghosts, and collecting bonuses. You will get an extra life after every 35,000 points. -- LEVEL shows your current level. Each level has a different map, if you complete all the maps, it will loop back to the first map and continue. -- LIVES shows how many extra lives you have remaining. If you are defeated by a ghost when this is at 0, the game is over.

Sliders -- DIFFICULTY controls the speed of the game. Lower numbers make both the ghosts and Pac-Man move slowly, giving you more time to react as you play. -- DIFFUSION-SPEED controls how fast the scent of the Pac-Man spreads. Lower speeds mean the scent does not spread as quickly so the old scent will linger longer (thus making it harder for the ghosts to catch up with the Pac-Man)

Buttons -- NEW sets up a new game on level 1, with 3 lives, and a score of 0. -- PLAY begins the game. The game will pause after each level, so you will need to hit PLAY again after each level to continue.

Controls -- UP, DOWN, LEFT, RIGHT control the direction Pac-Man moves.

Switches -- COLLABORATIVE-DIFFUSION controls whether the ghosts move via collaborative diffusion or not -- VISUALIZE-SCENT? controls whether or not to visualize the diffusion scent.

THINGS TO NOTICE

The intensity of the green on the maze represents how strong the Pac-Man scent is. The ghosts always go in the direction of the brighter color to find the Pac-Man.

When the ghosts are scared or are eaten they do not use collaborative diffusion, but rather scatter or return home.

If you go off the edge of the maze you will wrap around to the other side.

Identifying Things in the Maze: -- Yellow Circle with a mouth: This is Pac-Man - you. -- White Circles: These are Pellets - Collect all of these (including the Power-Pellets) to move on to the next level.

-- Large White Circles: These are Power-Pellets - They allow you to eat the Ghosts for a limited ammount of time.

-- Blue Squares: These are the walls of the maze - Neither Pac-Man nor the Ghosts can move through the walls.

-- Gray Squares: These are the Ghost Gates - Only Ghosts can move through them, and if they do so after having been eaten they will be healed.

-- Rotating Colored Stars: These are Bonus Stars - They give you extra points when you eat them.

-- Colorful Ghost with Eyes: These are the active Ghosts - Watch out for them!

-- Blue Ghost Shape: These are the scared Ghosts - Eat them for Extra Points!

-- Two Small Eyes: These are the Ghosts after they've been eaten - They will not affect you, and you can't eat them again, so just ignore them, but try not to be near its base when it gets back there.

Scoring System -- Eat a Pellet: 100 Points

-- Eat a Power-Pellet: 500 Points -- Eat a Scared Ghost: 500 Points -- Eat a Bonus Star: 100-1000 Points (varies)

THINGS TO TRY

Beat your Highest Score.

Can you write an automated program for Pac-Man that will get him safely through the maze and collect all the pellets?

EXTENDING THE MODEL

Think of other power-ups or bonuses that might be fun to have and make them appear randomly in the maze.

Add new enemies that behave differently from the ghosts.

NETLOGO FEATURES

This model makes use of breeds, create-, every, and user-message.

The "import-world" command is used to read in the different maze configurations (levels).

RELATED MODELS

See Collaboratve Diffusion Demo and PacMan-HubNet for collaborative diffusion models, and the Pac-Man model in the Models Library for the original Pac-Man game the code is adapted from.

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

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 [ pacmans pacman ]
pacmans-own  [ new-heading ]

breed [ ghosts ghost ]
ghosts-own  [ 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.
]

;;;;;;;;;;;;;;;;;;;;;;;;
;;; Setup Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;

to new  ;; Observer Button
  clear-all
  set level 1
  load-map
  if Collaborative-Diffusion [initialize-diffusion-values]
  set score 0
  set lives 3
  set extra-lives 0
  set scared 0
  set level-over? false
  reset-ticks
end 

to load-map  ;; Observer Procedure
             ;; Filenames of Level Files
  let maps ["pacmap1.csv" "pacmap2.csv" "pacmap3.csv"
    "pacmap4.csv" "pacmap5.csv"]
  let current-score score
  let current-lives lives
  let current-extra-lives extra-lives
  let current-difficulty difficulty
  
  ifelse ((level - 1) < length maps)
  [ import-world item (level - 1) maps
    set score current-score
    set lives current-lives
    set extra-lives current-extra-lives
    set difficulty current-difficulty
    set dead? false
    ask pacmans
    [ set home-pos list xcor ycor ]
    ask ghosts
    [ set home-pos list xcor ycor ]
  ]
  [ set level 1
    load-map ]
end 

;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Runtime Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;

to play  ;; Observer Forever Button
         ;; Only true at this point if you died and are trying to continue
  if dead?
  [ stop ]
  every (1 - difficulty / 10)
  [ move-pacman ]
  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.") ]
      ]
      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"
      ]
      set dead? false
    ]
  stop
  ]
  if level-over?
  [ user-message word "Level Complete!\nScore: " score  ;; \n means start a new line
    set level level + 1
    initialize-diffusion-values
    reset-colors
    load-map
    set level-over? false
    stop ]
  every 1.6 * (1 - difficulty / 10 )
  [ ifelse Collaborative-Diffusion 
    [move-ghosts-cd
      repeat diffusion-speed [set-diffusion-values]
      if visualize-scent? [visualize-scent]]
    [move-ghosts]]
  every next-bonus-in
  [ make-bonus ]
  display
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 ]
    ]
  ]
end 

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

to move-ghosts  ;; Observer Procedure
  ask ghosts
  [ ifelse eaten?
    [ if [pcolor] of patch-at 0 1 = gray
      [ set eaten? false
        set shape "ghost" ]
    return-home
    ]
    [ choose-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 

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 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 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-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 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 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Collaborative Diffusion Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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

to set-diffusion-values
  
  ask ghosts [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 ghosts [if shape != "eyes" [ask patch-here [set pacman-scent 0]]]
  ask pacmans [ask patch-here [set pacman-scent 1000]]
end 

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 

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 

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 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Interface Procedures ;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;

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 


; Copyright 2001 Uri Wilensky.
; See Info tab for full copyright and license.

There are 4 versions of this model.

Uploaded by When Description Download
Natalie Murray almost 6 years ago Final Vesion Download this version
Natalie Murray almost 6 years ago Added Scent Visualization Download this version
Natalie Murray almost 6 years ago functional game, option to play without collaborative diffusion Download this version
Natalie Murray almost 6 years ago Initial upload Download this version

Attached files

File Type Description Last updated
Pacman with Collabrative Diffusion.png preview Preview for 'Pacman with Collabrative Diffusion' almost 6 years ago, by Natalie Murray Download
pacmap1.csv data level 1 almost 6 years ago, by Natalie Murray Download
pacmap2.csv data level 2 almost 6 years ago, by Natalie Murray Download
pacmap3.csv data level 3 almost 6 years ago, by Natalie Murray Download
pacmap4.csv data level 4 almost 6 years ago, by Natalie Murray Download
pacmap5.csv data level 5 almost 6 years ago, by Natalie Murray Download

This model does not have any ancestors.

This model does not have any descendants.