Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <memory>
- #include "game/field.h"
- #include "players/player-interface.h"
- class sea_battle_t {
- public:
- enum turn_t { FIRST_PLAYER = 0, SECOND_PLAYER = 1 };
- sea_battle_t(std::shared_ptr<player_interface_t> player1, field_t field1, std::shared_ptr<player_interface_t> player2,
- field_t field2);
- ~sea_battle_t() = default;
- void play();
- static turn_t change_turn(turn_t current_turn);
- static std::string get_player_name(turn_t turn);
- private:
- std::shared_ptr<player_interface_t> get_current_player(turn_t current_turn) const;
- std::shared_ptr<player_interface_t> get_enemy_player(turn_t current_turn) const;
- field_t &get_current_player_field(turn_t current_turn);
- field_t &get_enemy_player_field(turn_t current_turn);
- field_t &get_enemy_player_hidden_field(turn_t current_turn);
- bool is_game_over(turn_t turn);
- std::shared_ptr<player_interface_t> player1;
- std::shared_ptr<player_interface_t> player2;
- std::vector<int> ship_cell_counts = {0, 0};
- field_t field1;
- field_t field2;
- field_t field1_for_enemy = field_t(0);
- field_t field2_for_enemy = field_t(0);
- bool running{false};
- };
- #include "game/sea-battle.h"
- #include <utility>
- sea_battle_t::sea_battle_t(
- std::shared_ptr<player_interface_t> player1,
- field_t field1,
- std::shared_ptr<player_interface_t> player2,
- field_t field2): player1(std::move(player1)), player2(std::move(player2)), field1(field1), field2(field2) {
- field1_for_enemy = field_t(
- std::vector<std::string>(
- field_t::FIELD_SIZE,
- std::string(field_t::FIELD_SIZE, field_t::EMPTY_CELL)));
- field2_for_enemy = field_t(
- std::vector<std::string>(
- field_t::FIELD_SIZE,
- std::string(field_t::FIELD_SIZE, field_t::EMPTY_CELL)));
- for(int i = 0; i < field_t::FIELD_SIZE; i++) {
- for(int j = 0; j < field_t::FIELD_SIZE; j++) {
- if(field1[i][j] == field_t::SHIP_CELL) {
- ship_cell_counts[1] += 1;
- }
- if(field2[i][j] == field_t::SHIP_CELL) {
- ship_cell_counts[0] += 1;
- }
- }
- }
- }
- sea_battle_t::turn_t sea_battle_t::change_turn(turn_t current_turn) {
- return current_turn == FIRST_PLAYER ? SECOND_PLAYER : FIRST_PLAYER;
- }
- std::string sea_battle_t::get_player_name(turn_t turn) {
- return turn == FIRST_PLAYER ? "First" : "Second";
- }
- std::shared_ptr<player_interface_t> sea_battle_t::get_current_player(turn_t current_turn) const{
- return current_turn == FIRST_PLAYER ? player1 : player2;
- }
- std::shared_ptr<player_interface_t> sea_battle_t::get_enemy_player(turn_t current_turn) const {
- return current_turn == FIRST_PLAYER ? player2 : player1;
- }
- field_t &sea_battle_t::get_current_player_field(turn_t current_turn) {
- return current_turn == FIRST_PLAYER ? field1 : field2;
- }
- field_t &sea_battle_t::get_enemy_player_field(turn_t current_turn) {
- return current_turn == FIRST_PLAYER ? field2 : field1;
- }
- field_t &sea_battle_t::get_enemy_player_hidden_field(turn_t current_turn) {
- return current_turn == FIRST_PLAYER ? field2_for_enemy : field1_for_enemy;
- }
- bool sea_battle_t::is_game_over(turn_t turn) {
- return ship_cell_counts[turn] == 0;
- }
- bool kill_ship(field_t &enemy_field, int x, int y) {
- int i = x-1;
- while(i >= 0 && enemy_field[i][y] != field_t::EMPTY_CELL && enemy_field[i][y] != field_t::MISS_CELL) {
- if(enemy_field[i][y] == field_t::SHIP_CELL) {
- return false;
- }
- i--;
- }
- i = x+1;
- while(i < field_t::FIELD_SIZE && enemy_field[i][y] != field_t::EMPTY_CELL && enemy_field[i][y] != field_t::MISS_CELL) {
- if(enemy_field[i][y] == field_t::SHIP_CELL) {
- return false;
- }
- i++;
- }
- i = y+1;
- while(i < field_t::FIELD_SIZE && enemy_field[x][i] != field_t::EMPTY_CELL && enemy_field[x][i] != field_t::MISS_CELL) {
- if(enemy_field[x][i] == field_t::SHIP_CELL) {
- return false;
- }
- i++;
- }
- i = y-1;
- while(i >= 0 && enemy_field[x][i] != field_t::EMPTY_CELL && enemy_field[x][i] != field_t::MISS_CELL) {
- if(enemy_field[x][i] == field_t::SHIP_CELL) {
- return false;
- }
- i--;
- }
- return true;
- }
- void sea_battle_t:: () {
- turn_t turn = FIRST_PLAYER;
- running = true;
- while(running) {
- field_t &enemy_field = get_enemy_player_field(turn);
- field_t &enemy_hidden_field = get_enemy_player_hidden_field(turn);
- auto current_player = get_current_player(turn);
- std::pair<int, int> coords = current_player->make_move(
- get_current_player_field(turn),
- enemy_hidden_field
- );
- int x = coords.first; int y = coords.second;
- if(!field_t::is_cell_valid(x, y)) {
- current_player->on_incorrect_move(x, y);
- continue;
- }
- if(enemy_field[x][y] == field_t::MISS_CELL || enemy_field[x][y] == field_t::HIT_CELL) {
- current_player->on_duplicate_move(x, y);
- continue;
- }
- if(enemy_field[x][y] == field_t::EMPTY_CELL) {
- current_player->on_miss(x, y);
- enemy_field[x][y] = field_t::MISS_CELL;
- enemy_hidden_field[x][y] = field_t::MISS_CELL;
- }
- if(enemy_field[x][y] == field_t::SHIP_CELL){
- if(kill_ship(enemy_field, x, y)) {
- current_player->on_kill(x, y);
- }else {
- current_player->on_hit(x, y);
- }
- enemy_field[x][y] = field_t::HIT_CELL;
- enemy_hidden_field[x][y] = field_t::HIT_CELL;
- ship_cell_counts[turn]--;
- }
- if(is_game_over(turn)) {
- running = false;
- current_player->on_win();
- get_enemy_player(turn)->on_lose();
- }else {
- if (enemy_field[x][y] != field_t::HIT_CELL) {
- turn = change_turn(turn);
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement