JavaRush /Java блог /Random UA /Гарвард CS50: завдання третього тижня (лекції 7 та 8), ча...
Masha
41 рівень

Гарвард CS50: завдання третього тижня (лекції 7 та 8), частина 2

Стаття з групи Random UA
Лекції Гарвардського курсу з основ програмування CS50 Додаткові матеріали: асимптотична нотація, алгоритми сортування та пошуку Завдання третього тижня, частина 1. Сортування та пошук.

Гра починається!

Гарвард CS50: завдання третього тижня (лекції 7 та 8), частина 2 - 1 Настав час пограти! Більшість людей знайомі з головоломкою «Пляшки». Якщо формалізувати, «Пляшки» - це двовимірне поле 4х4, у цьому полі розташовані не 16, а 15 квадратиків, тобто один слот залишається порожнім. Кожен із квадратиків пронумерований і може рухатися всередині поля по горизонталі або вертикалі (якщо, звичайно, є куди рухатися). Мета - розмістити числа по порядку, від 1 до 15 зліва направо зверху донизу. Тоді порожнє місце опиниться у правому нижньому кутку. Рух будь-якої плитки (або кількох) є «кроком» у цьому ігровому просторі. Представлена ​​на зображенні вище комбінація вже складена, але зверніть увагу, що плитка 12 або 15 можуть бути зрушені в порожній простір. Правила свідчать, що плитка не може переміщатися по діагоналі або витягуватись із гральної дошки. Насправді конфігурацій для початку гри - багато (можете порахувати, скільки саме), але давайте для простоти розташуємо плитки в порядку від найбільшої до найменшої і залишимо порожній простір у правому нижньому кутку дошки. Єдине, давайте поміняємо місцями 1 і 2, щоб головоломка була розв'язаною. Гарвард CS50: завдання третього тижня (лекції 7 та 8), частина 2 - 2 Тепер перейдіть в директорію ~/ робочого середовища, потім - /pset3/fifteen і відкрийте файл fifteen.c . У ньому - код "движка" гри. Завдання у тому, щоб дописати код гри. Але для початку давайте відкомпілюємо наш двигун (ви напевно вже знаєте, як це зробити). Незважаючи на те, що гра не закінчена, запустити програму можна. Зручніше запустити його у більшому, ніж звичайно, вікні терміналу, яке можна відкрити, натиснувши на зелений плюс (+) поряд з однією із вкладок коду і вибравши New Terminal . Або можна відкрити термінальне вікно на повний екран, клікнувши на іконку Maximize в правому верхньому кутку консолі. Ви бачите, що дещо працює. Але насправді більшість гри ще не написана. І ось тут – приготуйтеся – ваш вихід!
Дослідження
Вивчіть код та коментарі fifteen.c , після чого дайте відповідь на запитання нижче:
  1. Крім дошки 4х4, яку розмірність поля припускає наш двигун?
  2. Якою структурою даних є ігрове поле?
  3. Яка функція викликається для вітання гравця на початку гри?
  4. Які функції необхідно реалізувати?
  5. Примітка: якщо ви хочете, щоб автоперевірка відповіла вам, чи правильно ви відповіли на запитання, поряд із файлом fifteen.c знайдіть файл fifteen.txt і запишіть відповіді на ці запитання.
