2048 for NetLogo

2048 for NetLogo preview image

1 collaborator

Default-person Roman Driamov (Author)

Tags

2048 

Tagged by Roman Driamov about 5 years ago

game 

Tagged by Roman Driamov almost 5 years ago

games 

Tagged by Roman Driamov about 5 years ago

maths 

Tagged by Roman Driamov about 5 years ago

puzzle 

Tagged by Roman Driamov about 5 years ago

slider 

Tagged by Roman Driamov about 5 years ago

Visible to everyone | Changeable by the author
Model was written in NetLogo 5.0.5 • Viewed 1388 times • Downloaded 89 times • Run 0 times
Download the '2048 for NetLogo' 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 mathematical puzzle slider. Your objective is to combine identical tiles on a 4x4 grid, doubling their value until you finally get to 2048.

HOW IT WORKS

When you press any of the four directional buttons, all the numbered tiles try to move to the corresponding edge of the playing field, and a new minor tile spawns in a random unoccupied tile of the field. If there is an identical tile in the way, the tiles combine and form a new tile with twice the value.

HOW TO USE IT

  • Press the New Game button to start the game with two minor numbers.
  • You can also empty the field with "Setup field" command.
  • Swipe by clicking the directional buttons or use WASD (in order to do so, you have to first click in the white background of the Interface tab).
  • When you reach 2048, the game shows a victory message and a trigger in the code won't let you swipe anymore. If you wish to continue playing, you can check the play-after-victory? switch.

THINGS TO NOTICE

  • If you collapse a line with more than two tiles of the same value, 'forward-most' tiles get priority in combining
  • There is a 10% probability that a 4 will spawn after a turn, and a 90% probability of getting a 2
  • For every tile created, its value is added to score. After completing the objective of the game you will have a score of around 20000 points

THINGS TO TRY

An effective strategy is to always maintain a readily-collapsible row of biggest numbers 'glued' to one of the edges of the field and never swipe in the opposite direction. Be careful, though - there are situations when swiping in that direction is the only legitimate move. try to anticiate and prevent such situatuons - an unlucky spawn there can ruin half an hour of meticulous play! You can also try manipulationg the cheat-ish debug menu under the playing field. It was originally used for managing colors or checking the code for mistakes with victory conditions and the like, but now you can use it to experiment with epic field layouts and combo chains.

EXTENDING THE MODEL

This version of the game would benefit from some kind of gradual turtle movement animation, as well as a combination animation. This would require reforming the code, though, as at this moment movement and merging of tiles are made step-by-step in a chain of separate operations. Another thing to add could be an automatic save game feature, like the one in the browser version of the game.

NETLOGO FEATURES

As netLogo does not yet allow convenient label management, I had to rely on a tied turtle solution from Uri Wilensky's model "Label Position Example" to position numbers in the center of squares. I also had to create two special turtle shapes - a "frame" with an edge of 1 pixel used to create a grid and a "2048square", which is 2 pixels wider than the standard NetLogo square and fits in the "frame'.

CREDITS AND REFERENCES

2048 was originally created in March 2014 by an Italian web developer Gabriele Cirulli.

You can pay an online version of the game at http://gabrielecirulli.github.io/2048/

COPYRIGHT AND LICENSE

Copyright 2014 Roman Driamov.

CC BY-NC-SA 4.0

This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 License. To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/

Comments and Questions

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

Click to Run Model

breed [ squares square ]     ;; your basic elements
breed [ numbers number ]     ;; invisible turtles utilized to center labels
breed [ frames  frame  ]     ;; used to grid the playing field at setup
breed [ popups  popup  ]     ;; invisible turtles utilized to difplay popup messages

globals [
  score                      ;; cumulative game score
  won?                       ;; filter variable, blocks gameplay after the player creates 2048
  displayed-victory-message? ;; if a victory message has already been displayed
]

patches-own [
  occupied?                  ;; if there already is a square on the patch
]

turtles-own [
  value                      ;; value of a square
  combined?                  ;; if a square was already combined in this turn, used to prevent double-collapsing of fully same-number rows
  moveable                   ;; shows if a turtle can move, used in turn logic
]

to setup
 setup-field
 spawn 2
 setup-color
end 

to setup-grid            ;; creates a grid on the playing field
  set-default-shape frames "frame"
  ask patches [
    sprout-frames 1 [
      set color 37
      set heading 0
    ]
  ]
  ask frames [ stamp die ]
  reset-ticks
  ask patches [ set occupied? FALSE ]
end  

to setup-field
 clear-all
 set-patch-size 80
 ask patches [ set pcolor 38 ]
 set-default-shape squares "2048square"
 setup-grid
 reset-ticks
 ask patches [ set occupied? FALSE ]
 set score 0
 set displayed-victory-message? FALSE
end 

