
ЗМІСТ
ВСТУП 2
1 ПОСТАНОВКА ЗАДАЧІ 5
2 МАТЕМАТИЧНІ ТА АЛГОРИТМІЧНІ ОСНОВИ РІШЕННЯ ЗАДАЧІ 7
3 ПРОГРАМНА РЕАЛІЗАЦІЯ РІШЕННЯ ЗАДАЧІ 12
4 ПРИКЛАД ВИКОНАННЯ ПРОГРАМИ 66
ВИСНОВОК 69
СПИСОК ВИКОРИСТАНИХ ДЖЕРЕЛ ТА ЛІТЕРАТУРИ 70
ВСТУП
Гра «морський бій» досить добре відома і популярна. Практично кожен школяр у той чи інший період свого життя грав у цю гру. В останні роки у зв'язку з появою комп'ютерів і нових навчальних і розвиваючих програм знову зріс інтерес до неї. Якщо набрати запит про пошук ігри в Інтернет, то пошукова машина видасть кілька тисяч посилань. Тут і реклама, і різні варіанти гри, і якісні дослідження оптимальних стратегій гри і т.д. Але мало хто знає про те, що ця гра має серйозне наукове і практичне додаток, і для її аналізу можуть бути використані сучасні математичні та комп'ютерні методи. Як приклад такого додатка можна навести проблему ефективного пошуку записів у великих базах даних, що володіють складною багаторівневою структурою.
Зупинимося на деяких основних правилах класичного варіанту гри. Перший гравець, гравець А, розставляє кораблі на квадратному ігровому полі з n клітин (зазвичай це поле клітин). Кораблі діляться на класи: одноклітинні, двохклітинні, трьохклітинні і чотирьохклітинні. Гравець В на своєму полі розставляє свої кораблі. Зауважимо, що кораблі не повинні торкатися один одного. Гра полягає в тому, що гравці по черзі називають координати клітин, в яких, як вони припускають, розташовані кораблі супротивника, тобто як би роблять постріл з обраної клітці. Про попадання або промаху гравцеві повідомляється після пострілу. Гра продовжується до тих пір, поки у одного з гравців не будуть знищені всі кораблі.
На перший погляд, ця гра носить чисто імовірнісний характер, так як гравці ведуть обстріл, не знаючи розташування кораблів супротивника. Але, придбавши деякий досвід гри, можна помітити, що існують стратегії розстановки кораблів, які зменшують вірогідність попадання в останній одноклітинний корабель. Наприклад, можна розташувати весь флот таким чином, щоб він займав мінімальне місце на ігровому полі, а один або два кораблі ставлять на просторі, що залишився як на малюнку 1. Пошук кораблів також можна проводити, дотримуючись певної системи, яка дозволяє найбільш швидко виявити на початку гри багатоклітинні кораблі, а потім на просторі, що залишився шукати одноклітинні кораблі.
Рисунок 1
Ці якісні міркування показують, що у гравців А і В існує безліч нерівнозначних різних стратегій гри, тобто може бути поставлене питання про пошук оптимальних стратегій.
Зауважимо, що все це розмаїття стратегій, як це буде показано нижче, визначається правилом, що забороняє ставити кораблі впритул, а також правилом закінчення гри.
Надалі будемо розглядати тільки односторонню гру: гравець А розставляє кораблі , а гравець В веде їх пошук .
Математичну модель гри можна будувати двома способами. Перший спосіб полягає в тому, що після кожного пострілу враховуються зміни поля гри та ймовірності виявлення кораблів. Така форма гри називається розгорнутою, а сама гра представляється багатокроковою. Складність застосування цього підходу пов'язана з необхідністю визначення ймовірностей подій, які є комбінацією великого числа елементарних подій. При збільшенні числа пострілів k кількість комбінацій зростає пропорційно k! (факторіалів k).
Другий спосіб полягає в тому, що в якості вихідної безлічі подій розглядається безліч стратегій, елементи яких представляють повну послідовність n пострілів. У цьому випадку гра стає однокрокової, тобто гравець проводить вибір не однієї клітини при пострілі, а вибирає послідовність з n пострілів. Така форма гри називається нормальною. Другий підхід до побудови гри носить інтегральний характер, проте, в цьому випадку виникає проблема, пов'язана з поняттям закінчення гри.
1 Постановка задачі
Завдання полягає в розробці алгоритму, за яким комп'ютер зможе грати в «Морський бій» з максимальною якістю, і при цьому не підглядаючи до розташування флоту гравця.
Додаткова і очевидна умова: при кожній новій грі незалежно від розміщення сил противника комп'ютер повинен грати по-різному, тобто його ходи повинні бути не передбачувані.
Необхідно згадати правила гри: учасники поєдинку роблять ходи по черзі, причому, якщо один з гравців потрапляє по кораблю суперника, то він отримує право наступного ходу. Якщо реалізувати пошук цілі комп'ютером у вигляді окремої процедури, то треба якось навчити його запам'ятовувати результати минулих пострілів, щоб адекватно провести наступний. З цього факту випливає, що саме просте і раціональне рішення даної проблеми можна оформити у вигляді кінцевого автомата, найбільш точно описує послідовність дій.
Можна виділити три стани:
1) простріл ігрового поля по випадкових координатах до влучення по кораблю, після чого перехід в другий стан;
2) обстріл навколо підбитиго осередку поля для визначення напрямку корабля (вертикальне чи горизонтальне), після чергового попадання - перехід в третій стан;
3) розстріл корабля в отриманому напрямку до повного його знищення, після чого перехід в перший стан.
І так, вся гра зациклена на трьох основних діях: простріл, обстріл і розстріл. Всі ці дії мають продовжуватися до тих пір, поки в однієї зі сторін не будуть знищені всі кораблі.
Простріл.
На цьому етапі комп'ютер повинен зловити будь-який з кораблів противника. Для цього він буде стріляти по довільним незайнятим клітинам поля гравця. Набагато ефективніше спочатку розправитися з великими кораблями, тому вибираючи координати для пострілу треба перевіряти, щоб у цій позиції міг розміститися найбільший з решти кораблів. Процес припиняється, як тільки відбудеться влучання. Позначимо підбиту частину корабля значенням «*», а промах «~» відповідної комірки поля. Якщо у гравця залишилися тільки однопалубні кораблі, то цим попаданням корабель знищено повністю і обстрілювати її немає сенсу. В іншому випадку треба перейти до другого стану.
Обстріл.
На цьому кроці завдання полягає у визначенні напрямку спійманого корабля. Для цього треба обстріляти чотири осередки (якщо вони вільні), які можуть служити продовженням. У разі, коли всі чотири клітини обстріляні, а попадання не відбулося (однопалубний корабель), треба перейти до першого стану. Якщо в якийсь момент вдалося підбити ще одну палубу противника, то можна переходить до розстрілу даного корабля, так як його напрям стало відомо. Аналогічно першому стану, якщо у гравця залишилися кораблі не більше двох палуб, то цим попаданням корабель знищений повністю і треба повернутися до прострілу.
Розстріл.
На попередньому кроці вдалося встановити в якому напрямку розміщений спійманий корабель. Тепер завдання полягає в його повному знищенні. Для цього треба стріляти праворуч або ліворуч (зверху чи знизу) підбитих палуб, поки не доб'ємо його цілком, після чого повернемося в стан прострілу. При цьому слід враховувати максимально можливий корабель і намагатися потрапити по четвертій палубі, коли чотирьох палубний корабель знищений, немає ніякого сенсу.
Приклад
Поле кораблів
1 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
Стратегія гри комп’ютера.
Вибираємо випадкову клітинку, роздивляється її значення.
Якщо значення = 1 – попали в корабель, відмічаємо удар «*»;
Якщо значення = 0 – не попали, відмічаємо удар «~»;
Якщо значення = «*» або значення = «~», значить в цю клітинку ми вже зробили удар, повертаємося до кроку 1.
Після того як всі кораблі розбиті, завершуємо бій. Поле розбитих кораблів
* |
* |
* |
* |
~ |
~ |
* |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
* |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
* |
~ |
* |
~ |
~ |
~ |
* |
~ |
~ |
~ |
* |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
0 |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
* |
~ |
~ |
~ |
~ |
~ |
0 |
* |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
* |
~ |
~ |
~ |
~ |
* |
* |
~ |
~ |
~ |
~ |
* |
~ |
* |
~ |
~ |
~ |
~ |
* |
* |
* |
Нулями позначені ті клітини, в які ми не потрапили.