anchor.diff:    [#card{value=?tarabish_ACE, suit=1}|Rest] = Sorted,
     [#card{value=?tarabish_KING, suit=1}|_Rest2] = Rest.
   
  +sort_runs_test_() ->
  +  M  = fun (Value) -> #card{value=Value, suit=1} end,
  +  MT = fun (Value) -> #card{value=Value, suit=2} end,
  +  ML = fun (VList) -> lists:map(M, VList) end,
  +  MLT= fun (VList) -> lists:map(MT, VList) end,
  +
  +  [
  +    ?_assertEqual([ML([10, 9, 8, 7]), ML([9, 8, 7, 6]), ML([14, 13, 12])],
  +      sort_runs([ML([14, 13, 12]), ML([9, 8, 7, 6]), ML([10, 9, 8, 7])], 2)),
  +    ?_assertEqual([MLT([10, 9, 8, 7]), ML([10, 9, 8, 7]), ML([14, 13, 12])],
  +      sort_runs([ML([14, 13, 12]), ML([10, 9, 8, 7]), MLT([10, 9, 8, 7])], 2))
  +  ].
  +
  +new_run_record_test_() ->
  +  C = fun(V, S) -> #card{value=V, suit=S} end,
  +
  +  NoBest = #best_run{type=none, high=0, trump=false},
  +
  +  Twenty = #best_run{type=twenty, high=14, trump=false},
  +  TwentyCards = [C(14, 0), C(13, 0), C(12,0),
  +                 C(14, 1), C(13, 1), C(12,1),
  +                 C(14, 2), C(13, 2), C(12,2)],
  +
  +  Fifty = #best_run{type=fifty, high=13, trump=false},
  +  FiftyCards = [C(13, 1), C(12, 1), C(11, 1), C(10,1),
  +                C(14, 2), C(13, 2), C(12, 2)],
  +
  +  FiftyT = Fifty#best_run{trump=true},
  +  [
  +    ?_assertEqual(#run_record{best_run=NoBest, score=0, to_show=[]},
  +      new_run_record([C(14, 0), C(14, 1), C(14, 2), C(14, 3),
  +                      C(12, 0), C(12, 1), C(12, 2), C(12, 3),
  +                      C(10, 0), C(10, 1), C(10, 2), C(10, 3)], 0)),
  +    ?_assertEqual(#run_record{best_run=Twenty, score=60, to_show=TwentyCards},
  +      new_run_record([C(14, 0), C(14, 1), C(14, 2), C(14, 3),
  +                      C(13, 0), C(13, 1), C(13, 2), C(12, 3),
  +                      C(12, 0), C(12, 1), C(12, 2), C(10, 3)], 3)),
  +    % The twenty is trump, but the fifty still wins:
  +    ?_assertEqual(#run_record{best_run=Fifty, score=70, to_show=FiftyCards},
  +      new_run_record([C(14, 0), C(08, 0), C(11, 1), C(13, 2),
  +                      C(12, 0), C(13, 1), C(10, 1), C(12, 2),
  +                      C(10, 0), C(12, 1), C(14, 2), C(10, 3)], 2)),
  +    ?_assertEqual(#run_record{best_run=FiftyT, score=70, to_show=FiftyCards},
  +      new_run_record([C(14, 0), C(08, 0), C(11, 1), C(13, 2),
  +                      C(12, 0), C(13, 1), C(10, 1), C(12, 2),
  +                      C(10, 0), C(12, 1), C(14, 2), C(10, 3)], 1))
  +  ].
  +
   split_runs_test_() ->
     M = fun (Value) -> #card{value=Value} end,
     ML = fun (VList) -> lists:map(M, VList) end,
  
positive.code: split_runs([Card|Rest]) ->
      split_runs(Rest, [Card], []).
  
  % The last run, if it was a fifty, would be counted already
  % Count the last run, it's the best twenty:
  score_suit(_ExpectedValue, FirstValue, [], 3, none, _High, Score) ->
    make_best_run(twenty, FirstValue, Score + 20);
  
  % Count the last twenty, but it's not the bext:
  score_suit(_ExpectedValue, _FirstValue, [], 3, Other, High, Score) ->
    make_best_run(Other, High, Score + 20);
  
  % No last run, return bests:
  score_suit(_ExpectedValue, _FirstValue, [], _NoCount, Run, High, Score) ->
    make_best_run(Run, High, Score);
  
  % Start of new run:
  score_suit(_ExpectedValue, _FirstValue, [NewCard|Rest], 0, Run, High, Score) ->
    score_suit(NewCard#card.value - 1, NewCard#card.value, Rest, 1, Run, High, Score);
  
  % New fifty, must be smaller (due to high-low sort):
  score_suit(ExpectedValue, _FirstValue,
             [#card{value=ExpectedValue}|Rest], 3, fifty, High, Score) ->
    score_suit(none, none, Rest, 0, fifty, High, Score + 50);
  
  % First fifty, doesn't matter if there's twenties:
  score_suit(ExpectedValue, FirstValue,
             [#card{value=ExpectedValue}|Rest],
             3, _NotFifty, _High, Score) ->
      score_suit(none, none, Rest, 0, fifty, FirstValue, Score + 50);
  
  % First twenty, and it's the best:
  score_suit(_ExpectedValue, FirstValue, Cards, 3, none, _High, Score) ->
    score_suit(none, none, Cards, 0, twenty, FirstValue, Score + 20);
  
  % Higher twenty or fifty, but count the score:
  score_suit(_ExpectedValue, _FirstValue, Cards, 3, Run, High, Score) ->
    score_suit(none, none, Cards, 0, Run, High, Score + 20);
  
  % Building a run:
  score_suit(ExpectedValue, FirstValue,
             [#card{value=ExpectedValue}|Rest], Count,
             Run, High, Score) ->
      score_suit(ExpectedValue - 1, FirstValue, Rest, Count + 1, Run, High, Score);
  
  % No run, start again, doesn't matter the count:
  score_suit(_ExpectedValue, _FirstValue, Cards, _Count, Run, High, Score) ->
    score_suit(none, none, Cards, 0, Run, High, Score).
  
  % Must be all the same suit:
  score_suit(Cards) ->
    score_suit(none, none, Cards, 0, none, 0, 0).
  
  % fifty better than other:
  fold_runs(ThisSuit, #best_run{type=fifty, high=High, score=Score1},
            #best_run{type=Type, score=Score} = Best, Trump) when Type =/= fifty ->
    Best#best_run{type=fifty, score=Score + Score1, high=High,
      trump=(ThisSuit==Trump)};
  
  % twenty when no other run:
  fold_runs(ThisSuit, #best_run{type=twenty, high=High, score=Score1},
            #best_run{type=none, score=Score} = Best, Trump) ->
    Best#best_run{type=twenty, score=Score + Score1, high=High,
      trump=(ThisSuit==Trump)};
  
  % Same high card, same type, but this is trump:
  fold_runs(Trump, #best_run{type=Type, high=High, score=Score1},
            #best_run{type=Type, high=High, score=Score} = Best, Trump) ->
    Best#best_run{score=Score + Score1, trump=true};
  
  % Better high card, same type:
  fold_runs(_AnySuit, #best_run{type=Type, high=High, score=Score1},
            #best_run{type=Type, high=High2, score=Score} = Best, _Trump) when
            High > High2 ->
    Best#best_run{score=Score + Score1, high=High};
  
  % Worse run:
  fold_runs(_AnySuit, #best_run{score=Score1},
            #best_run{score=Score} = Best, _Trump) ->
    Best#best_run{score=Score + Score1}.
  
  %%
  %% Tests
  %%
  
negative.code:   Runs = lists:map(fun (Hand) -> new_run_record(Hand, TrumpSuit) end, Hands),
    Runs.
  
  new_run_record(Cards, TrumpSuit) ->
    SortedCards = sort_cards_by_value(Cards),
    CardsBySuit = split_by_suit(SortedCards),
  
    SplitByRuns = lists:reverse(lists:foldl(fun lists:append/2, [],
      lists:map(fun split_runs/1, CardsBySuit))),
  
    SortBySize = sort_runs(SplitByRuns, TrumpSuit),
  
    CardsToShow = lists:flatten(SortBySize),
    Score = score_runs(SplitByRuns),
    BestRun = make_best(SortBySize, TrumpSuit),
    #run_record{best_run=BestRun, score=Score, to_show=CardsToShow}.
  
  % This sorts top to bottom by values to make run finding easier
  sort_cards_by_value2(#card{suit=Suit, value=V1},
  