to setup-color           ;; assigns color to numeric values 
  ask squares [ 
    if value = 2    [ set color white ]
    if value = 4    [ set color 28.5  ]
    if value = 8    [ set color 27.8  ]
    if value = 16   [ set color 26    ]
    if value = 32   [ set color 25    ]
    if value = 64   [ set color 15.8  ]
    if value = 128  [ set color 15    ]
    if value = 256  [ set color 14.2  ]
    if value = 512  [ set color 125   ]
    if value = 1024 [ set color 126   ]
    if value = 2048 [ set color 114   ] 
    if value = 4096 [ set color black ]
  ]   
end 

to attach-number [x]     ;; command from "Label Position Example" model, creates a 'number' turtle with zero size and label
  hatch-numbers 1 [
    set size 0
    set label x
    ifelse x = 2 or x = 4 [ set label-color black ] [ set label-color white ]
    create-link-from myself [
      tie
      hide-link
    ]
    center
  ]
end  

to center                ;; centers the labels with different numbers 
  if label >= 1    and label <= 9    [ setxy pxcor + 0.07 pycor - 0.12 ]
  if label >= 10   and label <= 99   [ setxy pxcor + 0.12 pycor - 0.12 ]
  if label >= 100  and label <= 999  [ setxy pxcor + 0.17 pycor - 0.12 ]
  if label >= 1000 and label <= 9999 [ setxy pxcor + 0.22 pycor - 0.12 ]
end 

to reposition            ;; command from "Label Position Example" model, positions number turtles related to squares
  move-to one-of in-link-neighbors
  ask numbers [ center ]
end 

to spawn [ x ]          ;; this command spawns x squares witn numbers in unoccupied patches
  if any? patches with [ occupied? = FALSE ] [
    ask n-of x patches with [ occupied? = FALSE ] [
      sprout-squares 1 [
        ifelse random 99 > 89 [ set value 4 attach-number 4 ] [ set value 2 attach-number 2 ]
        set combined? FALSE
      ]
    set occupied? TRUE
  ]
  setup-color
]
end 


;;  Four following commands correspond to directional buttons

to move-up
  ifelse won? = TRUE and play-after-victory? = FALSE [] [ 
  ask squares [ set heading 0 set combined? FALSE ]
  assess-moves
  if any? squares with [ moveable = TRUE ] [ go ]
  check-result
  ]
end 

to move-right
  ifelse won? = TRUE and play-after-victory? = FALSE [] [ 
  ask squares [ set heading 90 set combined? FALSE ]
  assess-moves
  if any? squares with [ moveable = TRUE ] [ go ]
  check-result
    ]
end 

to move-down
  ifelse won? = TRUE and play-after-victory? = FALSE [] [ 
  ask squares [ set heading 180 set combined? FALSE ]
  assess-moves
  if any? squares with [ moveable = TRUE ] [ go ]
  check-result
  ]
end 

to move-left
  ifelse won? = TRUE and play-after-victory? = FALSE [] [
  ask squares [ set heading 270 set combined? FALSE ]
  assess-moves
  if any? squares with [ moveable = TRUE ] [ go ]
  check-result
  ]
end 

