Last active
June 22, 2019 16:30
-
-
Save errorseven/ad50650d05a5fb2bd477312ffc58976c to your computer and use it in GitHub Desktop.
2048 Console Edition Coded in AutoHotkey
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* ____ ___ _ _ ___ | |
|___ \ / _ \ | || | ( _ ) | |
__) | | | | | | || |_ / _ \ | |
/ __/ | |_| | |__ _| | (_) | | |
|_____| \___/ |_| \___/ | |
Console Edition! | |
Coded by errorseven @ 5/28 | |
2048 is played on a gray 4×4 grid, with numbered tiles that slide smoothly when | |
a player moves them using the four arrow keys. Every turn, a new tile will | |
randomly appear in an empty spot on the board with a 2 or 4, or small chance | |
current value present on the board. Tiles slide as far as possible in the chosen | |
direction until they are stopped by either another tile or the edge of the grid. | |
If two tiles of the same number collide while moving, they will merge into a tile | |
with the total value of the two tiles that collided. The resulting tile cannot | |
merge with another tile again in the same move. The game ends in a win if you | |
create a tile worth 2048 or a loss if you can no longer perform any moves. | |
Use the Arrow Keys to move the Tiles. | |
*/ | |
DllCall("AllocConsole") | |
hConsole:=DllCall("GetConsoleWindow","UPtr") | |
Stdout:=FileOpen(DllCall("GetStdHandle", "int", -11, "ptr"), "h `n") | |
Stdin:=FileOpen(DllCall("GetStdHandle", "int", -10, "ptr"), "h `n") | |
e:=SetConsoleOutputCP(65001) | |
board := [["", "", "", ""] | |
, ["", "", "", ""] | |
, ["", "", "", ""] | |
, ["", "", "", ""]] | |
board := addRandom(board, 2) | |
Loop { ; Main Game Loop | |
Print(drawBoard(board)) | |
loop { | |
input, key, L1, {Left}{Right}{Up}{Down} | |
e := errorlevel | |
if (e ~= "EndKey") { | |
board := updateBoard(board, StrSplit(e, ":").2) | |
Break | |
} | |
} | |
if (contains(board, 2048)) { | |
RunWait %comspec% /c "cls" | |
Print(drawBoard(board)) | |
MsgBox % "You Won" | |
exitApp | |
} | |
if (!movesRemaining(board)) { | |
MsgBox % "Game Over" | |
exitApp | |
} | |
if (getValues(board) != 16) | |
board := addRandom(board) | |
RunWait %comspec% /c "cls" | |
} | |
Print(string="", skip=0){ | |
global Stdout | |
global Stdin | |
if (!StrLen(string)) | |
return 1 | |
e:=DllCall("WriteConsole" . ((A_IsUnicode) ? "W" : "A") | |
, "UPtr", Stdout.__Handle | |
, "Str", string | |
, "UInt", strlen(string) | |
, "UInt*", Written | |
, "uint", 0) | |
if (!e) or (ErrorLevel) | |
return 0 ;Failure | |
Stdout.Read(0) | |
if (skip) | |
return 0 | |
return | |
} | |
SetConsoleOutputCP(codepage) { | |
e:=DllCall("SetConsoleOutputCP","UInt",codepage) | |
if (!e) or (ErrorLevel) | |
return 0 ;Failure | |
return 1 | |
} | |
addRandom(board, x:="1") { | |
loop % x { | |
random, o, 0, 9 | |
values := getValues(board) | |
if (values.count() < 1) | |
p := o > 8 ? 4 : 2 | |
else { | |
if (o > 7) { | |
random, n, 1, values.count() | |
p := values[n] | |
} | |
else | |
p := o > 3 ? 4 : 2 | |
} | |
random, col, 1, 4 | |
random, row, 1, 4 | |
while (board[col][row]) { | |
if (A_Index > 1000) { | |
MsgBox % "Game Over" | |
ExitApp | |
} | |
random, col, 1, 4 | |
random, row, 1, 4 | |
} | |
board[col][row] := p | |
} | |
return board | |
} | |
movesRemaining(board) { | |
if (Contains(board, "")) | |
return 1 | |
loop % 4 { | |
row := A_Index | |
loop % 3 { | |
col := A_Index | |
if (board[row][col] == board[row][col+1]) | |
return 1 | |
} | |
} | |
loop % 4 { | |
col := A_Index | |
loop % 3 { | |
row := A_Index | |
if (board[row][col] == board[row+1][col]) | |
return 1 | |
} | |
} | |
return 0 | |
} | |
drawBoard(board) { | |
for k, arr in board { | |
r := "" | |
for e, v in arr | |
r .= Format("{:-5}", v == "" ? "*" : v) | |
results .= trim(r, " ") "`n" | |
} | |
return Results | |
} | |
getValues(board) { | |
values := [] | |
for e, obj in board | |
for k, v in obj | |
if (v >= 2) | |
values.push(v) | |
return values | |
} | |
updateBoard(board, dir) { | |
if (dir == "Left") { | |
loop % 4 { | |
col := A_index, i := 1 | |
loop % 4 { | |
if (board[col][i] == "") | |
board[col].RemoveAt(i--), board[col].Push("") | |
i++ | |
} | |
loop % 4 { | |
row := A_index | |
if (board[col][row] == board[col][row+1] and board[col][row] != "") | |
board[col][row] += board[col][row+1], board[col].RemoveAt(row+1), board[col].Push("") | |
} | |
} | |
} | |
if (dir == "Right") { | |
loop % 4 { | |
col := A_index, i := 4 | |
loop % 4 { | |
If (board[col][i] == "") | |
board[col].RemoveAt(i++), board[col].InsertAt(1, "") | |
i-- | |
} | |
loop % 4 { | |
row := 5 - A_index | |
if (board[col][row] == board[col][row-1] and board[col][row] != "") | |
board[col][row] += board[col][row-1], board[col].RemoveAt(row-1), board[col].InsertAt(1, "") | |
} | |
} | |
} | |
if (dir == "Up") { | |
loop % 4 { | |
row := A_index | |
tempArr := [] | |
loop % 4 { ; Create Temp Array | |
col := A_index | |
tempArr.push(board[col][row]) | |
} | |
i := 1 | |
loop % 4 { | |
if (tempArr[i] == "") | |
tempArr.RemoveAt(i--), tempArr.Push("") | |
i++ | |
} | |
loop % 4 { | |
r := A_index | |
if (tempArr[r] == tempArr[r+1] and tempArr[r] != "") | |
tempArr[r] += tempArr[r+1], tempArr.RemoveAt(r+1), tempArr.Push("") | |
} | |
loop % 4 { ; Update Board from Temp Array | |
col := A_Index | |
board[col][row] := tempArr[col] | |
} | |
} | |
} | |
if (dir == "Down") { | |
loop % 4 { | |
row := A_index | |
tempArr := [] | |
loop % 4 { ; Create Temp Array | |
col := A_index | |
tempArr.push(board[col][row]) | |
} | |
i := 4 | |
loop % 4 { | |
If (tempArr[i] == "") | |
tempArr.RemoveAt(i++), tempArr.InsertAt(1, "") | |
i-- | |
} | |
loop % 4 { | |
r := 5 - A_index | |
if (tempArr[r] == tempArr[r-1] and tempArr[r] != "") | |
tempArr[r] += tempArr[r-1], tempArr.RemoveAt(r-1), tempArr.InsertAt(1, "") | |
} | |
loop % 4 { ; Update Board from Temp Array | |
col := A_Index | |
board[col][row] := tempArr[col] | |
} | |
} | |
} | |
return board | |
} | |
Contains(arr, x, y:="") { | |
/* | |
Returns a Str index (True) or False | |
Usage: | |
obj := [1, 3, 2, [5, 4]] | |
contains(obj, 4) ; --> [4][2] | |
*/ | |
For k, v in arr { | |
if (v == x) | |
return y "[" k "]" | |
if (IsObject(v) && v != r) | |
z := contains(arr[k], x, y "[" k "]" ) | |
if (z) | |
return z | |
} | |
return 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment