Курсовая
unknown
c_cpp
3 years ago
9.8 kB
11
Indexable
#include <iostream>
#include <limits>
#include <string>
using namespace std;
const char PLAYER = 'X';
const char COMPUTER = 'O';
const char EMPTY = '-';
const int max_size = 50;
const int min_size = 3;
void drawBoard(const int fieldSize, char** board) {
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
cout << board[i][j] << ' ';
}
cout << endl;
}
}
bool checkWin(const int fieldSize, char** board, char player) {
int winCount = (fieldSize == 3) ? 3 : 4;
// Перевірка рядків і стовпців
for (int i = 0; i < fieldSize; ++i) {
bool rowWin = true;
bool colWin = true;
for (int j = 0; j < fieldSize; ++j) {
rowWin &= (board[i][j] == player);
colWin &= (board[j][i] == player);
}
if (rowWin || colWin) {
return true;
}
}
// Перевірка діагоналей
bool diagonalWin = true;
bool reverseDiagonalWin = true;
for (int i = 0; i < fieldSize; ++i) {
diagonalWin &= (board[i][i] == player);
reverseDiagonalWin &= (board[i][fieldSize - i - 1] == player);
}
if (diagonalWin || reverseDiagonalWin) {
return true;
}
// Перевірка можливості виграшу на великому полі
if (fieldSize > 3) {
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
bool horizontalWin = true;
bool verticalWin = true;
bool diagonalWin = true;
bool reverseDiagonalWin = true;
// Перевірка горизонтального виграшу
for (int k = 0; k < winCount; ++k) {
if (j + k >= fieldSize || board[i][j + k] != player) {
horizontalWin = false;
break;
}
}
// Перевірка вертикального виграшу
for (int k = 0; k < winCount; ++k) {
if (i + k >= fieldSize || board[i + k][j] != player) {
verticalWin = false;
break;
}
}
// Перевірка виграшу по діагоналі
if (i + winCount <= fieldSize && j + winCount <= fieldSize) {
for (int k = 0; k < winCount; ++k) {
if (board[i + k][j + k] != player) {
diagonalWin = false;
break;
}
}
} else {
diagonalWin = false;
}
// Перевірка зворотного діагонального виграшу
if (i + winCount <= fieldSize && j - winCount + 1 >= 0) {
for (int k = 0; k < winCount; ++k) {
if (board[i + k][j - k] != player) {
reverseDiagonalWin = false;
break;
}
}
} else {
reverseDiagonalWin = false;
}
if (horizontalWin || verticalWin || diagonalWin || reverseDiagonalWin) {
return true;
}
}
}
}
return false;
}
void computerMove(const int fieldSize, char** board, char player) {
char opponent = (player == PLAYER) ? COMPUTER : PLAYER;
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
if (board[i][j] == EMPTY) {
board[i][j] = opponent;
if (checkWin(fieldSize, board, opponent)) {
board[i][j] = COMPUTER;
cout << "Computer move: row " << i + 1 << ", column " << j + 1 << endl;
return;
}
board[i][j] = EMPTY;
}
}
}
// Якщо немає виграшних ходів гравця, перевірити виграшні ходи комп'ютера і зробити хід
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
if (board[i][j] == EMPTY) {
board[i][j] = COMPUTER;
if (checkWin(fieldSize, board, COMPUTER)) {
cout << "Computer move: row " << i + 1 << ", column " << j + 1 << endl;
return;
}
board[i][j] = EMPTY;
}
}
}
// Якщо виграшних ходів не знайдено, зробити хід у центр дошки, якщо він вільний
if (board[fieldSize/2][fieldSize/2] == EMPTY) {
board[fieldSize/2][fieldSize/2] = COMPUTER;
cout << "Computer move: row " << fieldSize/2 + 1 << ", column " << fieldSize/2 + 1 << endl;
return;
}
// Якщо центр недоступний, зробити хід у першу вільну клітину
for (int i = 0; i < fieldSize; ++i) {
for (int j = 0; j < fieldSize; ++j) {
if (board[i][j] == EMPTY) {
board[i][j] = COMPUTER;
cout << "Computer move: row " << i + 1 << ", column " << j + 1 << endl;
return;
}
}
}
}
void printResults(const int result[], int numGames) {
int playerWin = 0;
int computerWin = 0;
int draws = 0;
for (int i = 0; i < numGames; ++i) {
if (result[i] == 1) {
++playerWin;
}
else if (result[i] == -1) {
++computerWin;
}
else {
++draws;
}
}
cout << "Player wins: " << playerWin << endl;
cout << "Computer wins: " << computerWin << endl;
cout << "Draws: " << draws << endl;
}
int main() {
string playerName;
cout << "Enter your name: ";
getline(cin, playerName);
int fieldSize;
while (true) {
cout << "Enter the size of the field (" << min_size << "-" << max_size << "): ";
if (!(cin >> fieldSize) || fieldSize < min_size || fieldSize > max_size) {
cout << "Error. Field size can only be a number " << min_size << "-" << max_size << "!" << endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
} else {
break;
}
}
int numGames = 0;
int result[max_size] = {0};
while (true) {
char** board = new char* [fieldSize];
for (int i = 0; i < fieldSize; ++i) {
board[i] = new char[fieldSize];
for (int j = 0; j < fieldSize; ++j) {
board[i][j] = EMPTY;
}
}
bool playerOneTurn = true;
int moves = fieldSize * fieldSize;
while (moves > 0) {
drawBoard(fieldSize, board);
if (playerOneTurn) {
int row, col;
cout << playerName << ", enter your move in the format 'row column': ";
cin >> row >> col;
// Перетворення координат клітинки в індекс
row -= 1;
col -= 1;
while (cin.fail() || row < 0 || row >= fieldSize || col < 0
|| col >= fieldSize || board[row][col] != EMPTY) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please enter 'row column': ";
cin >> row >> col;
row -= 1;
col -= 1;
}
board[row][col] = PLAYER;
if (checkWin(fieldSize, board, PLAYER)) {
drawBoard(fieldSize, board);
cout << "You won, " << playerName << "!" << endl;
result[numGames] = 1;
++numGames;
break;
}
playerOneTurn = false;
}
else {
computerMove(fieldSize, board, COMPUTER);
if (checkWin(fieldSize, board, COMPUTER)) {
drawBoard(fieldSize, board);
cout << "Computer won!" << endl;
result[numGames] = -1;
++numGames;
break;
}
playerOneTurn = true;
}
--moves;
}
if (moves == 0) {
drawBoard(fieldSize, board);
cout << "Draw!" << endl;
result[numGames] = 0;
++numGames;
}
// Звільнення пам'яті
for (int i = 0; i < fieldSize; ++i) {
delete[] board[i];
}
delete[] board;
// Запитуємо користувача, чи хоче він зіграти знову
string playAgain;
cout << "Do you want to play again? (yes/no): ";
cin >> playAgain;
while (playAgain != "yes" && playAgain != "no") {
cout << "Invalid input. Please enter 'yes' or 'no': ";
cin >> playAgain;
}
if (playAgain == "no") {
break;
}
}
printResults(result, numGames);
return 0;
}Editor is loading...