Skip to content

Instantly share code, notes, and snippets.

@ExtremeFine21
Created January 16, 2026 11:27
Show Gist options
  • Select an option

  • Save ExtremeFine21/83bf1c32a1a95409e5ef8b0be3d9f673 to your computer and use it in GitHub Desktop.

Select an option

Save ExtremeFine21/83bf1c32a1a95409e5ef8b0be3d9f673 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cctype>
#include <string>
using namespace std;
const int SIZE = 10;
const char EMPTY = '.';
const char SHIP = 'S';
const char HIT = 'x';
const char MISS = 'o';
struct Player {
string name;
bool isHuman;
int shipsAlive;
char field[SIZE][SIZE];
char enemyView[SIZE][SIZE];
};
void initField(char f[SIZE][SIZE]) {
for (int i = 0; i < SIZE; ++i)
for (int j = 0; j < SIZE; ++j)
f[i][j] = EMPTY;
}
void printField(char f[SIZE][SIZE]) {
cout << " ";
for (int i = 0; i < SIZE; ++i) cout << char('A' + i) << ' ';
cout << '\n';
for (int i = 0; i < SIZE; ++i) {
cout << i + 1 << (i < 9 ? " " : " ");
for (int j = 0; j < SIZE; ++j)
cout << f[i][j] << ' ';
cout << '\n';
}
}
bool isValidPlacement(char field[SIZE][SIZE], int r, int c, int len, bool hor) {
for (int i = 0; i < len; ++i) {
int rr = r + (!hor) * i;
int cc = c + hor * i;
if (field[rr][cc] != EMPTY) return false;
}
return true;
}
void placeShips(Player& p) {
int ships[4] = {4,3,2,1};
int counts[4]= {1,2,3,4};
for (int t = 0; t < 4; ++t)
for (int i = 0; i < counts[t]; ++i) {
bool placed = false;
while (!placed) {
int r, c;
bool hor;
if (p.isHuman) {
printField(p.field);
cout << "Ship size " << ships[t] << " (A5 H/V): ";
char pos[10], dir;
cin >> pos >> dir;
r = atoi(pos + 1) - 1;
c = toupper(pos[0]) - 'A';
hor = (toupper(dir) == 'H');
} else {
r = rand() % SIZE;
c = rand() % SIZE;
hor = rand() % 2;
}
if (r < 0 || c < 0) continue;
if ((hor && c + ships[t] > SIZE) || (!hor && r + ships[t] > SIZE)) continue;
if (!isValidPlacement(p.field, r, c, ships[t], hor)) continue;
for (int k = 0; k < ships[t]; ++k)
p.field[r + (!hor)*k][c + hor*k] = SHIP;
placed = true;
}
}
p.shipsAlive = 10;
}
bool isShipSunk(char f[SIZE][SIZE], int r, int c) {
int dx[4]={-1,1,0,0}, dy[4]={0,0,-1,1};
for (int d = 0; d < 4; ++d) {
int rr = r + dx[d], cc = c + dy[d];
if (rr>=0&&rr<SIZE&&cc>=0&&cc<SIZE && f[rr][cc]==SHIP)
return false;
}
return true;
}
bool makeShot(Player& s, Player& t, int r, int c) {
if (t.field[r][c] == SHIP) {
t.field[r][c] = HIT;
s.enemyView[r][c] = HIT;
if (isShipSunk(t.field, r, c)) {
t.shipsAlive--;
cout << "Sunk!\n";
} else {
cout << "Hit!\n";
}
return true;
}
if (t.field[r][c] == EMPTY) {
t.field[r][c] = MISS;
s.enemyView[r][c] = MISS;
cout << "Miss!\n";
}
return false;
}
void smartShot(Player& s, int& r, int& c) {
do {
r = rand() % SIZE;
c = rand() % SIZE;
} while (s.enemyView[r][c] != EMPTY);
}
bool getCoords(int& r, int& c) {
char in[10];
cin >> in;
c = toupper(in[0]) - 'A';
r = atoi(in + 1) - 1;
return (r>=0 && r<SIZE && c>=0 && c<SIZE);
}
void playGame(Player& p1, Player& p2) {
bool turn = rand() % 2;
while (p1.shipsAlive > 0 && p2.shipsAlive > 0) {
Player& cur = turn ? p1 : p2;
Player& tar = turn ? p2 : p1;
cout << "\nTurn: " << cur.name << '\n';
printField(cur.enemyView);
int r, c;
if (cur.isHuman) {
if (!getCoords(r, c)) continue;
} else {
smartShot(cur, r, c);
}
if (!makeShot(cur, tar, r, c))
turn = !turn;
}
cout << "\nWinner: " << (p1.shipsAlive ? p1.name : p2.name) << '\n';
}
int main() {
srand(time(0));
Player p1{"Player", true, 0};
Player p2{"Computer", false, 0};
initField(p1.field);
initField(p1.enemyView);
initField(p2.field);
initField(p2.enemyView);
placeShips(p1);
placeShips(p2);
playGame(p1, p2);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment