Skip to content

Instantly share code, notes, and snippets.

@ToJans
Last active August 29, 2015 13:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ToJans/9446300 to your computer and use it in GitHub Desktop.
Save ToJans/9446300 to your computer and use it in GitHub Desktop.
An implementation in Elixir for Threes (http://asherv.com/threes/). Started out of curiosity after seeing a tweet by GraemeF(https://twitter.com/GraemeF/status/442580143140134912)
defmodule Threes do
def right(board) do
board
|> Enum.map(&pack/1)
end
def left(board) do
board
|> Enum.map(&reverse_pack/1)
end
def down(board) do
board
|> pivot()
|> Enum.map(&pack/1)
|> pivot()
end
def up(board) do
board
|> pivot()
|> Enum.map(&reverse_pack/1)
|> pivot()
end
defp pack(x), do: pack(x,[])
defp reverse_pack(x), do: x |> Enum.reverse |> pack |> Enum.reverse
defp return_pack(acc=[_,_,_]), do: [get_nr | acc]
defp return_pack(acc=[_,_,_,_]), do: acc
defp pack([], acc), do: return_pack(acc)
defp pack([0 | xs], acc), do: pack(xs, acc ++ [0])
defp pack([a, 0| xs], acc), do: return_pack(acc ++ [a | xs])
defp pack([a, b| xs], acc) when rem(a+b, 3) == 0, do: return_pack(acc ++ [a+b | xs])
defp pack([x|xs],acc), do: pack(xs, acc ++ [x])
defp get_nr() do
x = :random.uniform(10)
if x > 2, do: 0, else: x
end
defp pivot(xs), do: pivot(xs,[[],[],[],[]])
defp pivot([],acc), do: acc |> Enum.map &Enum.reverse/1
defp pivot([[a,b,c,d]|xs],[as,bs,cs,ds]), do: pivot(xs,[[a|as],[b|bs],[c|cs],[d|ds]])
end
Code.load_file("threes.exs")
ExUnit.start
defmodule ThreesTest do
use ExUnit.Case, async: true
#doctest Threes
test "Move right" do
board = [[0, 0, 1, 2],
[2, 2, 2, 2],
[1, 2, 0, 0],
[2, 0, 1, 1]]
[a,b,c,d] = Threes.right(board)
assert [0, 0, 3] == tl(a)
assert [2, 2, 2, 2] == b
assert [3, 0, 0] == tl(c)
assert [2, 1, 1] == tl(d)
end
test "Move left" do
board = [[0, 0, 1, 2],
[2, 2, 2, 2],
[1, 2, 0, 0],
[2, 0, 1, 1]]
[a,b,c,d] = Threes.left(board)
assert [0, 0, 3] == Enum.take(a, 3)
assert [2, 2, 2, 2] == b
assert [3, 0, 0] == Enum.take(c, 3)
assert [2, 1, 1] == Enum.take(d, 3)
end
test "Move up" do
board = [[0, 0, 1, 2],
[2, 2, 2, 2],
[1, 2, 0, 2],
[2, 0, 1, 2]]
[a,b,c,d] = Threes.up(board)
[_,_,_,l] = d
assert [0, 2, 1, 2] == a
assert [2, 2, 2, 2] == b
assert [3, 0, 1, 2] == c
assert 2 == l
end
test "Move down" do
board = [[0, 0, 1, 2],
[2, 2, 2, 2],
[1, 2, 0, 2],
[2, 0, 1, 2]]
[a,b,c,d] = Threes.down(board)
[_,_,_,l] = a
assert l == 2
assert [0, 0, 3, 2] == b
assert [3, 2, 0, 2] == c
assert [2, 2, 1, 2] == d
end
end
@Sch3lp
Copy link

Sch3lp commented Mar 9, 2014

'sup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment