Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // header
- #pragma once
- #include "players/player-interface.h"
- #include <iostream>
- #include <cassert>
- #include <unordered_set>
- #include <cassert>
- #include <random>
- #include <chrono>
- struct pair_hash {
- inline std::size_t operator()(const std::pair<int,int> & v) const {
- return v.first*31+v.second;
- }
- };
- class smart_ai_player_t : public player_interface_t {
- public:
- explicit smart_ai_player_t();
- std::pair<int, int> make_move(const field_t &my_field, const field_t &enemy_field) override;
- void on_incorrect_move(int x, int y) override {
- std::cout << "incorrect: " << x << " " << y << std::endl;
- assert(false);
- }
- void on_duplicate_move(int x, int y) override {
- std::cout << "duplicate: " << x << " " << y << std::endl;
- assert(false);
- }
- void on_miss(int, int) override;
- void on_hit(int, int) override;
- void on_kill(int, int) override;
- void on_win() override {}
- void on_lose() override {}
- private:
- std::mt19937_64 gen;
- std::unordered_set<std::pair<int, int>, pair_hash> possible_steps;
- bool first_hit{false}, second_hit{false};
- int hit_x, hit_y;
- std::pair<int, int> direction;
- };
- void erase_value_from_vector(std::unordered_set<std::pair<int, int>, pair_hash> &my_vec, std::pair<int, int> el);
- // cpp
- #include "players/smart-ai-player.h"
- smart_ai_player_t::smart_ai_player_t(){
- std::seed_seq seq = {std::chrono::high_resolution_clock::now().time_since_epoch().count()};
- gen = std::mt19937_64(seq);
- for(int i = 0; i < field_t::FIELD_SIZE; i++) {
- for(int j = 0; j < field_t::FIELD_SIZE; j++) {
- possible_steps.insert({i, j});
- }
- }
- }
- void erase_value_from_vector(std::unordered_set<std::pair<int, int>, pair_hash> &my_vec, std::pair<int, int> el) {
- my_vec.erase(el);
- }
- std::pair<int, int> smart_ai_player_t::make_move(const field_t &, const field_t &enemy_field) {
- // std::cout << "possible values size: " << possible_steps.size() << std::endl;
- if(!first_hit && !second_hit) {
- auto it = possible_steps.begin();
- int n = std::uniform_int_distribution<int>(0, possible_steps.size() - 1)(gen);
- std::advance(it, n);
- return *it;
- }
- if(first_hit && !second_hit) {
- std::vector<std::pair<int, int>> next_steps = {{hit_x + 1, hit_y}, {hit_x - 1, hit_y},
- {hit_x, hit_y + 1}, {hit_x, hit_y - 1}};
- for(std::pair<int, int> step : next_steps) {
- auto [x, y] = step;
- if(field_t::is_cell_valid(x, y) && enemy_field[x][y] == field_t::EMPTY_CELL) {
- // std::cout << "new step: " << x << " " << y << std::endl;
- return step;
- }
- }
- }else if(first_hit && second_hit) {
- // std::cout << "direction: " << direction.first << " " << direction.second << std::endl;
- // std::cout << "current point: " << hit_x << " " << hit_y << std::endl;
- //
- // std::cout << enemy_field << std::endl;
- if(!field_t::is_cell_valid(hit_x + direction.first, hit_y + direction.second) || enemy_field[hit_x + direction.first][hit_y + direction.second] == field_t::MISS_CELL) {
- // std::cout << "cell is not valid! turn out! " << hit_x + direction.first << " " << hit_y + direction.second << std::endl;
- direction.first = - direction.first;
- direction.second = - direction.second;
- }
- while(enemy_field[hit_x][hit_y] != field_t::EMPTY_CELL) {
- hit_x = hit_x + direction.first;
- hit_y = hit_y + direction.second;
- }
- // std::cout << "new point: " << hit_x << " " << hit_y << std::endl;
- return {hit_x, hit_y};
- }
- }
- void smart_ai_player_t::on_miss(int x, int y) {
- erase_value_from_vector(possible_steps, {x, y});
- if(first_hit && second_hit) {
- direction.first = -direction.first;
- direction.second = -direction.second;
- }
- }
- void smart_ai_player_t::on_hit(int x, int y) {
- erase_value_from_vector(possible_steps, {x, y});
- if(!first_hit) {
- first_hit = true;
- hit_x = x;
- hit_y = y;
- // std::cout << "initial first hit!: " << x << " " << y << std::endl;
- }else if(!second_hit){
- // std::cout << "initial second hit!: " << x << " " << y << std::endl;
- second_hit = true;
- direction = {x - hit_x, y - hit_y};
- hit_x = x;
- hit_y = y;
- }
- }
- void smart_ai_player_t::on_kill(int x, int y) {
- // std::cout << "kill! " << x << " " << y << std::endl;
- erase_value_from_vector(possible_steps, {x, y});
- erase_value_from_vector(possible_steps, {x-1, y});
- erase_value_from_vector(possible_steps, {x+1, y});
- erase_value_from_vector(possible_steps, {x, y-1});
- erase_value_from_vector(possible_steps, {x, y+1});
- first_hit = false;
- second_hit = false;
- }
Add Comment
Please, Sign In to add comment