// Copyright 2019 DeepMind Technologies Ltd. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "open_spiel/algorithms/kriegspiel/random_bot.h"

#include "open_spiel/games/kriegspiel.h"
#include "open_spiel/abseil-cpp/absl/random/distributions.h"

namespace open_spiel {
namespace algorithms {


algorithms::RandomBot::RandomBot(int seed)
    : rng_(seed) { }

Action RandomBot::Step(const State &state) {
  std::vector<Action> available_actions = state.LegalActions();
  return available_actions[absl::Uniform(rng_, 0u, available_actions.size())];
}

algorithms::RandomBotHeuristic::RandomBotHeuristic(int seed)
  : rng_(seed) { }

void RandomBotHeuristic::InformAction(const State &state,
                                      Player player_id,
                                      Action action) {

  auto kriegspiel_state = down_cast<const kriegspiel::KriegspielState &>(state);
  chess::Move move = chess::ActionToMove(action, kriegspiel_state.Board());
  kriegspiel::KriegspielUmpireMessage msg = kriegspiel::GetUmpireMessage(kriegspiel_state.Board(), move);

  if (msg.capture_type != kriegspiel::KriegspielCaptureType::kNoCapture) {
    capture_square_ = msg.square;
  }
}

Action RandomBotHeuristic::Step(const State &state) {
  auto kriegspiel_state = down_cast<const kriegspiel::KriegspielState &>(state);

  std::vector<Action> available_actions = state.LegalActions();

  if (capture_square_ != chess::kInvalidSquare) {
    std::vector<Action> recapture_actions;
    for (Action action : available_actions) {
      chess::Move move = chess::ActionToMove(action, kriegspiel_state.Board());
      if (move.to == capture_square_) {
        recapture_actions.push_back(action);
      }
    }
    if (!recapture_actions.empty()) {
      available_actions = recapture_actions;
    }
  }
  return available_actions[absl::Uniform(rng_, 0u, available_actions.size())];
}

}  // namespace algorithms
}  // namespace open_spiel