Реалізація
Що ж, почнемо реалізовувати гру. Пам'ятайте, рухаємося крихітними кроками, не намагайтеся зробити все й одразу. Натомість давайте реалізовувати функції по черзі і переконайтеся, що вони працюють, перш ніж рухатися вперед. Зокрема, ми пропонуємо вам реалізувати функції гри в наступному порядку: init (ініціалізація), draw (промальовування), move (зробити крок), won (виграш). Дизайнерські рішення (наприклад, скільки прогалин потрібно вставляти між нашими плитками-числами) залишаються за вами. Ігрове поле має виглядати приблизно так: 15 14 13 12 11 10 9 8 7 6 5 4 3 1 2 _ Ще раз звертаємо увагу, що у стартовій позиції 1 і 2 розташовані у зворотному порядку (це стосується класичного поля 4х4 якщо кількість плиток - непарна). Якщо кількість плиток парна, а поле — 3х3, міняти дві «молодші» плитки подекуди не потрібно. 8 7 6 5 4 3 2 1 _ Щоб протестувати вашу реалізацію «Плямок», потрібно спробувати пограти в них (не забувайте, аварійний вихід із програми до її природного завершення можна викликати комбінацією клавіш crtl+c). Переконайтеся, що програма буде працювати, якщо введено неправильні числа. І пам'ятайте, що точно так, як ви автоматизували введення в find, ви можете автоматизувати «проходження» гри. Насправді, в папці ~cs50/pset3 є файли 3x3.txt та 4x4.txt , де зібрані всі послідовності кроків для перемоги на полях розмірності 3х3 та 4х4. Щоб протестувати програму, наприклад, за допомогою першого з файлів, виконайте таку команду: ./fifteen 3 < ~cs50/pset3/3x3.txt Налаштуйте потрібний аргумент для прискорення анімації. Та й взагалі, за бажання ви завжди можете змінити гру. Щоб розважатися з "керівними послідовностями ANSI", включаючи колір. Зверніть увагу на нашу реалізацію clear та перевірте http://isthe.com/chongo/tech/comp/ansi_escapes.html щоб засвоїти нові трюки. За бажання напишіть власні функції або поміняйте прототипи функцій, які писали ми. Єдине обмеження – не змінюйте логіку функції main, інакше ми не зможемо застосувати до неї деякі автоматичні тести для підтвердження коректності вашої програми. Зокрема, main повинна повертати 0, у тому й лише тому випадку, якщо користувач склав головоломку. Чи не нульові значення потрібно повернути для всіх варіантів помилок. Якщо виникають помилки, пишіть нам. Ну а якщо захочете пограти з реалізацією програми, підготовленої асистентами CS50, виконайте наступну команду: ~cs50/pset3/fifteen Якщо вам цікаво побачити крутішу реалізацію, з автоматичним рішенням головоломки, перегляньте «Хакерську» версію програми: ~cs50/hacker3/fifteen Замість того, щоб ввести номер у вікні гри, надрукуйте слово GOD. Здорово, чи не так? Якщо хочете перевірити правильність вашої програми офіційно з check50, зверніть увагу, що check50 передбачає, що порожній простір ігрового поля заповнено 0; якщо ви вибрали інше значення, для коректної перевірки замініть його на нуль. Крім того, check50 передбачає, що ви індексуєте поля ігрового поля в порядку [ряд] [стовпець], а не дошка [стовпець] [рядок]. check50 2015.fall.pset3.fifteen fifteen.c
Докладніше про реалізацію функцій гри Fifteen
  • init (ініціалізація)
  • draw (промальовування)
  • move (зробити крок)
  • won (виграш)
