Розбір коду: Як працює гра хрестики-нулики на C++
Детальний аналіз структури та логіки Tic Tac Toe
Постійна практика під час вивчення комп’ютерного програмування — це невіддільна частина процесу. Не важливо, чи ви лише на початку шляху, чи вже певний час вивчаєте програмування, — цікаві завдання позитивно впливають на результат. Саме тому пропонуємо вам створити просту гру хрестики-нулики на C++.
Чому хрестики-нулики?
У неї прості правила, які легко перекласти на код. Протягом багатьох років цю гру на С++ додають чи не в усі навчальні програми. Вона стала своєрідним стандартом і подібне завдання можуть дати навіть на співбесіді на позицію Trainee або Junior Software Developer.
Практика основних концепцій програмування
Навчальна гра хрестики-нулики на C++ допомагає розібратися з:
- Циклами: перевірка рядків, стовпців і діагоналей для визначення переможця.
- Умовними операторами: логіка перевірки перемоги, нічиєї або некоректного ходу.
- Введенням/виведенням даних: отримання даних від користувача і відтворення результату.
- Масивами/векторами: робота з багатовимірними структурами даних.
Код гри легко протестувати, і обчислення результату займає частку секунди. І що найголовніше — результат написання та відтворення коду (ігрове поле, переможець або черговість ходу) легко побачити й зрозуміти. Це мотивує студентів і дає змогу швидко оцінити свою роботу.
Правила гри
Ми здивуємося, якщо ви не грали хоча б раз у хрестики-нулики бодай на папері або в телефоні. Бо що ж іще робити на нудних уроках у школі? Та все ж таки, якщо вперше чуєте про цю гру, радимо зіграти в хрестики-нулики з Google.
Для цього в будь-якому браузері:
1. Відкрийте Google.com.
2. У рядку пошуку введіть tic tac toe або «хрестики-нулики».
3. Натисніть Enter — і гра з’явиться просто у вікні пошуку.
4. Оберіть бажаний рівень складності для гри з компʼютером або ж варіант гри з другом.
Для гри в хрестики-нулики потрібно 2 учасники. Кожен по черзі ставить лише свій символ (X або O) на ігровому полі розміром 3×3. Завдання гравця — розташувати три однакові символи в ряд, стовпець або по діагоналі. Якщо поле заповнене, а переможця немає, гра закінчується нічиєю.
Покроковий процес створення гри на С++
Для початку сформуємо коротке технічне завдання (ТЗ):
1. Мова програмування C++.
2. Кількість гравців — 2.
3. Інтерфейс — текстовий.
4. Розмір ігрового поля 3×3.
5. Можливість перезапустити гру.
Крок 1: Створення ігрового поля
Ігрове поле можна реалізувати за допомогою двовимірного масиву (або вектора) розміром 3×3. Воно відтворюватиме стан гри та оновлюватиметься після кожного ходу.
Крок 2: Інтерфейс текстового введення
На відміну від гри хрестики-нулики в Google, яка має графічний інтерфейс, у нашому випадку він текстовий. Гравці вводять координати (рядок і стовпець) для свого ходу.
Крок 3: Реалізація правил гри
Обчислення кожного наступного кроку має перевіряти, чи є переможець, нічия або некоректний хід. Як перевірити, чи є введене значення правильним:
- Коректне введення: якщо комірка порожня і не виходить за визначені межі.
- Неправильне введення: якщо комірка вже заповнена іншою літерою або розташована за межами поля.
Крок 4: Зміна гравців
Кожен гравець має символ X або O, і після кожного ходу символ змінюється.
Крок 5: Додавання можливості повторити гру
Як і у випадку з грою хрестики-нулики в Google, після завершення раунду запитати у гравців, чи хочуть вони повторити.
Програмний код гри хрестики-нулики
#include <iostream>
#include <vector>
#include <string>
using namespace std;
// Функція для відтворення ігрового поля
void displayBoard(const vector<vector<char>>& board) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
cout << " " << board[i][j];
if (j < 2) cout << " |";
}
cout << "\n";
if (i < 2) cout << "---+---+---\n";
}
}
// Перевірка переможця
bool checkWin(const vector<vector<char>>& board, char player) {
for (int i = 0; i < 3; i++) {
if ((board[i][0] == player && board[i][1] == player && board[i][2] == player) ||
(board[0][i] == player && board[1][i] == player && board[2][i] == player))
return true;
}
if ((board[0][0] == player && board[1][1] == player && board[2][2] == player) ||
(board[0][2] == player && board[1][1] == player && board[2][0] == player))
return true;
return false;
}
// Основна функція гри
void playGame() {
vector<vector<char>> board(3, vector<char>(3, ' '));
char currentPlayer = 'X';
bool running = true;
while (running) {
displayBoard(board);
cout << "Гравець " << currentPlayer << ", введіть хід (рядок і стовпець): ";
int row, col;
cin >> row >> col;
if (row < 1 || row > 3 || col < 1 || col > 3 || board[row-1][col-1] != ' ') {
cout << "Некоректний хід, спробуйте ще раз!\n";
continue;
}
board[row-1][col-1] = currentPlayer;
if (checkWin(board, currentPlayer)) {
displayBoard(board);
cout << "Гравець " << currentPlayer << " переміг!\n";
running = false;
} else if (count(board.begin(), board.end(), ' ') == 0) {
displayBoard(board);
cout << "Нічия!\n";
running = false;
} else {
currentPlayer = (currentPlayer == 'X') ? 'O' : 'X';
}
}
}
// Головна функція
int main() {
char playAgain;
do {
playGame();
cout << "Хочете зіграти ще раз? (y/n): ";
cin >> playAgain;
} while (playAgain == 'y');
cout << "Дякуємо за гру!";
return 0;
}
Результат
1. Початок гри
Після запуску програми відтворюється порожнє ігрове поле. Гравець, чий хід перший (завжди гравець X), отримує запит на введення координат.
| |
---+---+---
| |
---+---+---
| |
Гравець X, введіть хід (рядок і стовпець):
2. Хід гравця
Гравець вводить координати свого ходу у форматі рядок — стовпець. Наприклад, щоб поставити хрестик у центр, потрібно ввести 2 2.
| |
---+---+---
| |
---+---+---
| |
Гравець X, введіть хід (рядок і стовпець): 2 2
3. Перевірка ходу та оновлення ігрового поля
Програма перевіряє введені координати:
- чи розташовані вони в межах від 1 до 3;
- чи не зайнята обрана клітинка.
Якщо координати правильні, символ гравця стає в обрану клітинку. Ігрове поле оновлюється.
| |
---+---+---
| X |
---+---+---
| |
4. Зміна гравця
Якщо координати некоректні (наприклад, за межами поля або клітинка зайнята), програма виводить повідомлення про помилку, і гравець повинен повторити свій хід. Після успішного ходу гравець змінюється: якщо ходив X, тепер хід O — і навпаки. Так відбувається по колу, допоки не буде визначено переможця або нічию.
5. Перевірка результату
Після кожного кроку гра перевіряє:
- чи є три однакові символи в рядку, стовпці або по діагоналі;
- чи всі клітинки зайняті (для нічиєї).
Приклад 1:
X | | O
---+---+---
| X | O
---+---+---
| | X
Гравець X переміг!
Приклад 2:
X | O | X
---+---+---
X | X | O
---+---+---
O | X | O
Нічия!
6. Повторний запуск гри або завершення
Після завершення гри програма запитує:
Хочете зіграти ще раз? (y/n):
Якщо гравець вводить y, гра починається заново з порожнім полем. Якщо вводить будь-що інше (наприклад, n) — програма завершується з повідомленням:
Дякуємо за гру!
Підсумки
На перший погляд, не потрібно багато знань, щоб створити просту гру на C++. Проте в процесі програмування гри хрестики-нулики ви краще опануєте роботу з масивом або вектором даних, зафіксуєте принципи роботи з циклами, операторами, виведенням даних тощо. До того ж після розробки базової версії можна:
- Збільшити розмір ігрового поля. Наприклад, з 3×3 перейти до 10×10.
- Додати можливість грати проти компʼютера, приєднавши штучний інтелект. Наприклад, алгоритм Minimax.
- Розширити навички роботи з бібліотеками та реалізувати графічний інтерфейс гри.
Якщо зробити задачку складнішою, ви підсилите свої навички програмування на С++.