Advertisement
loalkota

Untitled

Jun 24th, 2021
485
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.70 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <memory>
  4.  
  5. #include "game/field.h"
  6. #include "players/player-interface.h"
  7.  
  8. class sea_battle_t {
  9. public:
  10.   enum turn_t { FIRST_PLAYER = 0, SECOND_PLAYER = 1 };
  11.  
  12.   sea_battle_t(std::shared_ptr<player_interface_t> player1, field_t field1, std::shared_ptr<player_interface_t> player2,
  13.                field_t field2);
  14.  
  15.   ~sea_battle_t() = default;
  16.  
  17.   void play();
  18.  
  19.   static turn_t change_turn(turn_t current_turn);
  20.   static std::string get_player_name(turn_t turn);
  21.  
  22. private:
  23.   std::shared_ptr<player_interface_t> get_current_player(turn_t current_turn) const;
  24.   std::shared_ptr<player_interface_t> get_enemy_player(turn_t current_turn) const;
  25.  
  26.   field_t &get_current_player_field(turn_t current_turn);
  27.   field_t &get_enemy_player_field(turn_t current_turn);
  28.   field_t &get_enemy_player_hidden_field(turn_t current_turn);
  29.  
  30.   bool is_game_over(turn_t turn);
  31.  
  32.   std::shared_ptr<player_interface_t> player1;
  33.   std::shared_ptr<player_interface_t> player2;
  34.  
  35.   std::vector<int> ship_cell_counts = {0, 0};
  36.  
  37.   field_t field1;
  38.   field_t field2;
  39.  
  40.   field_t field1_for_enemy = field_t(0);
  41.   field_t field2_for_enemy = field_t(0);
  42.  
  43.   bool running{false};
  44. };
  45.  
  46.  
  47.  
  48. #include "game/sea-battle.h"
  49.  
  50. #include <utility>
  51.  
  52. sea_battle_t::sea_battle_t(
  53.     std::shared_ptr<player_interface_t> player1,
  54.     field_t field1,
  55.     std::shared_ptr<player_interface_t> player2,
  56.     field_t field2): player1(std::move(player1)), player2(std::move(player2)), field1(field1), field2(field2) {
  57.  
  58.     field1_for_enemy = field_t(
  59.       std::vector<std::string>(
  60.           field_t::FIELD_SIZE,
  61.           std::string(field_t::FIELD_SIZE, field_t::EMPTY_CELL)));
  62.  
  63.     field2_for_enemy = field_t(
  64.         std::vector<std::string>(
  65.             field_t::FIELD_SIZE,
  66.             std::string(field_t::FIELD_SIZE, field_t::EMPTY_CELL)));
  67.  
  68.     for(int i = 0; i < field_t::FIELD_SIZE; i++) {
  69.       for(int j = 0; j < field_t::FIELD_SIZE; j++) {
  70.         if(field1[i][j] == field_t::SHIP_CELL) {
  71.           ship_cell_counts[1] += 1;
  72.         }
  73.         if(field2[i][j] == field_t::SHIP_CELL) {
  74.           ship_cell_counts[0] += 1;
  75.         }
  76.       }
  77.     }
  78. }
  79.  
  80. sea_battle_t::turn_t sea_battle_t::change_turn(turn_t current_turn) {
  81.   return current_turn == FIRST_PLAYER ? SECOND_PLAYER : FIRST_PLAYER;
  82. }
  83.  
  84. std::string sea_battle_t::get_player_name(turn_t turn) {
  85.   return turn == FIRST_PLAYER ? "First" : "Second";
  86. }
  87.  
  88. std::shared_ptr<player_interface_t> sea_battle_t::get_current_player(turn_t current_turn) const{
  89.   return current_turn == FIRST_PLAYER ? player1 : player2;
  90. }
  91.  
  92. std::shared_ptr<player_interface_t> sea_battle_t::get_enemy_player(turn_t current_turn) const {
  93.   return current_turn == FIRST_PLAYER ? player2 : player1;
  94. }
  95.  
  96. field_t &sea_battle_t::get_current_player_field(turn_t current_turn) {
  97.   return current_turn == FIRST_PLAYER ? field1 : field2;
  98. }
  99.  
  100. field_t &sea_battle_t::get_enemy_player_field(turn_t current_turn) {
  101.   return current_turn == FIRST_PLAYER ? field2 : field1;
  102. }
  103.  
  104. field_t &sea_battle_t::get_enemy_player_hidden_field(turn_t current_turn) {
  105.   return current_turn == FIRST_PLAYER ? field2_for_enemy : field1_for_enemy;
  106. }
  107.  
  108. bool sea_battle_t::is_game_over(turn_t turn) {
  109.   return ship_cell_counts[turn] == 0;
  110. }
  111.  
  112. bool kill_ship(field_t &enemy_field, int x, int y) {
  113.   int i = x-1;
  114.   while(i >= 0 && enemy_field[i][y] != field_t::EMPTY_CELL && enemy_field[i][y] != field_t::MISS_CELL) {
  115.     if(enemy_field[i][y] == field_t::SHIP_CELL) {
  116.       return false;
  117.     }
  118.     i--;
  119.   }
  120.  
  121.   i = x+1;
  122.   while(i < field_t::FIELD_SIZE && enemy_field[i][y] != field_t::EMPTY_CELL && enemy_field[i][y] != field_t::MISS_CELL) {
  123.     if(enemy_field[i][y] == field_t::SHIP_CELL) {
  124.       return false;
  125.     }
  126.     i++;
  127.   }
  128.  
  129.   i = y+1;
  130.   while(i < field_t::FIELD_SIZE && enemy_field[x][i] != field_t::EMPTY_CELL && enemy_field[x][i] != field_t::MISS_CELL) {
  131.     if(enemy_field[x][i] == field_t::SHIP_CELL) {
  132.       return false;
  133.     }
  134.     i++;
  135.   }
  136.  
  137.   i = y-1;
  138.   while(i >= 0 && enemy_field[x][i] != field_t::EMPTY_CELL && enemy_field[x][i] != field_t::MISS_CELL) {
  139.     if(enemy_field[x][i] == field_t::SHIP_CELL) {
  140.       return false;
  141.     }
  142.     i--;
  143.   }
  144.  
  145.   return true;
  146. }
  147.  
  148. void sea_battle_t:: () {
  149.   turn_t turn = FIRST_PLAYER;
  150.   running = true;
  151.  
  152.   while(running) {
  153.     field_t &enemy_field = get_enemy_player_field(turn);
  154.     field_t &enemy_hidden_field = get_enemy_player_hidden_field(turn);
  155.  
  156.     auto current_player = get_current_player(turn);
  157.  
  158.     std::pair<int, int> coords = current_player->make_move(
  159.         get_current_player_field(turn),
  160.         enemy_hidden_field
  161.         );
  162.  
  163.     int x = coords.first; int y = coords.second;
  164.  
  165.     if(!field_t::is_cell_valid(x, y)) {
  166.       current_player->on_incorrect_move(x, y);
  167.       continue;
  168.     }
  169.  
  170.     if(enemy_field[x][y] == field_t::MISS_CELL || enemy_field[x][y] == field_t::HIT_CELL) {
  171.       current_player->on_duplicate_move(x, y);
  172.       continue;
  173.     }
  174.  
  175.     if(enemy_field[x][y] == field_t::EMPTY_CELL) {
  176.       current_player->on_miss(x, y);
  177.  
  178.       enemy_field[x][y] = field_t::MISS_CELL;
  179.       enemy_hidden_field[x][y] = field_t::MISS_CELL;
  180.     }
  181.  
  182.     if(enemy_field[x][y] == field_t::SHIP_CELL){
  183.       if(kill_ship(enemy_field, x, y)) {
  184.         current_player->on_kill(x, y);
  185.       }else {
  186.         current_player->on_hit(x, y);
  187.       }
  188.  
  189.       enemy_field[x][y] = field_t::HIT_CELL;
  190.       enemy_hidden_field[x][y] = field_t::HIT_CELL;
  191.       ship_cell_counts[turn]--;
  192.     }
  193.  
  194.     if(is_game_over(turn)) {
  195.       running = false;
  196.  
  197.       current_player->on_win();
  198.       get_enemy_player(turn)->on_lose();
  199.     }else {
  200.       if (enemy_field[x][y] != field_t::HIT_CELL) {
  201.         turn = change_turn(turn);
  202.       }
  203.     }
  204.   }
  205. }
  206.  
  207.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement