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 |
* |
|||||||||||
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
~ |
* |
|||||||||||
~ |
~ |
~ |
~ |
* |
* |
~ |
~ |
~ |
~ |
|||||||||||
* |
~ |
* |
~ |
~ |
~ |
~ |
* |
* |
* |
|||||||||||
