anchor.diff:          , pick/4
           , play_bot_impl/11
           , train_game/8
  +        , qlearn_max/1
           ]).
   
  --safe([state, stop, resume, explore, flatten]).
  +-safe([state, stop, resume, explore, flatten, qlearn_max, pick, play_bot_impl]).
   
   game_types(egambo_tictac) -> all;
   game_types(_) -> [].
  
positive.code: -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,   { sin= <<>> :: binary() % binstr key of normalized position (Board)
                              , nos=1     :: number() % number of samples (1...)
                              , qos=1     :: number() % score of sample (-1..+1)
                              , aaq=[]    :: list()   % aggregated action qualities
                              }).
  
  -define(egTicTacQlSample,   [ binstr
                              , number
                              , number
                              , list
                              ]).
  % rd(egTicTacQlSample, {sin, nos, qos, aaq}).
  
  -record(state,  { bid        :: egBotId()       % bot id (= module name)
                  , tid        :: egGameTypeId()  % game type id
  
negative.code: 
  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).
  
  