Skip to content

Instantly share code, notes, and snippets.

@Roboneet Roboneet/2048.jl
Created Jan 25, 2019

Embed
What would you like to do?
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
You can’t perform that action at this time.