Курсовая
unknown
c_cpp
a year ago
9.8 kB
2
Indexable
Never
#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; }