anchor.diff:      {Input, Sym} = egambo_tictac_sym:norm(Width, Height, Gravity, Periodic, ABoard), 
       % ?Info("play_bot_impl Input (normalized board) and symmetry used ~p ~p", [Input, Sym]),
       {NOS, AccActionQuality} = case imem_meta:read(Table, list_to_binary(Input)) of
  -        [] ->   {0, new_output(Input, Width, Height, Gravity)};
  -        [#egTicTacQlSample{nos=Nos, aaq=Aaq}] -> {Nos,Aaq}
  +        [] when Gravity==false ->                   {0, empty_action_qualities(Input, Width*Height)};
  +        [] ->                                       {0, empty_action_qualities(Input, Width)};
  +        [#egTicTacQlSample{nos=Nos, aaq=Aaq}] ->    {Nos,Aaq}
       end,
       % ?Info("play_bot_impl ActionQuality ~p",[ActionQuality]),    
  -    NormIdx = pick(NOS, AccActionQuality, Explore, Flatten),      % 0-based index for predicted move
  +    NormIdx = pick(NOS, AccActionQuality, 1.0, Explore, Flatten),      % 0-based index for predicted move
       NewIdx = egambo_tictac_sym:unmap_move(Width, Height, NormIdx, Sym),    
       % ?Info("play_bot_impl NormIdx, NewIdx (output picked) ~p ~p", [NormIdx, NewIdx]),
       {ok, Idx, NewBoard} = egambo_tictac:put(Gravity, Board, Width, NewIdx, hd(NAliases)),
       % ?Info("play_bot_impl Idx, NewBoard ~p ~p", [Idx, binary_to_list(NewBoard)]),
       {ok, Idx, NewBoard}.
   
  -new_output(Input, Width, Height, false) ->
  -    F = fun(I) -> 
  -        Inp=lists:nth(I, Input), 
  -        if 
  -            Inp==32 ->   {0, 0};      % alternative legal move
  -            true ->      0            % illegal move (occupied)
  -        end 
  -    end, 
  -    lists:map(F, lists:seq(1, Width*Height));
  -new_output(Input, Width, _Height, true) ->
  -    F = fun(I) -> 
  -        Inp=lists:nth(I, Input), 
  -        if 
  -            Inp==32 ->   {0, 0};      % alternative legal move
  -            true ->      0            % illegal move (occupied)
  -        end 
  -    end, 
  -    lists:map(F, lists:seq(1, Width)).
  -
  -pick(NOS, AccActionQuality, Explore, 0) ->
  -    AL = [{target(A, NOS, Explore), rand:uniform(), I} || {A,I} <- lists:zip(AccActionQuality, lists:seq(0, length(AccActionQuality)-1))],
  +pick(NOS, AccActionQuality, Prior, Explore, 0) ->
  +    AL = [{ucb1_target(A, NOS, Prior, Explore), rand:uniform(), I} || {A,I} <- lists:zip(AccActionQuality, lists:seq(0, length(AccActionQuality)-1))],
       element(3, lists:last(lists:sort(AL)));
  -pick(NOS, AccActionQuality, Explore, Flatten) ->
  -    AL = [{target(A, NOS, Explore) + Flatten* rand:uniform(), I} || {A,I} <- lists:zip(AccActionQuality, lists:seq(0, length(AccActionQuality)-1))],
  +pick(NOS, AccActionQuality, Prior, Explore, Flatten) ->
  +    AL = [{ucb1_target(A, NOS, Prior, Explore) + Flatten*rand:uniform(), I} || {A,I} <- lists:zip(AccActionQuality, lists:seq(0, length(AccActionQuality)-1))],
       element(2, lists:last(lists:sort(AL))).
   
  -target(0, _, _) -> -100; 
  -target({0,0}, _, _) -> 100; 
  -target({N,Q}, NOS, Explore) -> 
  -    DE = 1.0 + Explore*math:sqrt(NOS)/(1+N),
  -    (Q/N + DE) / DE.
  -% target({N,Q}, NOS, Explore) -> Q/N + Explore*math:sqrt(NOS)/(1+N).
  -
  +ucb1_target(0, _, _, _) -> -100; 
  +ucb1_target({0, 0, 0}, _, _, _) -> 100; 
  +ucb1_target({N, Q, _Q2}, NOS, _Prior, Explore) -> 
  +    Q/N + ?UCB1_BONUS(NOS, N, _Prior, Explore).
  +
  +% ucb1_target({N,Q}, NOS, Prior, Explore) -> 
  +%     DE = 1.0 + Explore*math:sqrt(NOS)/(1+N),
  +%     (Q/N + DE) / DE.
  +% ucb1_target({N,Q}, NOS, Explore) -> Q/N + Explore*math:sqrt(NOS)/(1+N).
  +
  
positive.code:     supervisor:delete_child(egambo_bot_sup, ?BOT_ID(?MODULE, GameTypeId)).
  
  
  state(GameTypeId) ->
      gen_server:call(?BOT_GID(?MODULE, GameTypeId), state). 
  
  
  -spec play_bot_impl(binary(), integer(), integer(), integer(), boolean(), boolean(), [egAlias()], [egAlias()], float(), float(), atom()) -> egBotMove() | {error, atom()}.
  play_bot_impl(Board, Width, Height, _Run, Gravity, Periodic, IAliases, NAliases, Explore, Flatten, Table) ->
      % ?Info("play_bot_impl Board, NAliases ~p ~p", [Board, NAliases]),
  
negative.code:                 , winmod     :: egWinId()       % win function module
                  , players    :: integer()       % number of players 
                  , status     :: egBotStatus()   % current bot status (e.g. learning / playing)
                  , explore=0.1 :: float()         % rate for exploration (0..1.0)
                  , flatten=0  :: float()         % flat peak randomisation
                  , lrate=0.5  :: float()         % learning rate
                  , discount=0.95  :: float()      % Q-discount per move
                  , table      :: atom()          % table name for Q-A-aggregation
                  }).
  
  