2048: Difference between revisions

9,979 bytes added ,  15 days ago
m
→‎{{header|FutureBasic}}: Remove FutureBasic 'Output' label
(2048 in FreeBASIC)
m (→‎{{header|FutureBasic}}: Remove FutureBasic 'Output' label)
 
(20 intermediate revisions by 9 users not shown)
Line 11:
:*   All tiles move as far as possible in that direction, some move more than others.
:*   Two adjacent tiles (in that direction only) with matching numbers combine into one bearing the sum of those numbers.
:*   A move is valid when at least one tile can be moved,   if onlyincluding by combination.
:*   A new tile with the value of   '''2'''   is spawned at the end of each turn at a randomly chosen empty square   (if there is one).
:*   Adding a new tile on a blank space.   Most of the time,   a new   '''2'''   is to be added,   andbut occasionally   ('''10%''' of the time),   a   '''4'''.
:*   To win,   the player must create a tile with the number   '''2048'''.
:*   The player loses if no valid moves are possible.
 
Line 22:
 
;Requirements:
* &nbsp; "Non-greedy" movement. &nbsp; <br>&nbsp; The tiles that were created by combining other tiles should not be combined again during the same turn (move). &nbsp; <br>&nbsp; That is to say, &nbsp; that moving the tile row of:
 
<big><big> [2][2][2][2] </big></big>
Line 34:
<big><big> .........[8] </big></big>
 
* &nbsp; "Move direction priority". &nbsp; <br>&nbsp; If more than one variant of combining is possible, &nbsp; move direction shall indicate which combination will take effect. <br>&nbsp; For example, moving the tile row of:
 
<big><big> ...[2][2][2] </big></big>
Line 48:
 
 
* &nbsp; Check for valid moves. &nbsp; The player shouldn't be able to skipgain theirnew turntile by trying a move that doesn't change the board.
* &nbsp; Check for a &nbsp;win condition.
* &nbsp; Check for a lose condition.
<br><br>
Line 55:
=={{header|AArch64 Assembly}}==
{{works with|as|Raspberry Pi 3B version Buster 64 bits}}
<syntaxhighlight lang="aarch64 assembly">
<lang AArch64 Assembly>
/* ARM assembly AARCH64 Raspberry PI 3B */
/* program 2048_64.s */
Line 1,106:
/* for this file see task include a file in language AArch64 assembly */
.include "../includeARM64.inc"
</syntaxhighlight>
</lang>
=={{header|Ada}}==
{{works with|GNAT}}
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO; use Ada.Text_IO;
with System.Random_Numbers;
procedure Play_2048 is
Line 1,286:
end loop Main_Loop;
end Play_2048;
</syntaxhighlight>
</lang>
{{out}}
<pre>+----+----+----+----+
Line 1,300:
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68">
main:(
INT side = 4;
Line 1,443:
lose: print(("you lose!", new line))
)
</syntaxhighlight>
</lang>
=={{header|Amazing Hopper}}==
<pre>
VERSION 1: "Hopper" flavour.
</pre>
<syntaxhighlight lang="amazing hopper">
<lang Amazing Hopper>
#context-free select Position of aleatory tail
#context-free show Table
Line 1,685:
println
back
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,740:
VERSION 2: "Hopper-BASIC" flavour.
</pre>
<syntaxhighlight lang="amazing hopper">
<lang Amazing Hopper>
 
// Definicion de "contextos"
Line 2,029:
Clear Mark.
Return
</syntaxhighlight>
</lang>
{{out}}
<pre>
Se invoca como:
 
rxvt -g 79x38 -fn "xft:FantasqueSansMono-Regular:pixelsize=25" -e hopper bas/2048.bas
 
</pre>
[[File:Captura_de_pantalla_de_2022-10-07_14-43-23.png]]
 
=={{header|Applesoft BASIC}}==
<langsyntaxhighlight Applesoftlang="applesoft">PRINT "Game 2048"
 
10 REM ************
Line 2,238 ⟶ 2,246:
 
 
</syntaxhighlight>
</lang>
 
=={{header|ARM Assembly}}==
{{works with|as|Raspberry Pi}}
<syntaxhighlight lang="arm assembly">
<lang ARM Assembly>
/* ARM assembly Raspberry PI */
/* program 2048.s */
Line 3,134 ⟶ 3,142:
/***************************************************/
.include "../affichage.inc"
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 3,157 ⟶ 3,165:
 
=={{header|AutoHotkey}}==
<langsyntaxhighlight AutoHotkeylang="autohotkey">Grid := [], s := 16, w := h := S * 4.5
Gui, font, s%s%
Gui, add, text, y1
Line 3,380 ⟶ 3,388:
Grid[StrSplit(rnd, ",").1, StrSplit(rnd, ",").2] := 2
}
;------------------------------</langsyntaxhighlight>
 
=={{header|Batch File}}==
<langsyntaxhighlight lang="dos">:: 2048 Game Task from RosettaCode
:: Batch File Implementation v2.0.1
 