to move                ;; moves and combines turtles 
    ifelse can-move? 1 and not any? squares-on patch-ahead 1 [ fd 1 ] [
      if heading = 0   and combined? = FALSE [ if any? squares at-points [ [  0  1 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ fd 1 combine ] ] 
      if heading = 90  and combined? = FALSE [ if any? squares at-points [ [  1  0 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ fd 1 combine ] ] 
      if heading = 180 and combined? = FALSE [ if any? squares at-points [ [  0 -1 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ fd 1 combine ] ]
      if heading = 270 and combined? = FALSE [ if any? squares at-points [ [ -1  0 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ fd 1 combine ] ]
    ]
end 

to assess-moves        ;; checks if a turtle can move or collapse in a certain direction
  ask squares [ set moveable FALSE ]
  ask squares [ ifelse can-move? 1 and not any? squares-on patch-ahead 1 [ set moveable TRUE ] [
    if heading = 0   and combined? = FALSE [ if any? squares at-points [ [  0  1 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ set moveable TRUE ] ] 
    if heading = 90  and combined? = FALSE [ if any? squares at-points [ [  1  0 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ set moveable TRUE ] ] 
    if heading = 180 and combined? = FALSE [ if any? squares at-points [ [  0 -1 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ set moveable TRUE ] ]
    if heading = 270 and combined? = FALSE [ if any? squares at-points [ [ -1  0 ] ] with [ value = [ value ] of myself and combined? = FALSE ] [ set moveable TRUE ] ]
  ]
  ]
end 

to go                  ;; three-stage operation is utilized to ensure that correct order of actions is performed
  ask squares [
    if heading = 0   [ 
      ask squares with [ ycor = 2 ] [ repeat 1 [ move ] ]
      ask squares with [ ycor = 1 ] [ repeat 2 [ move ] ]
      ask squares with [ ycor = 0 ] [ repeat 3 [ move ] ]
    ]
    if heading = 90  [
      ask squares with [ xcor = 2 ] [ repeat 1 [ move ] ]
      ask squares with [ xcor = 1 ] [ repeat 2 [ move ] ]
      ask squares with [ xcor = 0 ] [ repeat 3 [ move ] ]
    ]
    if heading = 180 [
      ask squares with [ ycor = 1 ] [ repeat 1 [ move ] ]
      ask squares with [ ycor = 2 ] [ repeat 2 [ move ] ]
      ask squares with [ ycor = 3 ] [ repeat 3 [ move ] ]
      ]
    if heading = 270 [
      ask squares with [ xcor = 1 ] [ repeat 1 [ move ] ]
      ask squares with [ xcor = 2 ] [ repeat 2 [ move ] ]
      ask squares with [ xcor = 3 ] [ repeat 3 [ move ] ]
      ]
  ]
  ask patches [ ifelse any? squares-here [ set occupied? TRUE ] [ set occupied? FALSE ] ]
  spawn 1
  tick
end 

to combine             ;; this function creates a new square in place of the two collapsed ones and increases score
  if any? other squares-here with [ value = [ value ] of myself ] [
    ask one-of other squares-here with [ value = [ value ] of myself ] [ die ]
    ask numbers-here [ die ]
    hatch-squares 1 [ 
      set value [ value ] of myself * 2
      set score score + value 
      attach-number value 
      set combined? TRUE 
    ]
    die
    ]
end 

to check-result         ;; this function checks the game state (won / lost / playing after victory)
  if any? squares with [ value = 2048 ] [ set won? TRUE ]
  if won? = TRUE and play-after-victory? = FALSE [ win-game ]
  if won? = TRUE and play-after-victory? = TRUE and displayed-victory-message? = TRUE  [ ask popups [ die ] ]
  if won? = TRUE and play-after-victory? = TRUE and displayed-victory-message? = FALSE [ win-game ]
  ask squares [ set combined? FALSE ]
  ask squares [ set heading 0   ]
  assess-moves
  if not any? squares with [ moveable = TRUE ] [
    ask squares [ set heading 90  ]
    assess-moves
    if not any? squares with [ moveable = TRUE ] [
      ask squares [ set heading 180 ]
      assess-moves
      if not any? squares with [ moveable = TRUE ] [
        ask squares [ set heading 270 ]
        assess-moves
        if not any? squares with [ moveable = TRUE ] [ lose-game ]
      ]
    ]
  ]
  ask numbers [ reposition ]
end 

to win-game            ;; shows victory message
  create-popups 1 [
    set size 0
    set label "YOU WIN!"
    set label-color grey
    setxy 2 1.4
    ]
  set displayed-victory-message? TRUE
end  

to lose-game           ;; shows gameover message
  create-popups 1 [
    set size 0
    set label "GAME OVER"
    set label-color grey
    setxy 2 1.4
    ]
end 


;; Debug tools
;; These commands let you "cheat" by placing and removing squares from the field.
;; In order to use them you have to check the debug? switch 

to place [ x ]
  if debug? [
    if place-randomly? [ if any? patches with [ occupied? = FALSE ] [ ask one-of patches with [ occupied? = FALSE ] [ 
        sprout-squares 1 [
          set value x
          attach-number x
          set combined? FALSE
          set occupied? TRUE ] 
    ]
    ]
    setup-color
    stop
    ]
    if not place-randomly? [
      if mouse-down? [
      ask patches with [ pxcor = round mouse-xcor and pycor = round mouse-ycor and occupied? = FALSE ] [
        sprout-squares 1 [
          set value x
          attach-number x
          set combined? FALSE
          set occupied? TRUE
        ]
      ]
    ]
    ]
    setup-color
  ]
end 

to kill
  if debug? [
    if kill-randomly? [ ask one-of squares [ ask turtles-here [ die ] ] ask patches [ ifelse any? squares-here [ set occupied? TRUE ] [ set occupied? FALSE ] ] stop ]
    if not kill-randomly? [ if mouse-down? [ 
        ask turtles with [ pxcor = round mouse-xcor and pycor = round mouse-ycor ] [ die ] 
        ask patches [ ifelse any? squares-here [ set occupied? TRUE ] [ set occupied? FALSE ] ] ] ]
    ]
end 

There are 9 versions of this model.

Uploaded by When Description Download
Roman Driamov about 5 years ago optimized the "go" command to make use of "repeat" function Download this version
Roman Driamov about 5 years ago The "go" procedure turned out to have a major error, rewrote it. Download this version
Roman Driamov about 5 years ago fixed gameover message triggering incorrectly in certain situations Download this version
Roman Driamov about 5 years ago fixed updating of occupied? in kill command Download this version
Roman Driamov about 5 years ago version with turn count, debug tools and lightened setup function Download this version
Roman Driamov about 5 years ago Reverted to older version Download this version
Roman Driamov about 5 years ago Reverted to older version Download this version
Roman Driamov about 5 years ago added turn count and debug menu Download this version
Roman Driamov about 5 years ago Initial upload Download this version

Attached files

File Type Description Last updated
2048 for NetLogo.png preview Preview for '2048 for NetLogo' about 5 years ago, by Roman Driamov Download

This model does not have any ancestors.

This model does not have any descendants.