anchor.diff:  
   handle_info({notify_bot_req, _GameId, Ialiases, Space, finished, Naliases, Nscores, Moves}=_Request
               , #state{ width=Width, height=Height, gravity=Gravity, periodic=Periodic
  -            , explore=Explore, table=Table} = State) ->
  +            , table=Table, lrate=LearningRate, discount=Discount} = State) ->
       % ?Info("received ~p",[_Request]),
  -    train_game(egambo_tictac:samples(Space, Ialiases, Moves, Naliases, Nscores), Table, Width, Height, Gravity, Periodic, Explore, undefined),
  +    train_game(egambo_tictac:samples(Space, Ialiases, Moves, Naliases, Nscores), Table, Width, Height, Gravity, Periodic, LearningRate, Discount, undefined),
       {noreply, State};
   handle_info(Reqest, State) when element(1, Reqest) == notify_bot_req ->
       % ignore game notifications 
  
positive.code: -define(QL_TRAIN, "egTicTacQl_").           % Q-table name prefix (egGameTypeId to be appended)
  -define(QL_TRAIN_OPTS, [{record_name, egTicTacQlSample}, {type, set}]).        
  -define(QL_OUTPUT_UNSAMPLED, 0.001).        % Value emitted as output for unsampled move in Export
  
  -record(egTicTacQlSample,   { input= <<>> :: binary()  % binstr key of normalized position (Board)
                              , nos=1       :: integer() % number of board samples (1...)
  
negative.code:     {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
          [] 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, 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}.
  
  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, 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))).
  
  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).
  
  