Line 3,554 ⟶ 3,562:
echo(Press any key to exit . . .
pause>nul
exit /b 0</langsyntaxhighlight>
{{out}}
<pre>2048 Game in Batch
Line 3,574 ⟶ 3,582:
 
=={{header|BASIC}}==
==={{works withheader|QBasic}}===
El código es de MichD (https://github.com/michd/2048-qbasic)
 
Yo solo lo transcribo.
<langsyntaxhighlight lang="qbasic">
SCREEN 13
PALETTE 1, pColor(35, 33, 31)
Line 3,933 ⟶ 3,941:
PRINT "Score:" + STR$(gScore)
END SUB
</syntaxhighlight>
</lang>
 
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> SIZE = 4 : MAX = SIZE-1
Won% = FALSE : Lost% = FALSE
@% = 5
Line 4,007 ⟶ 4,014:
IF Board(z DIV SIZE,z MOD SIZE) = 0 THEN Board(z DIV SIZE,z MOD SIZE) = 2-(RND(10)=1)*2 : EXIT FOR
NEXT
ENDPROC</langsyntaxhighlight>
{{out}}
<pre> _ _ _ _
Line 4,039 ⟶ 4,046:
--------------------
You lost :-(</pre>
 
=={{header|BQN}}==
<syntaxhighlight lang="bqn">
#!/usr/bin/env BQN
# 2048 game
# The game is controlled with the vim movement keys:
# h: left, j: down, k: up, l: right, q: quit
# needs a VT-100 compatible terminal
 
Merge←{𝕩 0⊸≠⊸/↩ ⋄ m←<`=⟜«𝕩 ⋄ 4↑(¬»m)/𝕩×1+m}⌾⌽ # Merge a single row to the right
Step←Merge˘ # Merges each row of the board
Up←Step⌾(⌽⍉∘⌽) # Each direction merges the board
Down←Step⌾⍉ # by rotating it to the correct orientation, merging the rows
Right←Step # and reversing the rotation
Left←Step⌾(⌽˘)
# Spawns a 2 or a 4 (10% chance) at a random empty position
Spawn←{i←•rand.Range∘≠⊸⊑(0⊸= /○⥊ ↕∘≢)𝕩 ⋄ (•rand.Range∘≠⊸⊑9‿1/2‿4)⌾(i⊸⊑) 𝕩}
Lose←Left∘Right∘Down∘Up⊸≡ # Losing condition, no moves change the board
Win←∨´·∨˝2048⊸= # Winning condition, 2048!
 
Quit←{•Out e∾"[?12l"∾e∾"[?25h" ⋄ •Exit 𝕩} # Restores the terminal and exits
Display←{ # Displays the board, score and controls
•Out e∾"[H"∾e∾"[2J" # Cursor to origin and clear screen
•Out "Controls: h: left, j: down, k: up, l: right, q: quit"
•Show 𝕩
•Out "score: "∾•Repr ⌈´⌈˝ 𝕩
}
 
board←Spawn 4‿4⥊0
e←@+27 # Escape character for the ANSI escape codes
•term.RawMode 1
•Out e∾"[?25l"∾e∾"[2J"∾e∾"[H" # Cursor to origin, hide it and clear screen
{𝕤⋄
Display board
{𝕤⋄•Out "You win!" ⋄ Quit 0}⍟Win board
{𝕤⋄•Out "You lose!"⋄ Quit 1}⍟Lose board
key←•term.CharB @ # Read key
⊑key∊"hjklq"? # Valid key?
{𝕤⋄ Quit 0}⍟(key='q')@ # Quit key?
move←⊑(key="hjkl")/Left‿Down‿Up‿Right # Get movement function from the key
{𝕤⋄board↩Spawn∘Move 𝕩}⍟(Move⊸≢) board # Generate the next board if the move is valid
; @
}•_While_{𝕤⋄1}@
</syntaxhighlight>
 
=={{header|C}}==
===Version 1===
Supports limited colours through vt100 escape codes. Requires a posix machine for <tt>termios.h</tt> and <tt>unistd.h</tt> headers. Provides simplistic animations when moving and merging blocks.
<syntaxhighlight lang="c">
<lang c>
#include <stdio.h>
#include <stdlib.h>
Line 4,323 ⟶ 4,374:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 4,340 ⟶ 4,391:
 
 
<syntaxhighlight lang="c">
<lang c>
 
#include <stdio.h>
Line 4,682 ⟶ 4,733:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|C sharp|C#}}==
{{trans|C++}}
<langsyntaxhighlight lang="csharp">using System;
 
namespace g2048_csharp
Line 5,080 ⟶ 5,131:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,100 ⟶ 5,151:
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <time.h>
#include <iostream>
Line 5,294 ⟶ 5,345:
return system( "pause" );
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 5,313 ⟶ 5,364:
 
=={{header|Clojure}}==
<langsyntaxhighlight lang="clojure">
(ns 2048
(:require [clojure.string :as str]))
Line 5,432 ⟶ 5,483:
:default (recur (handle-turn field)))))
 
(play-2048)</langsyntaxhighlight>
 
{{out}}
Line 5,447 ⟶ 5,498:
=={{header|Common Lisp}}==
Depends on Windows msvcrt.dll for _getch. Depends on quicklisp. Use arrow keys to make moves and press "Q" to quit. Tested with SBCL.
<langsyntaxhighlight lang="lisp">(ql:quickload '(cffi alexandria))
 
(defpackage :2048-lisp
Line 5,647 ⟶ 5,698:
(format t "~% Score: ~D~%" score)
(print-board board 4)
(prompt-input board score))</langsyntaxhighlight>
{{out}}
<pre>* (2048-lisp::prompt)
Line 5,675 ⟶ 5,726:
=={{header|D}}==
{{trans|C++}}
<langsyntaxhighlight lang="d">import std.stdio, std.string, std.random;
import core.stdc.stdlib: exit;
 
struct G2048 {
public void gameLoop() /*@safe @nogc*/ {
addTile;
while (true) {
Line 5,693 ⟶ 5,744:
 
private:
static struct Tile {
uint val = 0;
bool blocked = false;
Line 5,705 ⟶ 5,756:
uint score = 0;
 
void drawBoard() const /*@safe @nogc*/ {
writeln("SCORE: ", score, "\n");
foreach (immutable y; 0 .. side) {
write("+------+------+------+------+\n| ");
foreach (immutable x; 0 .. side) {
if (board[x][y].val)
writef("%4d", board[x][y].val);
Line 5,718 ⟶ 5,769:
writeln;
}
writeln("+------+------+------+------+\n".writeln);
}
 
void waitKey() /*@safe*/ {
moved = false;
write("(W)Up (S)Down (A)Left (D)Right (Q)Quit: ".write);
immutableauto c = readln.strip.toLower;
 
switch (c) {
Line 5,735 ⟶ 5,786:
}
 
foreach (immutable y; 0 .. side)
foreach (immutable x; 0 .. side)
board[x][y].blocked = false;
}
Line 5,745 ⟶ 5,796:
}
 
void addTile() /*nothrow*/ @safe /*@nogc*/ {
foreach (immutable y; 0 .. side) {
foreach (immutable x; 0 .. side) {
if (!board[x][y].val) {
uint a, b;
Line 5,764 ⟶ 5,815:
}
 
bool canMove() const pure nothrow @safe @nogc {
foreach (immutable y; 0 .. side)
foreach (immutable x; 0 .. side)
if (!board[x][y].val)
return true;
 
foreach (immutable y; 0 .. side) {
foreach (immutable x; 0 .. side) {
if (testAdd(x + 1, y, board[x][y].val) ||
testAdd(x - 1, y, board[x][y].val) ||
Line 5,782 ⟶ 5,833:
}
 
bool testAdd(in uint x, in uint y, in uint v) const pure nothrow @safe @nogc {
if (x > 3 || y > 3)
return false;
Line 5,788 ⟶ 5,839:
}
 
void moveVertically(in uint x, in uint y, in uint d) pure nothrow @safe @nogc {
if (board[x][y + d].val && board[x][y + d].val == board[x][y].val &&
!board[x][y].blocked && !board[x][y + d].blocked) {
Line 5,811 ⟶ 5,862:
}
 
void moveHorizontally(in uint x, in uint y, in uint d) pure nothrow @safe @nogc {
if (board[x + d][y].val && board[x + d][y].val == board[x][y].val &&
!board[x][y].blocked && !board[x + d][y].blocked) {
Line 5,834 ⟶ 5,885:
}
 
void move(in moveDir d) pure nothrow @safe @nogc {
final switch (d) with(moveDir) {
case up:
foreach (immutable x; 0 .. side)
foreach (immutable y; 1 .. side)
if (board[x][y].val)
moveVertically(x, y, -1);
break;
case down:
foreach (immutable x; 0 .. side)
foreach_reverse (immutable y; 0 .. 3)
if (board[x][y].val)
moveVertically(x, y, 1);
break;
case left:
foreach (immutable y; 0 .. side)
foreach (immutable x; 1 .. side)
if (board[x][y].val)
moveHorizontally(x, y, -1);
break;
case right:
foreach (immutable y; 0 .. side)
foreach_reverse (immutable x; 0 .. 3)
if (board[x][y].val)
moveHorizontally(x, y, 1);
Line 5,866 ⟶ 5,917:
G2048 g;
g.gameLoop;
}</langsyntaxhighlight>
The output is the same as the C++ version.
 
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{libheader| Velthuis.Console}}Thanks for Rudy Velthuis [https://github.com/rvelthuis/Consoles].
{{Trans|C++}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program Game2048;
 
Line 6,277 ⟶ 6,329:
Writeln('Press Enter to exit');
Readln;
end.</langsyntaxhighlight>
{{out}}
<pre>
Line 6,298 ⟶ 6,350:
=={{header|Elixir}}==
{{works with|Elixir|1.3}}
<langsyntaxhighlight lang="elixir">defmodule Game2048 do
@size 4
@range 0..@size-1
Line 6,412 ⟶ 6,464:
end
 
Game2048.play 512</langsyntaxhighlight>
 
{{out}}
Line 6,444 ⟶ 6,496:
{{works with|Elm 0.18.0}}
Try online [https://ellie-app.com/3ZMMpYsbfcMa1/3]
<langsyntaxhighlight Elmlang="elm">module Main exposing (..)
 
import Html exposing (Html, div, p, text, button, span, h2)
Line 6,846 ⟶ 6,898:
viewGrid model.tiles
]
</syntaxhighlight>
</lang>
 
=={{header|F Sharp|F#}}==
Line 6,852 ⟶ 6,904:
The following code can be executed as is using F# Interactive from system command line ("fsi.exe 2048.fsx") but not from Visual Studio F# Interactive window due to the way it access keyboard (the System.Console.ReadKey() function).
 
<langsyntaxhighlight lang="fsharp">
// the board is represented with a list of 16 integers
let empty = List.init 16 (fun _ -> 0)
Line 6,912 ⟶ 6,964:
 
play()
</syntaxhighlight>
</lang>
 
=={{header|Factor}}==
Line 6,927 ⟶ 6,979:
 
 
<syntaxhighlight lang="factor">
<lang Factor>
USE: accessors
FROM: arrays => <array> array ;
Line 7,248 ⟶ 7,300:
 
MAIN: start-2048
</syntaxhighlight>
</lang>
 
=={{header|Forth}}==
Line 7,256 ⟶ 7,308:
Just like my implementation of [[15 Puzzle Game#Forth|15 Puzzle Game]], this uses Vim's h/j/k/l for movement.
 
<langsyntaxhighlight lang="forth">\ in Forth, you do many things on your own. This word is used to define 2D arrays
: 2D-ARRAY ( height width )
CREATE DUP ,
Line 7,490 ⟶ 7,542:
 
INIT
MAIN-LOOP</langsyntaxhighlight>
 
{{out}}
Line 7,517 ⟶ 7,569:
 
===Source===
The initial attempt at showing the board relied rather heavily on FORMAT tricks, in particular the use of the <''n''> facility whereby the value of an integer expression can be inserted into a format statement's coding on-the-fly, as in the following. <langsyntaxhighlight Fortranlang="fortran">
WRITE (MSG,1) !Roll forth a top/bottom boundary. No corner characters (etc.), damnit.
1 FORMAT ("|",<NC>(<W>("-"),"|")) !Heavy reliance on runtime values in NC and W. But see FORMAT 22.
Line 7,523 ⟶ 7,575:
WRITE (MSG,22) ((" ",L1 = 1,W),"|",C = 1,NC) !Compare to FORMAT 2.
22 FORMAT ("|",666A1) !A constant FORMAT, a tricky WRITE.
4 FORMAT ("|",<NC - 1>(<W>("-"),"+"),<W>("-"),"|") !With internal + rather than |.</langsyntaxhighlight>
This sort of thing is not necessarily accepted by all compilers, so instead the next stage was to convert to using complicated WRITE statements. If one regarded the various sizes (the values of NR, NC, W in the source) as truly fixed, literal constants could be used throughout. This would however mean that they would appear without explanation, and if one eventually attempted to recode with different values, mistakes would be likely. Thus below, FORMAT 3 has <code> (<NC>(A1,I<W>),A1)</code> and if the <> scheme were unavailable, you'd have to use <code>(4(A1,I6),A1)</code> instead, not too troublesome a change. Or, the text of the format sequence could be written to a CHARACTER variable, as demonstrated in [[Multiplication_tables#Traditional_approach]]. Yet another approach might be <code>(666(A1,I6))</code> which relies on the addendum <code>A1</code> happening to be the same as the start of the <code>(A1,I6)</code> pair, but there is still the appearance of the literal constant six instead of <W>, and if there were to be any change to be made, it would have to be remembered...
<langsyntaxhighlight Fortranlang="fortran"> SUBROUTINE SHOW(NR,NC,BOARD) !Mess about.
INTEGER NR,NC !Number of rows and columns.
INTEGER BOARD(NR,NC) !The board. Actual storage is transposed!
Line 7,715 ⟶ 7,767:
601 FORMAT ("None! Oh dear.") !Nothing more can be done.
END !That was fun.
</syntaxhighlight>
</lang>
 
===Output===
Line 7,771 ⟶ 7,823:
=={{header|FreeBASIC}}==
Based On MichD's original code (https://github.com/michd/2048-qbasic)
<langsyntaxhighlight lang="freebasic">#define EXTCHAR Chr(255)
 
'--- Declaration of global variables ---
Line 8,081 ⟶ 8,133:
End Select
Loop
Loop</langsyntaxhighlight>
 
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
begin enum 123
_lf
_rt
_dn
_up
_new
_end
end enum
str63 bd
colorref color(11)
byte zs
 
void local fn initialize
subclass window 1, @"2048",(0,0,438,438)
fn WindowSetBackgroundColor( 1, fn ColorBlack )
color(0) = fn ColorDarkGray
color(1) = fn ColorGray
color(2) = fn ColorLightGray
color(3) = fn ColorBlue
color(4) = fn ColorBrown
color(5) = fn ColorCyan
color(6) = fn ColorGreen
color(7) = fn ColorMagenta
color(8) = fn ColorOrange
color(9) = fn ColorPurple
color(10) = fn ColorYellow
color(11) = fn ColorRed
end fn
 
void local fn drawBoard
int x, y,r = 1, add
cls
for y = 320 to 20 step -100
for x = 20 to 320 step 100
rect fill (x,y,98,98),color( bd[r] )
select bd[r]
case < 4 : add = 40
case < 7 : add = 30
case < 10 : add = 20
case else : add = 6
end select
if bd[r] then print %(x+add, y+25)2^bd[r]
r++
next
next
end fn
 
local fn finish( won as bool )
CFStringRef s = @"GAME OVER"
CGRect r = fn windowContentRect( 1 )
r.origin.y += r.size.height - 20
r.size.height = 100
window 2,,r,NSwindowStyleMaskBorderless
if won
fn windowSetBackgroundColor( 2, color(11) )
s = @"CONGRATULATIONS—YOU DID IT!!"
text,24,fn ColorBlack,,NSTextAlignmentCenter
else
fn windowSetBackgroundColor( 2, fn ColorBlack )
text,24,fn ColorWhite,,NSTextAlignmentCenter
end if
print s
button _new,,,@"New Game", (229,20,100,32)
button _end,,,@"Quit", (109,20,100,32)
end fn
 
void local fn newGame
int r
text @"Arial bold", 36, fn ColorBlack, fn ColorClear
bd = chr$(0)
for r = 1 to 4
bd += bd
next
bd[rnd(16)] ++
do
r = rnd(16)
until bd[r] == 0
bd[r]++
zs = 14
fn drawBoard
end fn
 
local fn play( st as short, rd as short, cd as short )
short a, b, c, t, moved = 0
for a = st to st + rd * 3 step rd
// SHIFT
t = a
for b = a to a + cd * 3 step cd
if bd[b]
if t <> b then swap bd[t], bd[b] : moved ++
t += cd
end if
next
// MERGE
for b = a to a + cd * 2 step cd
if bd[b] > 0 && bd[b] == bd[b+cd]
bd[b]++ : c = b + cd
// FILL IN
while c <> a+cd*3
bd[c] = bd[c+cd] : c += cd
wend
bd[c] = 0
// CHECK FOR WIN
if bd[b] == 11 then fn drawBoard : fn finish( yes ) : exit fn
zs ++ : moved ++
end if
next
next
fn drawBoard
if moved == 0 then exit fn
// GROW
b = 0 : c = rnd(zs)
while c
b ++
if bd[b] == 0 then c--
wend
if rnd(10) - 1 then bd[b]++ else bd[b] = 2
zs--
timerbegin 0.25
fn drawBoard
timerend
if zs then exit fn
// IS GAME OVER?
for a = 1 to 12
if bd[a] == bd[a+4] then exit fn
next
for a = 1 to 13 step 4
if bd[a] == bd[a+1] || bd[a+1] == bd[a+2] || bd[a+2] == bd[a+3]¬
then exit fn
next
fn finish( no )
end fn
 
local fn doDialog(ev as long,tag as long, wnd as long)
select ev
case _windowKeyDown : if window() == 2 then exit fn
select fn EventKeyCode
case _up : fn play(13, 1, -4)
case _dn : fn play( 1, 1, 4)
case _lf : fn play( 1, 4, 1)
case _rt : fn play( 4, 4, -1)
case else : exit fn
end select
DialogEventSetBool(yes)
case _btnClick : window close 2
if tag == _end then end
fn newGame
case _windowWillClose : if wnd == 1 then end
end select
end fn
 
fn initialize
fn newGame
on dialog fn doDialog
 
handleevents
</syntaxhighlight>
[[File:FutureBasic 2048.png]]
 
=={{header|Go}}==
 
<langsyntaxhighlight Golang="go">package main
 
import (
Line 8,355 ⟶ 8,573:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Haskell}}==
<langsyntaxhighlight lang="haskell">import System.IO
import Data.List
import Data.Maybe
Line 8,490 ⟶ 8,708:
setCursorPosition 1 1
putStrLn $ intercalate "\n\n\n\ESC[C" $ concatMap showTile `map` pos
</syntaxhighlight>
</lang>
 
=={{header|J}}==
'''Solution'''
<langsyntaxhighlight lang="j">NB. 2048.ijs script
NB. =========================================================
NB. 2048 game engine
Line 8,599 ⟶ 8,817:
- start a new game:
grd=: g2048Con ''
)</langsyntaxhighlight>
'''Usage'''
<langsyntaxhighlight lang="j"> grd=: g2048Con ''
 
Score is 0
Line 8,620 ⟶ 8,838:
0 0 4 4
0 0 0 2
...</langsyntaxhighlight>
 
=={{header|Java}}==
[[File:game_2048_java2.png|300px|thumb|right]]
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.awt.*;
import java.awt.event.*;
import java.util.Random;
Line 8,922 ⟶ 9,140:
return -1;
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
Uses the P5.js library.
<syntaxhighlight lang="javascript">
<lang JavaScript>
/* Tile object: */
 
Line 9,106 ⟶ 9,324:
game.keyHandler(keyCode);
}
</syntaxhighlight>
</lang>
 
=={{header|Julia}}==
Uses the Gtk toolkit. Includes scoring, a choice of board size and toolbar buttons for Undo and New Game.
<langsyntaxhighlight lang="julia">using Gtk.ShortNames
 
@enum Direction2048 Right Left Up Down
Line 9,281 ⟶ 9,499:
const boardsize = 4
app2048(boardsize)
</syntaxhighlight>
</lang>
 
=={{header|Koka}}==
Based on F#
<syntaxhighlight lang="koka">
import std/num/random
import std/os/readline
 
val empty = list(0, 15).map(fn(_) 0)
fun win(l)
l.any(fn(x) x == 2048)
 
fun stack(l)
match l
Cons(0, tl) -> tl.stack ++ [0]
Cons(hd, tl) -> Cons(hd, tl.stack)
Nil -> Nil
 
fun join(l: list<int>)
match l
Cons(a, Cons(b, c)) | a == b -> Cons((a + b), c.join) ++ [0]
Cons(a, b) -> Cons(a, b.join)
Nil -> Nil
 
fun hit(l)
l.stack.join
 
fun hitBack(l)
l.reverse.hit.reverse
 
fun splitBy(l: list<a>, i: int): div list<list<a>>
val (a, b) = l.split(i)
match b
Cons -> Cons(a, b.splitBy(i))
Nil -> Cons(a, Nil)
 
fun transpose(l: list<list<a>>): <exn> list<list<a>>
match l
Cons(Cons(a, b), c) -> Cons(Cons(a, c.map(fn(x) x.head.unjust)), transpose(Cons(b, c.map(fn(x) x.tail)).unsafe-decreasing))
Cons(Nil, b) -> transpose(b)
Nil -> Nil
 
fun rows(l)
l.splitBy(4)
 
fun left(l)
l.rows.map(hit).concat
 
fun right(l)
l.rows.map(hitBack).concat
 
fun up(l)
l.rows.transpose.map(hit).transpose.concat
 
fun down(l)
l.rows.transpose.map(hitBack).transpose.concat
 
fun (==)(l1: list<int>, l2: list<int>): bool
match l1
Cons(a, b) -> match l2
Cons(c, d) -> a == c && b == d
Nil -> False
Nil -> match l2
Cons -> False
Nil -> True
 
fun lose(l)
l.left == l && l.right == l && l.up == l && l.down == l
 
fun numZeros(l: list<int>): int
l.filter(fn(x) x == 0).length
 
fun insert(l: list<int>, what: int, toWhere: int)
match l
Cons(0, tail) | tail.numZeros == toWhere -> Cons(what, tail)
Cons(head, tail) -> Cons(head, tail.insert(what, toWhere))
Nil -> Nil
 
fun spawnOn(l)
val newTileValue = if random-int() % 10 == 0 then 4 else 2
val newPosition = random-int() % (l.numZeros - 1)
l.insert(newTileValue, newPosition)
 
fun show-board(l: list<int>): div string
"\n" ++ l.rows.map(fn(r) r.map(fn(x) x.show.pad-left(4)).join("")).intersperse("\n").join("") ++ "\n"
 
fun quit(l)
[]
 
fun quitted(l)
l.is-nil
 
fun dispatch(c)
match c
'i' -> up
'j' -> left
'k' -> down
'l' -> right
'q' -> quit
_ ->
println("Unknown command: keys are ijkl to move, q to quit")
id
 
fun key()
readline().head-char.default('_')
 
fun turn(l)
l.show-board.println
val next = dispatch(key())(l)
if !(next == l) && next.quitted.not then
spawnOn(next)
else
next
 
fun play(state)
if state.win || state.lose || state.quitted then
if state.quitted then
"You quit!".println
else if state.win then
"You won!".println
else
"You lost!".println
else
"play".println
play(turn(state))
 
fun main()
print("ijkl to move, q to quit\n")
val initial = empty.spawnOn
println("Starting game...")
play(initial)
 
</syntaxhighlight>
 
=={{header|Kotlin}}==
Stateless with focus on clarity rather than conciseness.
 
<langsyntaxhighlight lang="scala">import java.io.BufferedReader
import java.io.InputStreamReader
 
Line 9,455 ⟶ 9,805:
}
println("+----+----+----+----+")
}</langsyntaxhighlight>
 
Sample output:
Line 9,476 ⟶ 9,826:
Takes input on stdin using the words "left", "right", "up", "down".
 
<syntaxhighlight lang="latitude">
<lang Latitude>
use 'format import '[format].
use 'random.
Line 9,703 ⟶ 10,053:
$stdout putln: "Better luck next time!".
}.
</syntaxhighlight>
</lang>
 
Sample output:
Line 9,719 ⟶ 10,069:
=={{header|Lua}}==
Sadly, ANSI C doesn't have low-level keyboard input, so neither does vanilla Lua, so the input is a bit cumbersome (wasd PLUS enter).
<langsyntaxhighlight lang="lua">-- 2048 for Lua 5.1-5.4, 12/3/2020 db
local unpack = unpack or table.unpack -- for 5.3 +/- compatibility
game = {
Line 9,794 ⟶ 10,144:
end
}
game:play()</langsyntaxhighlight>
{{out}}
<pre>+----+----+----+----+
Line 9,808 ⟶ 10,158:
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Game2048 {
\\ 10% 4 and 90% 2
Line 9,932 ⟶ 10,282:
}
Game2048
</syntaxhighlight>
</lang>
 
Each move copied to clipboard
Line 9,964 ⟶ 10,314:
 
Next is the main body of code:
<syntaxhighlight lang="maple">
<lang Maple>
macro(SP=DocumentTools:-SetProperty, GP=DocumentTools:-GetProperty);
G := module()
Line 10,184 ⟶ 10,534:
end module;
G:-reset();SP("Score/Lose",caption,"Click an Arrow to begin.");
</syntaxhighlight>
</lang>
 
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">SetOptions[InputNotebook[],NotebookEventActions->{
"LeftArrowKeyDown":>(stat=Coalesce[stat];AddNew[]),
"RightArrowKeyDown":>(stat=Reverse/@Coalesce[Reverse/@stat];AddNew[]),
Line 10,221 ⟶ 10,571:
 
stat=Nest[AddRandomNumber[#,RandomChoice[{2,4}]]&,ConstantArray[0,{n,n}],4];
Dynamic[PrintStat@stat]</langsyntaxhighlight>
 
 
=={{header|MATLAB}}==
 
<langsyntaxhighlight MATLABlang="matlab">function field = puzzle2048(field)
 
if nargin < 1 || isempty(field)
Line 10,357 ⟶ 10,707:
vector(vector==0) = [];
 
end</langsyntaxhighlight>
 
You can start with an empty 4 x 4 board and save the last state of the playing field with:
<langsyntaxhighlight MATLABlang="matlab">field = puzzle2048();</langsyntaxhighlight>
 
Or you start from a saved playing field:
<langsyntaxhighlight MATLABlang="matlab">field = puzzle2048(savedField);</langsyntaxhighlight>
 
=={{header|Nim}}==
Line 10,369 ⟶ 10,719:
{{works with|Nim Compiler|0.19.4}}
 
<langsyntaxhighlight lang="nim">import random, strutils, terminal
 
const
Line 10,553 ⟶ 10,903:
for i in 1..BoardLength + 7:
eraseLine()
cursorUp()</langsyntaxhighlight>
 
=={{header|OCaml}}==
 
<langsyntaxhighlight lang="ocaml">
let list_make x v =
let rec aux acc i =
Line 10,706 ⟶ 11,056:
loop grid
in
loop grid</langsyntaxhighlight>
 
{{out}}
Line 10,746 ⟶ 11,096:
 
=={{header|Pascal}}==
<syntaxhighlight lang="pascal">
<lang Pascal>
program game2048;
uses Crt;
Line 11,109 ⟶ 11,459:
until end_game;
end.
</syntaxhighlight>
</lang>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
 
use strict; # https://rosettacode.org/wiki/2048
Line 11,198 ⟶ 11,548:
add2(2) for 1, 2;
$winner = '';
}</langsyntaxhighlight>
 
=={{header|Phix}}==
Line 11,206 ⟶ 11,556:
Now I just got figure out how to win...
You can run this online [http://phix.x10.mx/p2js/2048.htm here].
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">-- demo\rosetta\2048.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 11,473 ⟶ 11,823:
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=={{header|PHP}}==
Works from PHP5 and upwards in CLI mode.
<syntaxhighlight lang="php">
<lang PHP>
<?php
 
Line 11,705 ⟶ 12,055:
 
}
</syntaxhighlight>
</lang>
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/simul.l")
 
(symbols 'simul 'pico)
Line 11,842 ⟶ 12,192:
(T (fish '((This) (= 512 (: N))) *G)
(println 'Maximum) ) )
(bye)</langsyntaxhighlight>
 
=={{header|Pony}}==
{{works with|ponyc|0.10.0}}
<langsyntaxhighlight lang="pony">
use "term"
use "random"
Line 12,113 ⟶ 12,463:
 
input(consume notify)
</syntaxhighlight>
</lang>
 
=={{header|Prolog}}==
Works with swi-prolog, any version.
<langsyntaxhighlight Prologlang="prolog">/* -------------------------------------------------------------
Entry point, just create a blank grid and enter a 'game loop'
-------------------------------------------------------------*/
Line 12,275 ⟶ 12,625:
dbl(' ', ' ').
dbl(2,4). dbl(4,8). dbl(8,16). dbl(16,32). dbl(32,64). dbl(64,128). dbl(128,256). dbl(256,512). dbl(512,1028). dbl(1028,2048).
</syntaxhighlight>
</lang>
{{out}}
<pre>?- play_2048.
Line 12,295 ⟶ 12,645:
=={{header|Python}}==
===Python: Original, with output===
<langsyntaxhighlight lang="python">#!/usr/bin/env python3
 
import curses
Line 12,496 ⟶ 12,846:
 
curses.wrapper(main)
</syntaxhighlight>
</lang>
 
===Python: using tkinter===
<langsyntaxhighlight lang="python">#!/usr/bin/env python3
 
''' Python 3.6.5 code using Tkinter graphical user interface.
Line 12,793 ⟶ 13,143:
root.bind_all('<Key>', g.key)
root.mainloop()
</syntaxhighlight>
</lang>
 
=={{header|QB64}}==
<syntaxhighlight lang="qb64">
<lang QB64>
_DEFINE A-Z AS _INTEGER64
DIM SHARED Grid(0 TO 5, 0 TO 5) AS INTEGER
Line 13,084 ⟶ 13,434:
COLOR dc&, bg&
END SUB
</syntaxhighlight>
</lang>
 
=={{header|R}}==
orginal R package : https://github.com/ThinkRstat/r2048
<syntaxhighlight lang="r">
<lang R>
GD <- function(vec) {
c(vec[vec != 0], vec[vec == 0])
Line 13,252 ⟶ 13,602:
}
 
</syntaxhighlight>
</lang>
 
=={{header|Racket}}==
Line 13,258 ⟶ 13,608:
Play the RacketScript fork online here: http://rapture.twistedplane.com:8080/#example/2048-game
 
<syntaxhighlight lang="racket">
<lang Racket>
;; LICENSE: See License file LICENSE (MIT license)
;;
Line 14,063 ⟶ 14,413:
 
(start)
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 14,069 ⟶ 14,419:
Uses termios to set the terminal options, so only compatible with POSIX terminals. This version does not include a specific "win" or "lose" condition. (though it would be trivial to add them.) You can continue to play this even after getting a 2048 tile; and if there is no valid move you can make, you can't do anything but quit.
{{works with|Rakudo|2018.05}}
<syntaxhighlight lang="raku" perl6line>use Term::termios;
 
constant $saved = Term::termios.new(fd => 1).getattr;
Line 14,183 ⟶ 14,533:
move %dir{$key} if so %dir{$key};
last if $key eq 'q'; # (q)uit
}</langsyntaxhighlight>
Sample output:
<pre>
Line 14,208 ⟶ 14,558:
{{works with|Red|0.6.4}}
 
<langsyntaxhighlight Redlang="red">Red [Needs: 'View]
 
random/seed now
Line 14,296 ⟶ 14,646:
display
view lay
</syntaxhighlight>
</lang>
 
{{out}}
Line 14,315 ⟶ 14,665:
::* &nbsp; displays a message if a winning move was entered.
::* &nbsp; displays the game board as a grid &nbsp; (with boxes).
<langsyntaxhighlight lang="rexx">/*REXX program lets a user play the 2048 game on an NxN grid (default is 4x4 grid).*/
parse arg N win seed . /*obtain optional arguments from the CL*/
if N=='' | N=="," then N= 4 /*Not specified? Then use the default.*/
Line 14,404 ⟶ 14,754:
do s=r to sTo by #; @.s.c= @(s + #, c) /*slide ↑ or ↓ */
end /*s*/; @.sTo.c= b /*handle the last one.*/
end /*r*/; return</langsyntaxhighlight>
Programming note: &nbsp; with a little more program complexity, &nbsp; the &nbsp; '''moveLR''' &nbsp; and &nbsp; '''moveUD''' &nbsp; subroutines could've
<br>been combined, &nbsp; as well as the &nbsp; '''packLR''' &nbsp; and &nbsp; '''packUD''' &nbsp; subroutines.
Line 14,573 ⟶ 14,923:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : 2048 Game
 
Line 15,010 ⟶ 15,360:
on '2048' setStylesheet(C_BUTTON2048STYLE)
off
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
inspired by the Raku version
<langsyntaxhighlight lang="ruby">
#!/usr/bin/ruby
 
Line 15,213 ⟶ 15,563:
end
end
</syntaxhighlight>
</lang>
 
=={{header|Rust}}==
Line 15,219 ⟶ 15,569:
A simple implementation in rust. The user has to input an endline since i did not find a way to read a key press
{{libheader|rand}}
<langsyntaxhighlight lang="rust">
use std::io::{self,BufRead};
extern crate rand;
Line 15,404 ⟶ 15,754:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">import java.awt.event.{KeyAdapter, KeyEvent, MouseAdapter, MouseEvent}
import java.awt.{BorderLayout, Color, Dimension, Font, Graphics2D, Graphics, RenderingHints}
import java.util.Random
Line 15,599 ⟶ 15,949:
}
 
}</langsyntaxhighlight>
 
=={{header|Seed7}}==
Line 15,611 ⟶ 15,961:
STD_CONSOLE works also always the same, independent from the operating system or terminal/console.
 
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "console.s7i";
include "keybd.s7i";
Line 15,800 ⟶ 16,150:
until moveOkay;
until quit;
end func;</langsyntaxhighlight>
 
=={{header|Tcl}}==
===Text mode===
<langsyntaxhighlight lang="tcl">
# A minimal implementation of the game 2048 in Tcl.
# For a maintained version with expanded functionality see
Line 16,081 ⟶ 16,431:
 
main
</syntaxhighlight>
</lang>
 
===Tk===
Line 16,088 ⟶ 16,438:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<langsyntaxhighlight lang="vbnet">Friend Class Tile
Public Sub New()
Me.Value = 0
Line 16,327 ⟶ 16,677:
End Sub
End Module
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 16,352 ⟶ 16,702:
{{libheader|Wren-fmt}}
{{libheader|Wren-str}}
<langsyntaxhighlight ecmascriptlang="wren">import "./dynamic" for Enum, Struct
import "random" for Random
import "./ioutil" for Input
import "./fmt" for Fmt
import "./str" for Str
 
var MoveDirection = Enum.create("MoveDirection", ["up", "down", "left", "right"])
Line 16,564 ⟶ 16,914:
}
 
runGame.call()</langsyntaxhighlight>
 
{{out}}
Line 16,587 ⟶ 16,937:
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
int Box(16), Moved;
 
Line 16,647 ⟶ 16,997:
until Moved;
];
]</langsyntaxhighlight>
408

edits