Created
January 16, 2026 11:27
-
-
Save ExtremeFine21/83bf1c32a1a95409e5ef8b0be3d9f673 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #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