На уроці Ігри на Python Експедиція X ми створимо логічну гру про дослідження невідомої території та побудову мапи безпечних і ризикованих зон. У цьому всесвіті поле поділене на сектори, серед яких приховані невідомі аномальні темні області ⬛️. Гравець виступає дослідником, який відкриває клітинки та аналізує дані, щоб не потрапити в небезпечну зону. Безпечні клітинки — це чисті сектори, які поступово формують карту місцевості. Наше завдання — використати логіку й програмування, щоб обстежити всю територію без помилок.

Практика. Ігри на Python Експедиція X
Стережіться! У цій грі головоломці під ігровим полем заховані темні аномалії. Чи зможете ви знайти всі безпечні квадрати і потрапити в чорну пастку ?

Легенда(умовні позначення у грі):
🟦ще не натиснутий
🟩 натиснутий і безпечний (число вказує, скільки аномалій знаходиться навколо цього квадрата)
⬛️ натиснутий і аномалія спрацювала – кінець гри

Створення поля
Щоб намалювати поле, потрібно використати модуль tkinter. Також знадобиться модуль random для розміщення аномалій на полі випадковим чином
1: Для початку імпортуйте бібліотеки tkinter та random.
2: Далі потрібно створити змінні для відстеження виконання гри:
gameOver: буде вказувати комп’ютеру, чи закінчилась гра. Значення на початку: False
score: рахунок, тобто кількість натиснутих квадратів. Значення на початку: 0.
squaresToClear: кількістьбезпечних квадратів, які залишилися.Значення на початку: 0.
3: Тепер визначимо функцію, яка запускається під час гри.

Функції в середині play_expedition_X будуть створені пізніше. Наразі функція лише вказує комп’ютеру, в якому порядку слід їх викликати.
Розміщення аномалій
Щоб комп’ютер запам’ятав, де саме знаходяться аномалії, потрібно використати ґратку з чисел, де 1 – ⬛️ клітинка з аномалією, а 0 – 🟩 безпечна клітинка. Для цього нам знадобиться список, і не простий, а список списків.
Список my_field – зберігає список рядків поля. Кожен рядок, це інший список rowList, який зберігає елементи кожного стовпчика в цьому рядку.
4: Почніть зі створення порожнього списку my_field у розділі глобальних змінних на початку програми. Та потім створіть функцію create_field для заповнення списку. Та сама функція буде потрібна для оновлення значення кількості безпечних квадратів, які залишилися


5: Тепер визначимо саму функцію. Спочатку використайте цикл for для створення 10-ти порожніх списків (рядків). Потім додайте ще один цикл for для заповнення кожного зі списків значенням 1 і 0. Для розміщення 2 та 0 використаємо генератор випадкових чисел.

6: Для перевірки правильності роботи коду варто додати функцію printField(my_field) в кінець функції створення поля create_field()
7: Далі визначаємо функцію відображенні інформації в списках (на фото 6 і 7 завдання разом)

8: Додайте виклик функції запуску гри. Зауважте, що це має бути останній рядок програми, тобто увесь інший код має бути перед цим рядок. Слідкуйте за цим впродовж написання гри.

Збережіть й запустіть ваш код. Програма має вивести мапу нашої планети з безпечними зонами 0 і аномаліями 1. Далі програма поки що показує помилку про те, що функція layout_window не визначена. Ми виправимо це в наступних кроках.

Розфарбовуємо поле
9: Тепер потрібно розмістити клітинки у вікні за допомогою визначення функції layout_window(). Почніть з вказівки комп’ютеру переглянути кожний елемент списків, використовуючи цикли for і функцію enumerate()

