%% -----------------------------------------------------
%% @author  :ljy
%% moudle   :lib_reversi.erl
%% desc     :黑白棋算法
%% time     :2020.11.24
%% ------------------------------------------------------
-module(lib_reversi).

-include("def_fun.hrl").

-export([get_passive_lattice/2]).

%% 获取被动翻开的格子
get_passive_lattice(PoolInfo, Num) ->
    TopList = get_top(PoolInfo, [], Num),
    LowerList = get_lower(PoolInfo, [], Num),
    LeftList = get_left(PoolInfo, [], Num),
    RigthList = get_right(PoolInfo, [], Num),
    TopLeftList = get_top_left(PoolInfo, [], Num),
    TopRightList = get_top_right(PoolInfo, [], Num),
    LowerLeftList = get_lower_left(PoolInfo, [], Num),
    LowerRightList = get_lower_right(PoolInfo, [], Num),
    TopList ++ LowerList ++ LeftList ++ RigthList ++ TopLeftList ++ TopRightList ++ LowerLeftList ++ LowerRightList.

% 上
get_top(PoolInfo, AddList, Num) ->
    Num1 = Num - 4,
    Line = get_line(Num1),
    if
        Num1 >= 1, Line >= 1 ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_top(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.
% 下
get_lower(PoolInfo, AddList, Num) ->
    Num1 = Num + 4,
    Line = get_line(Num1),
    if
        Num1 =< 16, Line =< 4 ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_lower(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.
% 左
get_left(PoolInfo, AddList, Num) ->
    Num1 = Num - 1,
    % 本行最左的数
    Line = get_line(Num),
    LeftNum = (Line - 1) * 4 + 1,
    if
        Num1 >= LeftNum ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_left(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.

% 右
get_right(PoolInfo, AddList, Num) ->
    Num1 = Num + 1,
    % 本行最右的数
    Line = get_line(Num),
    RightNum = Line * 4,
    if
        Num1 =< RightNum ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_right(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.

% 左上
get_top_left(PoolInfo, AddList, Num) ->
    Num1 = Num - 5,
    {Line, Row} = get_line_and_row(Num),
    {Line1, Row1} = get_line_and_row(Num1),
    if
        Num1 >= 1 andalso Line - 1 =:= Line1 andalso Row - 1 =:= Row1 ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_top_left(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.

% 右上
get_top_right(PoolInfo, AddList, Num) ->
    Num1 = Num - 3,
    {Line, Row} = get_line_and_row(Num),
    {Line1, Row1} = get_line_and_row(Num1),
    if
        Num1 >= 1 andalso Line - 1 =:= Line1 andalso Row + 1 =:= Row1 ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_top_right(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.

% 左下
get_lower_left(PoolInfo, AddList, Num) ->
    Num1 = Num + 3,
    {Line, Row} = get_line_and_row(Num),
    {Line1, Row1} = get_line_and_row(Num1),
    if
        Num1 =< 16 andalso Line + 1 =:= Line1 andalso Row - 1 =:= Row1 ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_lower_left(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.

% 右下
get_lower_right(PoolInfo, AddList, Num) ->
    Num1 = Num + 5,
    {Line, Row} = get_line_and_row(Num),
    {Line1, Row1} = get_line_and_row(Num1),
    if
        Num1 =< 16 andalso Line + 1 =:= Line1 andalso Row + 1 =:= Row1 ->
            case lists:keyfind(Num1, 1, PoolInfo) of
                {_, _, 0} -> get_lower_right(PoolInfo, [Num1 | AddList], Num1);
                _ -> AddList
            end;
        true -> []
    end.

get_line(Num) ->
    Quotient = Num rem 4,
    Line = ?IF(Quotient =:= 0, Num div 4, Num div 4 + 1),
    Line.

%% 格子的行、列
get_line_and_row(Num) ->
    Line = get_line(Num),
    Remainder = Num rem 4,
    Row = ?IF(Remainder =:= 0, 4, Remainder),
    {Line, Row}.
