2048: Difference between revisions

4,214 bytes added ,  6 days ago
→‎{{header|Wren}}: Removed redundant initializeBoard method.
No edit summary
(→‎{{header|Wren}}: Removed redundant initializeBoard method.)
 
(9 intermediate revisions by 4 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 is spawned at the end of each turn at a randomly chosen empty square   (if there is one).
:*   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 8,137:
 
=={{header|FutureBasic}}==
 
<syntaxhighlight lang="futurebasic">
 
begin enum 123
_lf
Line 8,153 ⟶ 8,151:
 
void local fn initialize
subclass window 1, @"2048",(0,0,438,440438)
fn WindowSetBackgroundColor( 1, fn ColorBlack )
color(0) = fn ColorDarkGray
color(1) = fn ColorGray
color(2) = fn ColorLightGray
color(3) = fn ColorBrownColorBlue
color(4) = fn ColorBlueColorBrown
color(5) = fn ColorCyan
color(6) = fn ColorGreen
Line 8,225 ⟶ 8,223:
short a, b, c, t, moved = 0
// SHIFT
for a = st to st + rd * 3 step rd
// SHIFT
t = a
for b = a to a + cd * 3 step cd
Line 8,234 ⟶ 8,232:
end if
next
// MERGE
next
// MERGE
for a = st to st + rd * 3 step rd
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 ++
Line 8,252 ⟶ 8,247:
next
next
if moved == 0 then exit fn
fn drawBoard
if moved == 0 then exit fn
// GROW
Line 8,304 ⟶ 8,300:
handleevents
</syntaxhighlight>
[[File:FutureBasic 2048.png]]
{{out}}
[[File:2048 Game Window.png]]
 
=={{header|Go}}==
Line 9,330 ⟶ 9,325:
}
</syntaxhighlight>
 
=={{header|jq}}==
'''Works with jq, the C implementation of jq'''
 
'''Works with gojq, the Go implementation of jq'''
 
Except for trivial changes to one or two lines in the "play" function, the following
implementation is generic with respect to the number of rows and
columns. The target value can also be specified when calling `play`.
 
As of this writing, neither the C nor Go implementations of jq include
a built-in PRN generator and so in the following the MRG32k3a module
available at [[:Category:jq/MRG32k3a.jq|MRG32k3a.jq]] is used.
<syntaxhighlight lang="jq">
include "MRG32k3a" {search: "."}; # see comment above
 
### Generic functions
 
def lpad($len): tostring | ($len - length) as $l | (" " * $l) + .;
 
# Create an m x n matrix with initial values specified by .
def matrix($m; $n):
if $m == 0 then []
else . as $init
| if $m == 1 then [range(0;$n) | $init]
elif $m > 0 then
matrix(1; $n) as $row
| [range(0; $m) | $row ]
else error("matrix\($m);\($n)) invalid")
end
end;
 
 
### The 2048 Game
# Left-squish the input array in accordance with the game requirements for a single row
def squish:
def squish($n):
def s:
if length == 0 then [range(0;$n)|null]
elif .[0] == null then .[1:] | s
elif length == 1 then . + [range(0; $n - 1)|null]
elif .[0] == .[1] then [.[0] + .[1]] + (.[2:]|squish($n-1))
else .[0:1] + (.[1:]|squish($n-1))
end;
s;
squish(length);
 
# Input: a matrix of rows
def squish_left:
[.[] | squish];
 
def squish_right:
[.[] | reverse | squish | reverse];
 
def squish_up:
transpose
| [.[] | squish]
| transpose;
 
def squish_down:
transpose
| [.[] | reverse | squish | reverse]
| transpose;
 
# Gather the [i,j] co-ordinates of all the null values in the input matrix
def gather:
if length == 0 then error end
| (.[0] | length) as $cols
| [range(0;length) as $i
| range(0; $cols) as $j
| select(.[$i][$j] == null) | [$i,$j]]
| if length == 0 then error end ;
 
# Input: {matrix}
# Add a random 2 or 4 if possible, else error
# Output: includes .prng for the PRN generator
def add_random:
(.matrix | gather) as $gather
| ($gather | length) as $n
| if $n == 0 then error end
| if .prng == null then .prng = seed(now | tostring | sub("^.*[.]";"") | tonumber) end
| .prng |= nextFloat
| $gather[.prng.nextFloat * $n | trunc] as [$i,$j]
| .prng |= nextFloat
| (if (.prng.nextFloat) < 0.1 then 4 else 2 end) as $exmachina
| .matrix[$i][$j] = $exmachina ;
 
def prompt: "[ijkl] or [wasd] or q to quit or n to restart:";
 
def direction:
{"i": "up", "j": "left", "k": "down", "l": "right",
"w": "up", "a": "left", "s": "down", "d": "right",
"q": "quit",
"n": "restart"
};
 
# Recognize $goal as the goal
def play($goal):
 
# Pretty print
def pp:
.matrix[] | map(. // "." | lpad(4)) | join(" ");
 
def won:
any(.matrix[][]; . == $goal);
 
def lost:
.matrix
| (squish_left == .) and (squish_right == .) and
(squish_up == .) and (squish_down == .);
 
def round:
pp,
if lost then "Sorry! Better luck next time.", play($goal)
else prompt,
( (try input catch halt) as $in
| .matrix as $matrix # for checking if a move is legal
| .emit = null
| direction[$in | ascii_downcase] as $direction
| if $direction == "up" then .matrix |= squish_up
elif $direction == "down" then .matrix |= squish_down
elif $direction == "left" then .matrix |= squish_left
elif $direction == "right" then .matrix |= squish_right
elif $direction == "quit" then .emit = "bye"
elif $direction == "restart" then .emit = "restart"
else .emit = "unknown direction \($direction) ... please try again."
end
| if .emit == "bye" then .emit, halt
elif .emit == "restart" then "Restarting...", play($goal)
elif .emit != null then .emit, round
elif .matrix == $matrix then "Disallowed direction! Please try again.", round
elif won then pp, "Congratulations!", play($goal)
else add_random | round
end)
end;
 
{ matrix: (null | matrix(4;4))}
| .matrix[2] = [null,2,2,2]
| round;
 
play(2048)
</syntaxhighlight>
Invocation: jq -nRrf 2048.jq
{{output}}
<pre>
. . . .
. . . .
. 2 2 2
. . . .
[ijkl] or [wasd] or q to quit or n to restart:
l
2 . . .
. . . .
. . 2 4
. . . .
[ijkl] or [wasd] or q to quit or n to restart:
 
...etc...
</pre>
 
 
=={{header|Julia}}==
Line 16,707 ⟶ 16,862:
{{libheader|Wren-fmt}}
{{libheader|Wren-str}}
<syntaxhighlight lang="ecmascriptwren">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,729 ⟶ 16,884:
}
_rand = Random.new()
initializeBoard()
}
 
initializeBoard() {
for (y in 0..3) {
for (x in 0..3) _board[x][y] = Tile.new(0, false)
}
}
 
9,490

edits