init
У цій функції ми представляємо ігрове поле. Для цього використовуємо двовимірний масив цілих чисел. Розмір масива - MAX x MAX, де MAX - константа, що позначає максимальну кількість плиток, які можуть поміститися в рядку або стовпці поля. Таким чином, нам потрібно визначити змінну int board[MAX][MAX] Однак пригадаємо, що розмірність ігрового поля визначає користувач. Тому потрібно визначити змінну, яка позначала б розмірність дошки, яку повинен ввести користувач. Це int d . де d - Розмірність дошки, d <= MAX. Однак у Cі ви не можете змінювати розмір масиву, тому доведеться задовольнятися максимальною розмірністю. У init вам потрібно помістити значення на дошку. Гарвард CS50: завдання третього тижня (лекції 7 та 8), частина 2 - 3 Почитайте більше про двовимірні масиви, якщо ви з ними ще не працювали. Коротко, вони мають два індекси, перший позначає номер рядка, другий — номер стовпця. Для нашого завдання ми починаємо з максимального числа та закінчуємо у випадку d = 3 («Восьм'яшки») одиницею та порожнім кутом. Якщо у нас все-таки «П'ятнашки», тоді 1 та 2 міняємо місцями. Що ж робити із порожнім місцем? Наш масив складається з цілих чисел, тому й порожнеча має бути заповнена якимось цілим. Тому ви повинні вибрати ціле число для ініціалізації порожньої плитки (а у випадку фізичної гри, її відсутність). Щоб ініціалізувати ігрове поле та заповнити його стартовим набором плиток, можна використовувати цикли. Ведемо цикли за індексами i та j, де board[i][j] — плитка, яка знаходиться в рядку номер i та стовпці номер j. Заповнюємо дошку у спадному порядку. Якщо кількість плиток (без порожньої) — непарна, міняємо місцями 1 і 2.
draw
Ця функція має надрукувати поточний стан ігрового поля. Пам'ятаємо, що у нас можуть бути значення з одним або двома розрядами, тому для гарного форматування після чисел 1-9 функція повинна друкувати пробіл ( #s ). Це можна організувати за допомогою плейсхолдера %2d . printf (“%2d”, board[i][j]); Також не забувайте про порожню клітку. Виберіть символ, який представлятиме її (у нашому прикладі — це нижнє підкреслення). Функція draw повинна малювати цей символ, як тільки ви потрапляєте на порожню клітку. Отже, наш цикл буде приблизно таким: for каждой строки for каждого елемента строки print значення и пробел print новую строку Запам'ятайте, що порядок, в якому функція draw виводить на екран плитки, повинен відображати порядок, в якому вони знаходяться в масиві, визначеному функції init .
move
Як тільки ви ініціалізували ігрове поле та намалювали початкові позиції плиток, потрібно дозволити користувачеві редагувати положення плиток, тобто здійснювати рухи. Отже, у Fifteen.c програма приймає висновок від користувача, будує ігрове поле і потім викликає функцію move, і каже, яку плитку він хоче посунути. Будьте уважні: ви застосовуєте функцію саме до номера на плитці, а не до положення на дошці (у масиві). Таким чином, вам потрібно знайти актуальне положення плитки. Крім того, ви повинні дозволити користувачеві посунути плитку лише тоді, коли це можливо. Гарвард CS50: завдання третього тижня (лекції 7 та 8), частина 2 - 4 На зображенні вище ми можемо посунути лише плитки номер 2, 5 та 8. Як це визначити? За значенням пустої плитки. Таким чином, функція move працює приблизно так:
  • Приймає номер плитки, який користувач хоче посунути
  • Шукає положення у масиві (на ігровому полі) цієї плитки
  • Запам'ятовує позицію порожньої плитки
  • Якщо порожня плитка є сусідами з тією, яку користувач хоче посунути, вони змінюються місцями в масиві.
won
Ця функція перевіряє, чи гра завершилася після кожного кроку користувача. Вона повертає true, якщо плитки стоять у правильному порядку (у тому числі і положення порожньої плитки у нижньому правому кутку). У такому разі програму можна завершити. Якщо плитки все ще розкидані, функція повертає false і передає кермо функції move . Як організувати перевірку? Як і у випадку ініціалізації та малювання дошки – за допомогою двох вкладених циклів for. Наприклад, можна поставити умову, що кожне наступне число в масиві має бути більшим за попередній. Зверніть увагу на те, яке значення записано в пустій ​​плитці. Або інший спосіб - використовуйте лічильник, щоб переконатися, що всі плитки на місцях, якщо впораєтеся та напишете формулу, щоб це отримати. Бажаємо удачі в експериментах!

Як підтвердити правильність коду та отримати оцінки

Увага! Якщо вам важливо перевірити тільки правильність завдань, то скористайтеся cs50check. Якщо ж ви ходите отримати оцінки на платформі edx, виконайте процедуру, описану нижче. Майте на увазі, ця процедура для перевірки завдань використовує той же cs50check. Різниця лише в тому, що вона запам'ятовує результати та підраховує загальну оцінку.
  1. Залогіньтесь у CS50 IDE
  2. Поряд з лівим верхнім кутом CS50 IDE там, де розташований її файловий браузер (не в термінальному вікні), клацніть правою клавішею миші по вашій директорії pset3 і натисніть Download . Ви повинні побачити, що браузер завантажив pset3.tar.gz архів .
  3. В окремому вікні або вкладці введіть CS50 Submit
  4. Клацніть по іконці Submit у лівому верхньому кутку екрану
  5. У списку папок зліва клацніть по директорії Problem Set 3 , потім натисніть кнопку Upload New Submission. Вона знаходиться праворуч.
  6. На екрані клікніть по кнопці Add files …. Відкриється вікно вибору файлів із комп'ютера.
  7. Перейдіть до папки, де ви зберегли pset3.tar.gz. Швидше за все, він знаходиться в папці Downloads ("Завантаження") або там, куди ваш браузер складає стандартні файли. Коли знайдете pset3.tar.gz , клацніть по ньому один раз, щоб вибрати, потім клацніть Open («Відкрити»).
  8. Натисніть Start upload . Ваші файли будуть завантажені на сервери CS50 .
  9. На екрані ви повинні побачити вікно No File Selected . Якщо ви переведете курсор миші вліво, ви побачите список файлів, що завантажабося. Для підтвердження клацніть по кожному з них. Якщо ви у чомусь не впевнені, ви можете перезавантажити файли, повторивши ті самі кроки. Ви це можете робити скільки завгодно разів до кінця 2016 року.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