|
|
@ -1,179 +1,25 @@ |
|
|
|
-module(util1). |
|
|
|
|
|
|
|
-compile(export_all). |
|
|
|
|
|
|
|
%% 在List中的每两个元素之间插入一个分隔符 |
|
|
|
implode(_S, []) -> |
|
|
|
[<<>>]; |
|
|
|
implode(S, L) when is_list(L) -> |
|
|
|
implode(S, L, []). |
|
|
|
implode(_S, [H], NList) -> |
|
|
|
lists:reverse([thing_to_list(H) | NList]); |
|
|
|
implode(S, [H | T], NList) -> |
|
|
|
L = [thing_to_list(H) | NList], |
|
|
|
implode(S, T, [S | L]). |
|
|
|
|
|
|
|
%%返回X在[Min, Max]区间内的值 |
|
|
|
minmax(X, Min, Max) -> |
|
|
|
min(max(X, Min), Max). |
|
|
|
|
|
|
|
%% 字符->列 |
|
|
|
explode(S, B) -> |
|
|
|
re:split(B, S, [{return, list}]). |
|
|
|
explode(S, B, int) -> |
|
|
|
[list_to_integer(Str) || Str <- explode(S, B), length(Str) > 0]. |
|
|
|
|
|
|
|
thing_to_list(X) when is_integer(X) -> integer_to_list(X); |
|
|
|
thing_to_list(X) when is_float(X) -> float_to_list(X); |
|
|
|
thing_to_list(X) when is_atom(X) -> atom_to_list(X); |
|
|
|
thing_to_list(X) when is_binary(X) -> binary_to_list(X); |
|
|
|
thing_to_list(X) when is_list(X) -> X. |
|
|
|
|
|
|
|
%% 日志记录函数 |
|
|
|
log(T, F, A, Mod, Line) -> |
|
|
|
{ok, Fl} = file:open("logs/error_log.txt", [write, append]), |
|
|
|
Format = list_to_binary("#" ++ T ++ " ~s[~w:~w] " ++ F ++ "\r\n~n"), |
|
|
|
{{Y, M, D}, {H, I, S}} = erlang:localtime(), |
|
|
|
Date = list_to_binary([integer_to_list(Y), "-", integer_to_list(M), "-", integer_to_list(D), " ", integer_to_list(H), ":", integer_to_list(I), ":", integer_to_list(S)]), |
|
|
|
file:close(Fl). |
|
|
|
|
|
|
|
%% 取得当前的unix时间戳 |
|
|
|
unixtime() -> |
|
|
|
{M, S, _} = game_timer:now(),%%os:timestamp() |
|
|
|
M * 1000000 + S. |
|
|
|
|
|
|
|
longunixtime() -> |
|
|
|
{M, S, Ms} = game_timer:now(), |
|
|
|
(M * 1000000000000 + S * 1000000 + Ms) div 1000. |
|
|
|
|
|
|
|
%% 转换成HEX格式的md5 |
|
|
|
md5(S) -> |
|
|
|
lists:flatten([io_lib:format("~2.16.0b", [N]) || N <- binary_to_list(erlang:md5(S))]). |
|
|
|
|
|
|
|
%% 产生一个介于Min到Max之间的随机整数 |
|
|
|
rand(Same, Same) -> Same; |
|
|
|
rand(Min, Max) -> |
|
|
|
M = Min - 1, |
|
|
|
if |
|
|
|
Max - M =< 0 -> |
|
|
|
0; |
|
|
|
true -> |
|
|
|
%% 如果没有种子,将从核心服务器中去获取一个种子,以保证不同进程都可取得不同的种子 |
|
|
|
case get("rand_seed") of |
|
|
|
undefined -> |
|
|
|
RandSeed = mod_rand:get_seed(), |
|
|
|
random:seed(RandSeed), |
|
|
|
put("rand_seed", RandSeed); |
|
|
|
_ -> skip |
|
|
|
end, |
|
|
|
RanNum = random:uniform(Max - M) + M, |
|
|
|
RanNum |
|
|
|
end. |
|
|
|
|
|
|
|
%%随机从集合中选出指定个数的元素length(List) >= Num |
|
|
|
%%[1,2,3,4,5,6,7,8,9]中选出三个不同的数字[1,2,4] |
|
|
|
get_random_list(List, Num) -> |
|
|
|
ListSize = length(List), |
|
|
|
F = fun(N, List1) -> |
|
|
|
Random = rand(1, (ListSize - N + 1)), |
|
|
|
Elem = lists:nth(Random, List1), |
|
|
|
List2 = lists:delete(Elem, List1), |
|
|
|
List2 |
|
|
|
end, |
|
|
|
Result = lists:foldl(F, List, lists:seq(1, Num)), |
|
|
|
List -- Result. |
|
|
|
|
|
|
|
|
|
|
|
%%从列表[{a,7},{b,8},{c,90},{d,100}],a为7%概率,中根据概率选出指定数目不重复的元素列表 |
|
|
|
%%注意Num不能大于lenth(List) |
|
|
|
get_random_list_probability(List, Num) -> |
|
|
|
F = fun(Elem, ProbabilityValue) -> |
|
|
|
lists:duplicate(ProbabilityValue, Elem) |
|
|
|
end, |
|
|
|
Result1 = lists:flatten([F(Elem, ProbabilityValue) || {Elem, ProbabilityValue} <- List]), |
|
|
|
ProbabilityList = lists:reverse(lists:sort([ProbabilityValue || {_Elem, ProbabilityValue} <- List])), |
|
|
|
MaxProbabilityValue = lists:sum([lists:nth(N, ProbabilityList) || N <- lists:seq(1, Num)]), |
|
|
|
Result2 = get_random_list(Result1, Num + MaxProbabilityValue - length(List)), |
|
|
|
Result3 = lists:usort(Result2), |
|
|
|
Result4 = get_random_list(Result3, Num), |
|
|
|
Result4. |
|
|
|
|
|
|
|
get_randomId_by_value([], _) -> |
|
|
|
fail; |
|
|
|
get_randomId_by_value(Data, Random) -> |
|
|
|
case lists:nth(1, Data) of |
|
|
|
{Id, Weight} -> |
|
|
|
case Weight >= Random of |
|
|
|
true -> |
|
|
|
Id; |
|
|
|
false -> |
|
|
|
get_randomId_by_value(Data -- [{Id, Weight}], Random - Weight) |
|
|
|
end; |
|
|
|
_ -> |
|
|
|
io:format("get_randomId_by_value no match") |
|
|
|
end. |
|
|
|
|
|
|
|
%%从列表[{a,7},{b,8},{c,9},{d,10}],a为7权重,b为8权重 |
|
|
|
get_random_by_weight(List) -> |
|
|
|
F = fun({Id, Weight}, Sum) -> |
|
|
|
Sum + Weight |
|
|
|
end, |
|
|
|
Sum2 = lists:foldl(F, 0, List), |
|
|
|
RandomVa = random:uniform(Sum2), |
|
|
|
RandomId = get_randomId_by_value(List, RandomVa). |
|
|
|
|
|
|
|
|
|
|
|
%%向上取整 |
|
|
|
ceil(N) -> |
|
|
|
T = trunc(N), |
|
|
|
case N == T of |
|
|
|
true -> T; |
|
|
|
false -> 1 + T |
|
|
|
end. |
|
|
|
|
|
|
|
%%向下取整 |
|
|
|
floor(X) -> |
|
|
|
T = trunc(X), |
|
|
|
case (X < T) of |
|
|
|
true -> T - 1; |
|
|
|
_ -> T |
|
|
|
end. |
|
|
|
|
|
|
|
sleep(T) -> |
|
|
|
receive |
|
|
|
after T -> ok |
|
|
|
end. |
|
|
|
|
|
|
|
sleep(T, F) -> |
|
|
|
receive |
|
|
|
after T -> F() |
|
|
|
end. |
|
|
|
|
|
|
|
get_list([], _) -> |
|
|
|
[]; |
|
|
|
get_list(X, F) -> |
|
|
|
F(X). |
|
|
|
|
|
|
|
%% for循环 |
|
|
|
for(Max, Max, F) -> |
|
|
|
F(Max); |
|
|
|
for(I, Max, F) -> |
|
|
|
F(I), |
|
|
|
for(I + 1, Max, F). |
|
|
|
|
|
|
|
%% 带返回状态的for循环 |
|
|
|
%% @return {ok, State} |
|
|
|
for(Max, Min, _F, State) when Min < Max -> |
|
|
|
{ok, State}; |
|
|
|
for(Max, Max, F, State) -> F(Max, State); |
|
|
|
for(I, Max, F, State) -> {ok, NewState} = F(I, State), for(I + 1, Max, F, NewState). |
|
|
|
|
|
|
|
|
|
|
|
for_new(Min, Max, _F, State) when (Min > Max) -> |
|
|
|
{ok, State}; |
|
|
|
for_new(Min, Max, F, State) -> |
|
|
|
{ok, NewState} = F(Min, State), |
|
|
|
for_new(Min + 1, Max, F, NewState). |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
%% term序列化,term转换为string格式,e.g., [{a},1] => "[{a},1]" |
|
|
|