Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dorofeev_id/task5/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"CodeGPT.apiKey": "CodeGPT Plus Beta"
"CodeGPT.apiKey": "Ollama"
}
99 changes: 99 additions & 0 deletions dorofeev_id/task6/Board.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#include "Board.h"

Board::Board(int size) : size(size), grid(size, std::vector<Cell>(size)) {}

void Board::display() const
{
std::cout << " A B C D E F G H I J\n";
for (int i = 0; i < size; ++i)
{
std::cout << i + 1 << ' ';
for (int j = 0; j < size; ++j)
{
char c = '.';
switch (grid[i][j].state)
{
case EMPTY: c = '.'; break;
case SHIP: c = 'S'; break;
case HIT: c = 'X'; break;
case MISS: c = 'O'; break;
}
std::cout << c << ' ';
}
std::cout << '\n';
}
}

bool Board::placeShip(int x1, int y1, int x2, int y2, int size)
{
if (x1 != x2 && y1 != y2) return false;
if (std::abs(x2 - x1) + 1 != size && std::abs(y2 - y1) + 1 != size) return false;

for (int i = x1; i <= x2; ++i)
{
for (int j = y1; j <= y2; ++j)
{
if (grid[i][j].state != EMPTY || isAdjacent(i, j, i, j)) return false;
}
}

for (int i = x1; i <= x2; ++i)
{
for (int j = y1; j <= y2; ++j)
{
grid[i][j].state = SHIP;
}
}
return true;
}

bool Board::isHit(int x, int y)
{
if (grid[x][y].state == SHIP)
{
grid[x][y].state = HIT;
return true;
}
else
{
grid[x][y].state = MISS;
return false;
}
}

bool Board::allShipsSunk() const
{
for (const auto& row : grid)
{
for (const auto& cell : row)
{
if (cell.state == SHIP) return false;
}
}
return true;
}

Cell Board::getCell(int x, int y) const
{
return grid[x][y];
}

bool Board::isAdjacent(int x1, int y1, int x2, int y2) const
{
for (int i = -1; i <= 1; ++i)
{
for (int j = -1; j <= 1; ++j)
{
int x = x1 + i;
int y = y1 + j;
if (x >= 0 && x < size && y >= 0 && y < size && !(x == x2 && y == y2))
{
if (grid[x][y].state == SHIP)
{
return true;
}
}
}
}
return false;
}
23 changes: 23 additions & 0 deletions dorofeev_id/task6/Board.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <vector>
#include <iostream>
#include "Cell.h"

#define BOARD_SIZE 10

class Board
{
public:
Board(int size);
void display() const;
bool placeShip(int x1, int y1, int x2, int y2, int size);
bool isHit(int x, int y);
bool allShipsSunk() const;
Cell getCell(int x, int y) const;

private:
int size;
std::vector<std::vector<Cell>> grid;
bool isAdjacent(int x1, int y1, int x2, int y2) const;
};
3 changes: 3 additions & 0 deletions dorofeev_id/task6/Cell.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "Cell.h"

Cell::Cell() : state(EMPTY) {}
16 changes: 16 additions & 0 deletions dorofeev_id/task6/Cell.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

enum CellState
{
EMPTY,
SHIP,
HIT,
MISS
};

class Cell {
public:
CellState state;
Cell();
};

35 changes: 35 additions & 0 deletions dorofeev_id/task6/ComputerPlayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "ComputerPlayer.h"

ComputerPlayer::ComputerPlayer(Board& board)
: Player(board), gen(rd()), dis(0, 9) {}

void ComputerPlayer::placeShips()
{
int shipSizes[] = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
for (int size : shipSizes)
{
bool placed = false;
while (!placed)
{
int x1 = dis(gen), y1 = dis(gen);
int direction = dis(gen) % 2; // 0 - horizontal, 1 - vertical
int x2 = direction == 0 ? x1 : x1 + size - 1;
int y2 = direction == 0 ? y1 + size - 1 : y1;
if (x2 < 10 && y2 < 10 && board.placeShip(x1, y1, x2, y2, size))
{
placed = true;
}
}
}
}

bool ComputerPlayer::takeTurn(Player& opponent)
{
int x = dis(gen), y = dis(gen);
while (opponent.getBoard().getCell(x, y).state == HIT || opponent.getBoard().getCell(x, y).state == MISS)
{
x = dis(gen);
y = dis(gen);
}
return opponent.getBoard().isHit(x, y);
}
18 changes: 18 additions & 0 deletions dorofeev_id/task6/ComputerPlayer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#pragma once

#include "Player.h"
#include <random>

class ComputerPlayer : public Player
{
public:
ComputerPlayer(Board& board);
void placeShips() override;
bool takeTurn(Player& opponent) override;

private:
std::random_device rd;
std::mt19937 gen;
std::uniform_int_distribution<> dis;
};