Функція enumerate() проходить кожен елемент списку, повертаючи індекс і елемент списку.
10: А тепер створімо функцію для випадкового вибору кольору кожної з клітинок. Також потрібно за допомогою інструкції tkinter.Label додати порожні мітки для створення клітинок. Допишіть умовув середину циклів, які створили в минулому завданні.
Замініть фіолетові рядки на відповідний ним код.
# якщо випадкове число менше ніж 25,
if random.randint(1,100) < 25:
# то клітинка матиме колір royalblue
square=tkinter.Label(window, text=" ", bg="royalblue")
# якщо випадкове число більше ніж 75,
# то клітинка матиме колір skyblue
# інакше
# то клітинка буде матиме MediumSlateBlue
square.grid (row=rowNumber, column=columnNumber) tkinter.Label створює прямокутник мітки для кожної з клітинок
text=” ” – чотири пробіли між лапками зададуть ширину кожної клітинки.
window – з’єднає клітинку з вікном tkinter-а яке було створено раніше.
Палітру кольорів можна глянути тут і обрати ті, які сподобаються. Назву пишемо назву кольору у одне слово або використайте шістнадцятковий код (наприклад #F5FFFA)
11: Тепер потрібно вказати комп’ютеру відображати кожен з квадратиків у вигляді ґратка у вікні модуля tkinter. Для цього використаймо функцію grid. Зверніть увагу, що цей рядок знаходиться в середині функції й обох циклів, але не в середині умови. Самостійно розрахуйте на якій відстані зліва його варто розташувати.
square.grid (row=rowNumber, column=columnNumber) square.grid – символ . означає. що функція grid(), яка розташована за крапкою, належить клітинці.
Функція grid маю багато вбудованих параметрів, але вам знадобляться лише row (рядок) і column (стовпчик)
Перший запуск
12: Перевірте, чи все працює, для чого збережіть і запустіть програму. Переконайтеся, що play_expedition_X() рядок знаходиться у кінці вашого коду.
Ви побачите вікно, як на малюнку.Під час кожного запуску, поле буде змінюватися, бо клітинки мають випадкові кольори.
Подумайте, чому рядок play_expedition_X() має бути в самому кінці?

🐞 🐛 🦟 🪲 Баги. Якщо в програмі є помилки. Не переймайтеся, якщо отримати кілька помилок, поверніться до минулих кроків і спробуйте розібратися, що працює не вірно. В помилці завжди вказується номер рядка, це допоможе вам знайти проблемне місце.
Рядок, на який вказує комп’ютер не зажди вірний, помилка іноді може знаходитися на рядок вище, але через відсутність коли чи дужки комп’ютер буде вказувати на проблему в +1 рядку.
13: Також при запуску зараз з’являється карта розташування аномалій у вигляді 0 та 1. Якщо поле відображається без помилок, то можна цю підказку відключити, закоментувавши printField(my_field)
[0, 0, 0, 1, 0, 1, 1, 0, 0, 0]
[0, 0, 0, 1, 0, 1, 0, 0, 1, 0]
[1, 0, 1, 0, 1, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
[1, 0, 1, 0, 1, 0, 0, 0, 0, 0]
[0, 1, 0, 0, 0, 0, 1, 1, 1, 1]
[0, 0, 1, 0, 0, 1, 0, 1, 1, 0]
[0, 0, 0, 0, 0, 0, 1, 0, 1, 0]Реагування на кліки
Після створення поля з аномаліями, потрібно створити код реагування на кліки користувача по клітинках за допомогою події. Модуль tkinter має спеціальні команди для розрізнення різних типів подій.
14: Ми перетворимо кожну клітинку на кнопку <Button1> і вкажемо комп’ютеру, що треба реагувати на лівий клік мишки, тобто на натиснення кнопки. Це можна зробити, якщо додати ще один рядок під рядком з кроку 11 (який розміщую клітинки). Новий рядок виділений блакитним:

Функція bind() зв’язує подію(клік мишкою по клітинці) і відповідь комп’ютера (нова функція on_click(), яку опишемо в наступних кроках.). Тобто при кожному кліку на клітинку, запускатиметься функція on_click()
15: Остання функція повинна вказати комп’ютеру, що робити при кліці на клітинку. Створіть нову функцію on_click() з параметром event, який вона автоматично отримає при виклику.
Визначте глобальні змінні (вкажіть global) в середині функції, щоб вона могла з ними працювати: score, gameOver, squaresToClear
def on_click(event): # event буде посилатися на подію кліка на клітинку16: По-перше, потрібно переконатися, що комп’ютер знає, за якою саме клітинкою слідкувати. Для цього знадобиться слово widget, воно визначає об’єкт, на якому виникає подія, тобто клік у нашому випадку. Потім треба визначити позицію клітинки у сітці (її адресу, тобто рядок і стовпчик)

17: Далі комп’ютер має перевірити текстову мітку клітинки (навіть, якщо там просто пропуски). Для цього знадобиться нова функція cget(“text”) – шукає вже наявний текст

18: Тепер треба перевірити, чи є у клітинці аномалія, і вказати комп’ютеру, що робити, якщо її знайдено.

19: Після цього вкажіть комп’ютеру, що робити, якщо клітинка безпечна. По-перше, потрібно перевірити, чи була клітинка вже натиснута. Якщо не була, нам потрібно змінити її колірна зелений і відобразити кількість аномалій навколо цієї клітинки.

22. Ігри на Python Експедиція X
20: Щоб визначити кількість аномалій навколо клітинки, потрібно перевірити усі 8 сусідніх клітинок. Почнімо з клітинки знизу:


Потім перевіримо клітинку вище


Потім перевіримо клітинку зліва. Допишіть код самостійно.
Підказка: column > 0 та [row][column-1]

Допишіть код для перевірки клітинки справа

Допишіть код для перевірки клітинки у верхньому лівому кутку.
Підказка: row >0 and column > 0:
та [row-1][column-1]

Допишіть код для перевірки клітинки у нижньому лівому кутку.

Допишіть код для перевірки клітинки у верхньому правому кутку.

Допишіть код для перевірки клітинки у нижньому правому кутку.

Завершуємо гру
21: Після перевірки всіх навколишніх клітинок на наявність аномалій можна відобразити отримане значення, додаючи мітку до клітинки

22: Щоб відстежувати значення рахунку гравця, збільште score на 1 і зменште squaresToClear на 1.
23: Якщо ви знайшли УСІ безпечні клітинки, гра повинна закінчитися перемогою.

24: Перевірте, що останнім рядком програми все ще залишається play_expedition_X(). Запустіть гру. Для початку протестуйте з відображенням відповідей, щоб перевірити, що програма правильно рахує аномалії

25: Якщо програма рахує не вірно, перевірте логіку клітинок:

26: Нумо грати!


Домашня робота
1: Закінчіть гру до кінця і протестуйте, що все працює правильно.
2: Перефарбуйте поле, аномалії та перевірені клітини в інші кольори. Палітру кольорів можна глянути тут. Назву пишемо разом, малими літерами.
3: Зробіть поле 30 на 30 і змініть гру для такого поля. Винесіть розміри поля у глобальну змінну. Не забудьте відредагувати також перевірки клітинок!

Level Up!
Ігри на Python Експедиція X
1: Зробіть 3 рівні гри: новачок, досвідчений, геймер. І три види поля: маленьке, середнє і велике. Користувач перед початком гри в консолі вводить свій рівень і вид поля, і гра стартує з цими даними.
Опис рівнів:
- новачок: кількість аномалій МЕНШЕ, ніж у прикладі, який описаний в уроці
- досвідчений: кількість аномалій, ТАКА Ж, як у прикладі, який описаний в уроці
- геймер: кількість аномалій БІЛЬШЕ, ніж у прикладі, який описаний в уроці
Види полів:
маленьке: 10 на 10
середнє: 30 на 30
велике: 50 на 50
2: Зробить В кінці гри програма запитує ім’я гравця і записує його результат у файл (створіть файл в тій же папці, де знаходиться гра).
Не зупиняйтесь у вивченні Python! До зустрічі на наступних уроках!
