anchor.diff:              %% We use our own initialization of the weights so we have some flexibility.
               [rand:uniform() * 0.5 - 0.25 || _ <- lists:seq(1, N)];
           [#{cvalue := CVal }] ->
  -            lists:flatten(imem_json:decode(CVal, [return_maps]))
  +            imem_json:decode(CVal, [return_maps])
       end.
   
   -spec save(list(), pid()) -> ok.
   save(Id, NN) ->
  -    Weights = ann:get_weights(NN),
  +    Weights = annlink:get_weights(NN),
       imem_dal_skvh:write(system, ?NETWORK_CHANNEL, Id, imem_json:encode(Weights)),
       ok.
   
  --spec init_network([integer()], [float()]) -> pid() | {error, binary()}.
  +-spec init_network([integer()], [float()]) -> binary() | {error, binary()}.
   init_network([42 | Rest] = Layers, Weights) ->
       case lists:last(Rest) of
  -        1 -> ann:create_neural_network(Layers, Weights, relu);
  +        1 ->
  +            {ok, Conn} = annlink:new_connection('192.168.1.42', 8778),
  +            annlink:create_neural_network(Conn, Layers, Weights, relu),
  +            Conn;
           _ -> {error, <<"Output layer must contain only one neuron">>}
       end;
   init_network(_, _) -> {error, <<"Input layer must contain 42 neuros">>}.
  
positive.code: 
  -record(state, {
      id :: list(),
      network :: pid(), 
      games = #{} :: map()
  }).
  
  
negative.code: suggest_moves_impl(Board, NN) ->
      Moves = empty_pos(Board, [35,28,21,14,7,0], 0),
      NextBoards = [apply_move(Board, M) || M <- Moves],
      Values = annlink:predict(NN, NextBoards),
      Suggested = lists:zip(Values, Moves),
      {_, Best} = lists:max(Suggested),
      {Suggested, Best}.
  