6 changes: 6 additions & 0 deletions dorofeev_id/task6/Constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#pragma once

#include <vector>

const int BOARD_SIZE = 10;
const std::vector<int> SHIP_SIZES = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
40 changes: 40 additions & 0 deletions dorofeev_id/task6/Game.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "Game.h"

Game::Game()
: humanBoard(10), computerBoard(10),
humanPlayer(humanBoard), computerPlayer(computerBoard) {}

void Game::play()
{
humanPlayer.placeShips();
computerPlayer.placeShips();

while (!humanBoard.allShipsSunk() && !computerBoard.allShipsSunk())
{
if (humanPlayer.takeTurn(computerPlayer))
{
std::cout << "You hit a ship!\n";
}
else
{
std::cout << "You missed.\n";
}
if (computerPlayer.takeTurn(humanPlayer))
{
std::cout << "Computer hit your ship!\n";
}
else
{
std::cout << "Computer missed.\n";
}
}

if (humanBoard.allShipsSunk())
{
std::cout << "Computer wins!\n";
}
else
{
std::cout << "You win!\n";
}
}
19 changes: 19 additions & 0 deletions dorofeev_id/task6/Game.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#pragma once

#include "Player.h"
#include "HumanPlayer.h"
#include "ComputerPlayer.h"

class Game
{
public:
Game();
void play();

private:
Board humanBoard;
Board computerBoard;
HumanPlayer humanPlayer;
ComputerPlayer computerPlayer;
};

118 changes: 118 additions & 0 deletions dorofeev_id/task6/HumanPlayer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#include "HumanPlayer.h"
#include <iostream>
#include <sstream>
#include <cctype>
#include <limits>


HumanPlayer::HumanPlayer(Board& board) : Player(board) {}

void HumanPlayer::placeShips()
{
int shipSizes[] = { 4, 3, 3, 2, 2, 2, 1, 1, 1, 1 };
for (int size : shipSizes)
{
bool placed = false;
while (!placed)
{
board.display();
std::cout << "Place a ship of size " << size << ".\n";
std::cout << "Enter the starting and ending coordinates (e.g., A1 A4 or B2 E2): ";
std::string input;
std::getline(std::cin, input);
std::istringstream iss(input);
std::string startCoord, endCoord;
iss >> startCoord >> endCoord;

if (startCoord.length() < 2 || endCoord.length() < 2)
{
std::cout << "Invalid input format. Please enter coordinates in the format: A1 A4 or B2 E2.\n";
continue;
}

char startCol = startCoord[0], endCol = endCoord[0];
int startRow, endRow;
try {
startRow = std::stoi(startCoord.substr(1));
endRow = std::stoi(endCoord.substr(1));
}
catch (const std::invalid_argument&) {
std::cout << "Invalid row input. Please enter valid coordinates.\n";
continue;
}

if (!isalpha(startCol) || !isalpha(endCol))
{
std::cout << "Invalid column input. Please enter valid coordinates.\n";
continue;
}

startCol = toupper(startCol);
endCol = toupper(endCol);

int x1 = startRow - 1, y1 = startCol - 'A';
int x2 = endRow - 1, y2 = endCol - 'A';

if (x1 < 0 || x1 >= BOARD_SIZE || y1 < 0 || y1 >= BOARD_SIZE ||
x2 < 0 || x2 >= BOARD_SIZE || y2 < 0 || y2 >= BOARD_SIZE)
{
std::cout << "Coordinates out of bounds. Please try again.\n";
continue;
}

if (board.placeShip(x1, y1, x2, y2, size))
{
placed = true;
}
else
{
std::cout << "Invalid placement. Try again.\n";
}
}
}
}

bool HumanPlayer::takeTurn(Player& opponent)
{
board.display();
std::cout << "Enter coordinates to hit (e.g., A1): ";
std::string input;
std::getline(std::cin, input);
std::istringstream iss(input);
std::string coord;
iss >> coord;

if (coord.length() < 2)
{
std::cout << "Invalid input format. Please enter coordinates in the format: A1.\n";
return false;
}

char col = coord[0];
int row;
try {
row = std::stoi(coord.substr(1));
}
catch (const std::invalid_argument&) {
std::cout << "Invalid row input. Please enter valid coordinates.\n";
return false;
}

if (!isalpha(col))
{
std::cout << "Invalid column input. Please enter valid coordinates.\n";
return false;
}

col = toupper(col);

int x = row - 1, y = col - 'A';

if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE)
{
std::cout << "Coordinates out of bounds. Please try again.\n";
return false;
}

return opponent.getBoard().isHit(x, y);
}
Loading