deck.erl 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. %% Author: Serge Polkovnikov <serge.polkovnikov@gmail.com>
  2. %% Created: Oct 8, 2012
  3. %% Description: The library for manipulations with decks.
  4. -module(deck).
  5. %% Predefined types of deck:
  6. %% empty - No one element in the deck.
  7. %%
  8. %% okey - The deck consist of such types of element: {Color, Value} | false_okey.
  9. %% There are two instances of each element in the deck.
  10. %% Color = 1..4
  11. %% Value = 1..13
  12. %%
  13. %% Include files
  14. %%
  15. %%
  16. %% Exported Functions
  17. %%
  18. -export([
  19. init_deck/1,
  20. from_list/1,
  21. to_list/1,
  22. shuffle/1,
  23. pop/2,
  24. push/2,
  25. get/2,
  26. put/3,
  27. replace/3,
  28. size/1,
  29. del_first/2,
  30. member/2
  31. ]).
  32. %%
  33. %% API Functions
  34. %%
  35. %% @spec init_deck(Type) -> Deck
  36. %% @doc Creates a deck.
  37. %% @end
  38. init_deck(empty) ->
  39. [];
  40. init_deck(okey) ->
  41. [false_okey, false_okey | [{C, V} || C <- [1,2,3,4], V <- lists:seq(1,13), _ <- [1,2]]].
  42. %% @spec from_list(List) -> Deck
  43. %% @doc Creates a deck from the list of elements.
  44. %% @end
  45. from_list(List) ->
  46. List.
  47. %% @spec to_list(Deck) -> List
  48. %% @doc Convers the deck to a list of elements.
  49. %% @end
  50. to_list(Deck) ->
  51. Deck.
  52. %% @spec shuffle(Deck1) -> Deck2
  53. %% @doc Shuffles the deck.
  54. %% @end
  55. shuffle(Deck) when is_list(Deck) ->
  56. shuffle(Deck, deck:size(Deck), []).
  57. shuffle([], 0, Acc) -> Acc;
  58. shuffle(Deck, Size, Acc) ->
  59. Pos = crypto:rand_uniform(1, Size+1),
  60. {E, Deck1} = get(Pos, Deck),
  61. shuffle(Deck1, Size-1, [E |Acc]).
  62. %% @spec pop(Num, Deck1) -> {Deck2, Deck3}
  63. %% @doc Takes specified number of elements from top of the deck.
  64. %% @end
  65. pop(Num, Deck) when Num > 0, is_list(Deck) ->
  66. lists:split(Num, Deck).
  67. %% @spec push(Deck1, Deck2) -> Deck3.
  68. %% @doc Puts the first deck on the top of the second deck.
  69. %% @end
  70. push(Deck1, Deck2) when is_list(Deck1), is_list(Deck2) ->
  71. Deck1 ++ Deck2.
  72. %% @spec get(Pos, Deck1) -> {E, Deck2}
  73. %% @doc Draws an element at the position Pos of the deck.
  74. %% Position is counted from top of the deck.
  75. %% @end
  76. get(Pos, Deck) when Pos > 0, is_list(Deck) ->
  77. {Head, [E | Tail]} = lists:split(Pos - 1, Deck),
  78. {E, Head ++ Tail}.
  79. %% @spec put(E, Pos, Deck1) -> Deck2
  80. %% @doc Inserts the element to the position Pos of the deck.
  81. %% Position is counted from top of the deck.
  82. %% @end
  83. put(E, Pos, Deck) when Pos > 0, is_list(Deck) ->
  84. {Head, Tail} = lists:split(Pos - 1, Deck),
  85. Head ++ [E | Tail].
  86. %% @spec replace(E1, E2, Deck1) -> Deck2
  87. %% @doc Replaces all instances of the element E1 in the deck by the element E2.
  88. %% @end
  89. replace(E1, E2, Deck) ->
  90. [if E == E1 -> E2; true -> E end || E <- Deck].
  91. %% @spec size(Deck) -> Size
  92. %% @doc Returns a number of elements in the deck.
  93. %% @end
  94. size(Deck) when is_list(Deck) ->
  95. length(Deck).
  96. %% @spec del_first(E, Deck1) -> {ok, Deck2} | error
  97. %% @doc Deletes the element from the deck.
  98. %% @end
  99. del_first(E, Deck) ->
  100. case lists:member(E, Deck) of
  101. true ->
  102. {ok, lists:delete(E, Deck)};
  103. false ->
  104. error
  105. end.
  106. %% @spec member(E, Deck) -> boolean()
  107. %% @doc Checks is the element a memeber of the deck.
  108. %% @end
  109. member(E, Deck) ->
  110. lists:member(E, Deck).
  111. %%
  112. %% Local Functions
  113. %%