loalkota

Untitled

Jun 28th, 2021 (edited)
145
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.66 KB | None | 0 0
  1. // header
  2. #pragma once
  3.  
  4. #include "players/player-interface.h"
  5.  
  6. #include <iostream>
  7. #include <cassert>
  8. #include <unordered_set>
  9. #include <cassert>
  10. #include <random>
  11. #include <chrono>
  12.  
  13.  
  14. struct pair_hash {
  15.   inline std::size_t operator()(const std::pair<int,int> & v) const {
  16.     return v.first*31+v.second;
  17.   }
  18. };
  19.  
  20. class smart_ai_player_t : public player_interface_t {
  21. public:
  22.   explicit smart_ai_player_t();
  23.  
  24.   std::pair<int, int> make_move(const field_t &my_field, const field_t &enemy_field) override;
  25.  
  26.   void on_incorrect_move(int x, int y) override {
  27.     std::cout << "incorrect: " << x << " " << y << std::endl;
  28.     assert(false);
  29.   }
  30.   void on_duplicate_move(int x, int y) override {
  31.     std::cout << "duplicate: " << x << " " << y << std::endl;
  32.     assert(false);
  33.   }
  34.  
  35.   void on_miss(int, int) override;
  36.   void on_hit(int, int) override;
  37.   void on_kill(int, int) override;
  38.  
  39.   void on_win() override {}
  40.   void on_lose() override {}
  41.  
  42. private:
  43.   std::mt19937_64 gen;
  44.   std::unordered_set<std::pair<int, int>, pair_hash> possible_steps;
  45.  
  46.   bool first_hit{false}, second_hit{false};
  47.   int hit_x, hit_y;
  48.   std::pair<int, int> direction;
  49. };
  50.  
  51. void erase_value_from_vector(std::unordered_set<std::pair<int, int>, pair_hash> &my_vec, std::pair<int, int> el);
  52.  
  53. // cpp
  54.  
  55. #include "players/smart-ai-player.h"
  56.  
  57.  
  58. smart_ai_player_t::smart_ai_player_t(){
  59.   std::seed_seq seq = {std::chrono::high_resolution_clock::now().time_since_epoch().count()};
  60.   gen = std::mt19937_64(seq);
  61.  
  62.   for(int i = 0; i < field_t::FIELD_SIZE; i++) {
  63.     for(int j = 0; j < field_t::FIELD_SIZE; j++) {
  64.       possible_steps.insert({i, j});
  65.     }
  66.   }
  67. }
  68.  
  69. void erase_value_from_vector(std::unordered_set<std::pair<int, int>, pair_hash> &my_vec, std::pair<int, int> el) {
  70.   my_vec.erase(el);
  71. }
  72.  
  73. std::pair<int, int> smart_ai_player_t::make_move(const field_t &, const field_t &enemy_field) {
  74. //  std::cout << "possible values size: " << possible_steps.size() << std::endl;
  75.  
  76.   if(!first_hit && !second_hit) {
  77.     auto it = possible_steps.begin();
  78.  
  79.     int n = std::uniform_int_distribution<int>(0, possible_steps.size() - 1)(gen);
  80.     std::advance(it, n);
  81.  
  82.     return *it;
  83.   }
  84.  
  85.   if(first_hit && !second_hit) {
  86.     std::vector<std::pair<int, int>> next_steps = {{hit_x + 1, hit_y}, {hit_x - 1, hit_y},
  87.                                                    {hit_x, hit_y + 1}, {hit_x, hit_y - 1}};
  88.  
  89.     for(std::pair<int, int> step : next_steps) {
  90.       auto [x, y] = step;
  91.  
  92.       if(field_t::is_cell_valid(x, y) && enemy_field[x][y] == field_t::EMPTY_CELL) {
  93. //        std::cout << "new step: " <<  x << " " << y << std::endl;
  94.  
  95.         return step;
  96.       }
  97.     }
  98.   }else if(first_hit && second_hit) {
  99. //    std::cout << "direction: " << direction.first << " " << direction.second << std::endl;
  100. //    std::cout << "current point: " << hit_x << " " << hit_y << std::endl;
  101. //
  102. //    std::cout << enemy_field << std::endl;
  103.  
  104.     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) {
  105. //      std::cout << "cell is not valid! turn out! " << hit_x + direction.first << " " << hit_y + direction.second << std::endl;
  106.       direction.first = - direction.first;
  107.       direction.second = - direction.second;
  108.     }
  109.  
  110.     while(enemy_field[hit_x][hit_y] != field_t::EMPTY_CELL) {
  111.       hit_x = hit_x + direction.first;
  112.       hit_y = hit_y + direction.second;
  113.     }
  114.  
  115. //    std::cout << "new point: " << hit_x << " " << hit_y << std::endl;
  116.  
  117.     return {hit_x, hit_y};
  118.   }
  119. }
  120.  
  121.  
  122. void smart_ai_player_t::on_miss(int x, int y) {
  123.   erase_value_from_vector(possible_steps, {x, y});
  124.  
  125.   if(first_hit && second_hit) {
  126.     direction.first = -direction.first;
  127.     direction.second = -direction.second;
  128.   }
  129. }
  130.  
  131. void smart_ai_player_t::on_hit(int x, int y)  {
  132.   erase_value_from_vector(possible_steps, {x, y});
  133.  
  134.   if(!first_hit) {
  135.     first_hit = true;
  136.     hit_x = x;
  137.     hit_y = y;
  138.  
  139. //    std::cout << "initial first hit!: " << x << " " << y << std::endl;
  140.   }else if(!second_hit){
  141. //    std::cout << "initial second hit!: " << x << " " << y << std::endl;
  142.  
  143.     second_hit = true;
  144.     direction = {x - hit_x, y - hit_y};
  145.  
  146.     hit_x = x;
  147.     hit_y = y;
  148.   }
  149. }
  150.  
  151. void smart_ai_player_t::on_kill(int x, int y) {
  152. //  std::cout << "kill! " << x << " " << y << std::endl;
  153.   erase_value_from_vector(possible_steps, {x, y});
  154.   erase_value_from_vector(possible_steps, {x-1, y});
  155.   erase_value_from_vector(possible_steps, {x+1, y});
  156.   erase_value_from_vector(possible_steps, {x, y-1});
  157.   erase_value_from_vector(possible_steps, {x, y+1});
  158.  
  159.   first_hit = false;
  160.   second_hit = false;
  161. }
  162.  
Add Comment
Please, Sign In to add comment