Skip to content

Instantly share code, notes, and snippets.

@Roboneet
Created January 25, 2019 19:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Roboneet/12bd2811aa0b4e0cd70b145c64c9cc8f to your computer and use it in GitHub Desktop.
Save Roboneet/12bd2811aa0b4e0cd70b145c64c9cc8f to your computer and use it in GitHub Desktop.
2048 for humans
# 2048 for humans
# ---------------
# controls:
# w: up
# a: left
# s: down
# d: right
# press enter
mutable struct Board{T,N} <: AbstractArray{T,N}
cells::Array{T,N}
dir
end
Board() = Board(4)
Board(n) = Board(zeros(Int, n, n), Val(:l))
dir(x) = Val(:l)
dir(b::Board) = b.dir
cells(b::Board) = b.cells
Base.size(b::Board) = size(b.cells)
Base.getindex(b::Board{T,N}, i...) where {T,N} =
Base.getindex(cells(b), inv(dir(b), size(b)[1], i...)...)
Base.setindex!(b::Board{T,N}, x, i...) where {T,N} =
Base.setindex!(cells(b), x, inv(dir(b), size(b)[1], i...)...)
Base.inv(dir, n, c::CartesianIndex{2}) = inv(dir, n, Tuple(c)...)
Base.inv(dir::Val{:l}, n, i, j) = tuple(i, j)
Base.inv(dir::Val{:r}, n, i, j) = tuple(i, n + 1 - j)
Base.inv(dir::Val{:u}, n, i, j) = tuple(j, i)
Base.inv(dir::Val{:d}, n, i, j) = tuple(n + 1 - j, i)
Base.display(b::Board) = display(cells(b))
function shift(arr::AbstractArray{T, 2}, default=zero(T)) where T
shifted = -1
r, c = size(arr)
@inbounds for i=1:r
k = 1
can_merge = true
@inbounds for j=1:c
if arr[i, j] == default
elseif k > 1 && arr[i, j] == arr[i, k-1] && can_merge
shifted = 1
arr[i, k-1] *= 2
arr[i, j] = default
can_merge = false
elseif j == k
k += 1
can_merge = true
else
shifted = 1
arr[i, k] = arr[i, j]
arr[i, j] = default
k += 1
can_merge = true
end
end
end
return shifted
end
function drop(arr::AbstractArray{T,2}) where {T}
s = findall(iszero, arr)
(length(s) == 0) && return -1
arr[Tuple(rand(s))...] = rand([2, 2, 4])
end
m = Dict("w"=> :u, "a"=>:l, "s"=>:d, "d"=>:r)
function input!(b::Board)
inp = () -> (println("w/a/s/d? ");readline())
d = inp();
while !haskey(m, d)
d = inp()
end
b.dir = Val(m[d])
end
function play()
b = Board()
v = drop(b)
while v != -1
display(b)
input!(b)
if shift(b) != -1
v = drop(b)
end
end
println("Game Over!")
end
play()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment