# 2048 ### 1 collaborator Aiden Cowling (Author)

### Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by everyone
Model was written in NetLogo 5.2.0 • Viewed 484 times • Downloaded 27 times • Run 0 times Download this modelEmbed this model

## 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/ 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"
sprout-frames 1 [
set color 37
]
]
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
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 ]
tie
]
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
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 [] [
assess-moves
if any? squares with [ moveable = TRUE ] [ go ]
check-result
]
end

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

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

to move-left
ifelse won? = TRUE and play-after-victory? = 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 with [ ycor = 2 ] [ repeat 1 [ move ] ]
ask squares with [ ycor = 1 ] [ repeat 2 [ move ] ]
ask squares with [ ycor = 0 ] [ repeat 3 [ move ] ]
]
ask squares with [ xcor = 2 ] [ repeat 1 [ move ] ]
ask squares with [ xcor = 1 ] [ repeat 2 [ move ] ]
ask squares with [ xcor = 0 ] [ repeat 3 [ move ] ]
]
ask squares with [ ycor = 1 ] [ repeat 1 [ move ] ]
ask squares with [ ycor = 2 ] [ repeat 2 [ move ] ]
ask squares with [ ycor = 3 ] [ repeat 3 [ move ] ]
]
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 ]
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 ]
assess-moves
if not any? squares with [ moveable = TRUE ] [
assess-moves
if not any? squares with [ moveable = TRUE ] [
assess-moves
if not any? squares with [ moveable = TRUE ] [
assess-moves
if not any? squares with [ moveable = TRUE ] [ lose-game ]
]
]
]
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 is only one version of this model, created about 5 years ago by Aiden Cowling.

## Attached files

File Type Description Last updated