diff --git a/lib/tile.ex b/lib/tile.ex index 2497dcf..273bca5 100644 --- a/lib/tile.ex +++ b/lib/tile.ex @@ -48,28 +48,14 @@ defmodule Tile do |> Enum.reduce(true, fn(t,acc) -> acc && (t.sub == h.sub) && (t.num == h.num) end) end - def valid_3([x, y, z]) do - sheung([x, y, z]) or pung([x, y, z]) - end - - def same_sub_3([x, y, z]) do - x.sub == y.sub && - y.sub == z.sub - end - - def consec_3([x, y, z]) do - mag = [x.num, y.num, z.num] - |> Enum.sort - [min|_T] = mag - [0, 1, 2] == mag |> Enum.map(fn n -> n - min end) - end - def pung([x, y, z]) do same([x, y, z]) end - def sheung([x, y, z]) do - same_sub_3([x, y, z]) && consec_3([x, y, z]) + def sheung([_x, _y, _z] = inlist) do + same_sub_3(inlist) && + consec_3(inlist) && + Enum.reduce(inlist, true, fn (t, acc) -> acc && t.cat in [:Dot, :Bamboo, :Character] end) end def find_3(tiles) do @@ -94,6 +80,22 @@ defmodule Tile do all_tiles end + defp same_sub_3([x, y, z]) do + x.sub == y.sub && + y.sub == z.sub + end + + defp consec_3([x, y, z]) do + mag = [x.num, y.num, z.num] + |> Enum.sort + [min|_T] = mag + [0, 1, 2] == mag |> Enum.map(fn n -> n - min end) + end + + defp valid_3([x, y, z]) do + sheung([x, y, z]) or pung([x, y, z]) + end + defp all_bamboos do get_tiles(:Bamboo, :Bamboo, 9) end diff --git a/test/tile_test.exs b/test/tile_test.exs new file mode 100644 index 0000000..944fa82 --- /dev/null +++ b/test/tile_test.exs @@ -0,0 +1,152 @@ +defmodule TileTest do + use ExUnit.Case + doctest Tile + + def pingwu do + [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 4}, + %Tile{cat: :Dot, sub: :Dot, num: 5}, + %Tile{cat: :Dot, sub: :Dot, num: 6}, + %Tile{cat: :Bamboo, sub: :Bamboo, num: 1}, + %Tile{cat: :Bamboo, sub: :Bamboo, num: 1} + ] + end + + def gg() do + [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 4}, + %Tile{cat: :Dot, sub: :Dot, num: 5}, + %Tile{cat: :Dot, sub: :Dot, num: 6}, + %Tile{cat: :Dot, sub: :Dot, num: 7}, + %Tile{cat: :Dot, sub: :Dot, num: 7} + ] + end + + test "Same tiles" do + s = [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + ] + assert Tile.same(s) + + s = [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + ] + assert !Tile.same(s) + + s = [ %Tile{cat: :Bamboo, sub: :Bamboo, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Flower, sub: :Flower, num: 1}, + ] + assert !Tile.same(s) + end + + test "Pung" do + s = [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + ] + assert Tile.pung(s) + end + + test "Not Pung" do + s = [ %Tile{cat: :Bamboo, sub: :Bamboo, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Flower, sub: :Flower, num: 1}, + ] + assert !Tile.pung(s) + end + + test "Sheung" do + s = [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + ] + assert Tile.sheung(s) + end + + test "Sheung invalid" do + s = [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 1}, + ] + assert !Tile.sheung(s) + end + + test "Sheung Fans" do + s = [ %Tile{cat: :Fan, sub: :Wind, num: 1}, + %Tile{cat: :Fan, sub: :Wind, num: 2}, + %Tile{cat: :Fan, sub: :Wind, num: 3}, + ] + assert !Tile.sheung(s) + end + + test "Sheung Flowers" do + s = [ %Tile{cat: :Flower, sub: :Flower, num: 1}, + %Tile{cat: :Flower, sub: :Flower, num: 2}, + %Tile{cat: :Flower, sub: :Flower, num: 3}, + ] + assert !Tile.sheung(s) + end + + test "all tiles no flowers" do + assert 136 == Tile.all |> Enum.count + end + + test "all tiles" do + assert 144 == Tile.all(true) |> Enum.count + end + + test "find 3 1" do + s = [ %Tile{cat: :Dot, sub: :Dot, num: 1}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 2}, + %Tile{cat: :Dot, sub: :Dot, num: 3}, + %Tile{cat: :Dot, sub: :Dot, num: 4}, + %Tile{cat: :Dot, sub: :Dot, num: 4}, + %Tile{cat: :Dot, sub: :Dot, num: 4}, + ] + + expected = [[%Tile{cat: :Dot, num: 1, sub: :Dot}, %Tile{cat: :Dot, num: 2, sub: :Dot}, %Tile{cat: :Dot, num: 3, sub: :Dot}], + [%Tile{cat: :Dot, num: 2, sub: :Dot}, %Tile{cat: :Dot, num: 2, sub: :Dot}, %Tile{cat: :Dot, num: 2, sub: :Dot}], + [%Tile{cat: :Dot, num: 2, sub: :Dot}, %Tile{cat: :Dot, num: 3, sub: :Dot}, %Tile{cat: :Dot, num: 4, sub: :Dot}], + [%Tile{cat: :Dot, num: 4, sub: :Dot}, %Tile{cat: :Dot, num: 4, sub: :Dot}, %Tile{cat: :Dot, num: 4, sub: :Dot}]] + assert expected == Tile.find_3(s) + end + + test "find 3 2" do + s = [ %Tile{cat: :Wind, sub: :Wind, num: 1}, + %Tile{cat: :Wind, sub: :Wind, num: 2}, + %Tile{cat: :Wind, sub: :Wind, num: 3}, + %Tile{cat: :Wind, sub: :Wind, num: 2}, + %Tile{cat: :Wind, sub: :Wind, num: 2}, + %Tile{cat: :Wind, sub: :Wind, num: 3}, + %Tile{cat: :Wind, sub: :Wind, num: 4}, + %Tile{cat: :Wind, sub: :Wind, num: 4}, + %Tile{cat: :Wind, sub: :Wind, num: 4}, + ] + + expected = [[%Tile{cat: :Wind, num: 2, sub: :Wind}, %Tile{cat: :Wind, num: 2, sub: :Wind}, %Tile{cat: :Wind, num: 2, sub: :Wind}], + [%Tile{cat: :Wind, num: 4, sub: :Wind}, %Tile{cat: :Wind, num: 4, sub: :Wind}, %Tile{cat: :Wind, num: 4, sub: :Wind}]] + assert expected == Tile.find_3(s) + end +end