Skip to content

Instantly share code, notes, and snippets.

@errorseven
Last active June 22, 2019 16:30
Show Gist options
  • Save errorseven/ad50650d05a5fb2bd477312ffc58976c to your computer and use it in GitHub Desktop.
Save errorseven/ad50650d05a5fb2bd477312ffc58976c to your computer and use it in GitHub Desktop.
2048 Console Edition Coded in AutoHotkey
/* ____ ___ _ _ ___
|___ \ / _ \ | || | ( _ )
__) | | | | | | || |_ / _ \
/ __/ | |_| | |__ _| | (_) |
|_____| \___/ |_| \___/
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