Створення гри хрестики нуліки. Теоретичні основи розробки

Вітаю вас любі друзі! У цьому уроці я покажу, як можна зробити браузерну гру - хрестики нуліки, на javascript! Всі ви знаєте, що це за гра і як у неї грати, але ще раз нагадаю:

Хрестики-нуліки - це логічна гра між двома гравцями на квадратному полі 3 на 3 клітинки (можливо і більшого розміру). Один грає «хрестиками», а другий – «нуликами».

P.S. як і у всіх подібних уроках javascript , в кінці статті ви можете завантажити вихідний файл, а також подивитися результат роботи на demo прикладі!

Опис гри

Давайте розглянемо особливості гри:

  • гра починається відразу після завантаження сторінки;
  • право ходити першим вибирається випадковим чином (або починаєте ходити, або комп'ютер);
  • знак, який ви ставитимете, вибирається випадковим чином (хрестик або нулик);
  • якщо виграє гравець, то переможні символи (смуга хрестиків чи нуліків) виділяються зеленим кольором;
  • якщо гравець програє комп'ютер, то смуга виділяється червоним кольором;
  • над полем є рядок інформації, де виводиться результат (перемога чи поразка).

Логіка

Я не став вигадувати складних (універсальних) алгоритмів для ігрового поля 3 на 3 клітинки, я пішов іншим шляхом – перебором! (Про це трохи пізніше). Я виділив три основні послідовні етапи, на яких і тримається вся логіка:

1 етап: перевіряємо – чи переміг гравець?

На цьому етапі ми перевіряємо, чи є 3 клітини (на одній лінії), заповнені однаковими символами граючого (хрестиками чи нулями). Тобто. незважаючи на те, який цей хід (хай навіть перший) ми завжди спочатку перевіряємо - чи виграв гравець. Ось так виглядає перемога:

2 етап: перевіряємо – чи може комп'ютер перемогти наступним ходом?

На цьому етапі ми шукаємо лінію, де були б 2 клітинки заповнені комп'ютером та одна порожня клітина – тобто намагаємося виграти за рахунок неуважності гравця. Ось так виглядає поразка (тобто перемога комп'ютера):

3 етап: не даємо виграти!

Тут ми шукаємо таку ж лінію, як і на другому етапі, тільки 2 клітинки мають бути заповнені ігровими знаками гравця, тобто на цьому етапі не даємо програти комп'ютеру, поставивши знак у порожню клітинку. Кожен з етапів є самостійною функцією - це ви можете побачити в js коді нижче.

Реалізація

Розмітка ігрового поля дуже проста - в основному блоці розміщено рядок інформації (клас - result) і 9 блоків, що є клітинами (клас - block) HTML розмітка клітин:

Ваш хід!

Допоміжний клас cell необхідний, щоб точно ідентифікувати потрібну клітинку на ігровому полі. CSS стилі для ігрового поля:

Krestiki_noliki( width: 306px; margin: 0 auto; ) .krestiki_noliki .block( width: 100px; height: 100px; border: 1px solid #ccc; 100px, line-height: 94px;

Тепер давайте розглянемо весь JS код, після чого я розповім про основні моменти:

$(document).ready(function()( var znak_user = "O"; var znak_comp = "X"; var rand_num = Math.round((Math.random() * (9 - 1) + 1))); if (rand_num > 3)( var znak_comp = "O"; var znak_user = "X"; $(".cell"+rand_num).text(znak_comp); ) var exit_flag = false; var win_user_array = ["123"," 456","789","147","258","369","159","357"]; // Визначаємо перемогу гравця function check_3_user(znak)( for (var i = 0; i< 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first+",."+second+",."+third).css("background-color", "#83e2c3"); $(".result").text("Вы выиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем возможность победы компьютера function check_2_comp(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == "" && exit_flag == false){ $("."+third).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak && exit_flag == false){ $("."+second).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak && exit_flag == false){ $("."+first).text(znak); $("."+first+",."+second+",."+third).css("background-color", "#EF7C7C"); $(".result").text("Вы проиграли!"); $(".krestiki_noliki .block").unbind("click"); exit_flag = true; } } } //Определяем ход компьютера function check_2_user(znak){ for (var i = 0; i < 8; i++) { var first = "cell" + win_user_array[i].substr(0,1); var second = "cell" + win_user_array[i].substr(1,1); var third = "cell" + win_user_array[i].substr(2,1); if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == znak && $("."+third).text() == ""){ $("."+third).text(znak_comp); exit_flag = true; } } if(exit_flag == false){ if($("."+first).text() == znak && $("."+second).text() == "" && $("."+third).text() == znak){ $("."+second).text(znak_comp); exit_flag = true; } } if($("."+first).text() == "" && $("."+second).text() == znak && $("."+third).text() == znak){ $("."+first).text(znak_comp); exit_flag = true; } if(exit_flag) break; } } $(".krestiki_noliki .block").click(function(){ //Если клетка пустая if($(this).text() == ""){ $(this).text(znak_user); check_3_user(znak_user); check_2_comp(znak_comp); check_2_user(znak_user); if(exit_flag == false){ for (var i = 1; i < 10; i++) { if($(".cell"+i).text() == ""){ $(".cell"+i).text(znak_comp); break; } } }else exit_flag = false; } }); });

Спочатку ми оголошуємо змінні: znak_user - у цій змінній ми зберігаємо знак, яким гратиме користувач (за замовчуванням там зберігається нолік - це англійська будка "О"). znak_comp - у цій змінній ми зберігаємо знак, яким гратиме комп'ютер (за умовчанням там зберігається хрестик - це англійська будка "ікс").

Логіка така: якщо випадкове число більше 3, то комп'ютер грає нуліками, і він (комп'ютер) робить перший хід.

Ви можете змінити цю логіку так, як вам зручно, наприклад, можна створити кілька випадкових цифр, щоб зробити більше варіантів того, хто буде хоч першим і якими знаками. exit_flag - цей прапор (змінна) відповідає за вихід із функції, тобто, наприклад, коли комп'ютер вже зробив свій хід, і потрібно вийти з функції та передати хід гравцеві. win_user_array – у цьому масиві зберігаються всі переможні варіанти заповнення клітин. Щоб стало зрозуміло, погляньмо ось на цю картинку:

Кожен елемент масиву - це рядок із трьох цифр, що є виграшною комбінацією, тобто, наприклад, якщо заповнити клітини під цифрами 1, 2 та 3, то настане перемога (або поразка). Як бачите, всього є 8 переможних варіантів, наше завдання - перебрати всі ці варіанти. Далі йдуть 3 функції:

  1. check_3_user();
  2. check_2_comp();
  3. check_2_user();

Призначення цих функцій описано у вигляді трьох етапів у розділі Логіка (вище). Ці функції викликаються на кліку на будь-яку з клітин поля. У кожну з функцій передається параметр (znak) - це знак гравця або комп'ютера (хрестик або нулик), наприклад, у функцію, що визначає перемогу гравця (check_3_user), ми передаємо знак гравця для того, щоб знайти 3 однакових знаки на одній лінії.

Після трьох функцій (якщо комп'ютер ще не зробив хід), комп'ютер заповнюємо одну із вільних клітин. Тут ви можете ускладнити ігровий процес, наприклад, зробивши так, що якщо вільна центральна клітина (клітина під номером 5), то спочатку ставити в неї, якщо вона зайнята, то ставити в один із вільних кутів (це клітини № 1, 3, 7 і 9) і так далі - загалом, тут вже на вашу думку.

Ось, в принципі, і все, що потрібно для створення подібної гри.

Тепер можете подивитися гру на демо прикладі та завантажити вихідний файл (всього 1 файл).

08.06.2018 - дякую за уважність автору листа: Patvakan Baghdasaryan, виправлена ​​помилка, коли комп'ютер мав кілька можливих варіантівперемоги і зафарбовувалися всі його переможні ходи (від 4 до 6 клітин, замість 3).

На цьому у мене все, сподіваюся, цей урок був корисний для вас, бажаю вам удачі, поки що!

Як написати бота, якого не можна буде обіграти в «хрестики-нуліки», або Знайомство з правилом «мінімакс»

Цілком можливо, що після сотень партій у «хрестики-нуліки» ви замислювалися: який оптимальний алгоритм? Але якщо ви тут, то ви, напевно, ще й пробували написати реалізацію цієї гри. Ми підемо далі і напишемо бота, який неможливо буде обіграти в «хрестики-нуліки». Передбачивши ваше запитання «чому?», відповімо: завдяки алгоритму .

Як і професійний шахіст, цей алгоритм прораховує дії суперника на кілька ходів уперед - доти, доки не досягне кінця партії, чи то перемога, поразка чи нічия. Потрапивши в цей кінцевий стан, ІІ нарахує собі позитивну кількість очок (у нашому випадку +10) за перемогу, негативне (-10) – за поразку, та нейтральне (0) – за нічию.

У той самий час алгоритм проводить аналогічні розрахунки для ходів гравця. Він вибиратиме хід з найвищим балом, якщо ходить ІІ, і хід із найменшим, якщо ходить гравець. Використовуючи таку стратегію, мінімакс уникає поразки.

Спробуйте зіграти ось у таку гру.

Алгоритм «мінімакс» найпростіше описати у вигляді рекурсивної функції, яка:

  1. повертає значення, якщо знайдено кінцевий стан (+10, 0, -10),
  2. проходить по всіх порожніх клітинах на полі,
  3. викликає мінімакс-функцію для кожної з них (рекурсія),
  4. оцінює отримані значення
  5. і повертає найкраще їх.

Якщо ви не знайомі з рекурсією, то варто подивитися цю лекцію з гарвардського курсу CS50:

Щоб розібратися в тому, як влаштований мінімакс, напишемо його реалізацію і змоделюємо його поведінку. Займемося цим у двох наступних розділах.

Реалізація мінімаксу

Ми розглянемо ситуацію, коли гра добігає кінця (дивіться картинку нижче). Оскільки мінімакс проходить по всіх можливих станах гри (а їх сотні тисяч), має сенс розглядати ендшпіль - так нам доведеться відстежувати меншу кількість рекурсивних викликів функції (всього 9).

Нехай ІІ грає хрестиками, людина – нуліками.

Щоб спростити роботу з полем, оголосимо його як масив із 9 елементів зі значеннями, рівними вмісту клітин. Заповнимо його хрестиками і нуліками, як на картинці вище, і назвемо origBoard.

Var origBoard = ["O",1,"X","X",4,"X",6,"O","O"];

Потім оголосимо змінні aiPlayer і huPlayer і надамо їм значення "X" і "O" відповідно.

Крім того, нам потрібна функція, яка шукає переможні комбінації та повертає справжнє значення у разі успішного пошуку, та функція, яка зберігає індекси доступних клітин.

/* початковий стандошки O | | X --------- X | | X --------- | O | O * / var origBoard = [ "O", 1, "X", "X", 4, "X", 6, "O", "O"]; // людина var huPlayer = "O"; // ІІ var aiPlayer = "X"; // повертає список індексів порожніх клітин дошки function emptyIndices(board)( return board.filter(s => s != "O" && s != "X"); ) // переможні комбінації з урахуванням індексів function winning(board, player)( if((board == player && board == player && board == player) || (board == player && board == player && board == player) || (board == player && board == (board == player && board == player &| board == player && board == player) || (board == player &&board == player &&board == player) || (board == player && board == player && board == player) || (board == player && board == player && board == player)) ( return true;) else (return false;))

Отже, давайте визначимо мінімакс-функцію з двома аргументами: newBoard (нове поле) та player (гравець). Потім знайдемо індекси вільних клітин на полі і передамо їх у змінну availSpots.

// основна мінімакс-функція function minimax(newBoard, player)( //доступні клітини var availSpots = emptyIndices(newBoard);

Крім того, нам потрібно відстежувати кінцеві стани та повертати відповідні значення. Якщо перемагає «нулик», потрібно повернути -10, якщо «хрестик» - +10. Якщо розмір масиву availSpots дорівнює нулю, значить, вільних клітин немає, гра закінчиться нічиєю, і потрібно повернути нуль.

// перевірка на термінальний стан (перемога / поразка / нічия) //and returning a value accordingly if (winning(newBoard, huPlayer))( return (score:-10); ) else if (winning(newBoard, aiPlayer))( return (score:10); ) else if (availSpots.length === 0)( return (score:0); )

Після цього потрібно зібрати окуляри з кожною з порожніх кліток. Для цього створимо масив ходів moves і пройдемо в циклі по всіх порожніх клітинах, розміщуючи індекси та окуляри кожного ходу в об'єкт move.

Потім задамо індекс порожньої клітини, який зберігався у вигляді числа в origBoard, що дорівнює властивості-індексу об'єкта move. Потім сходимо за поточного гравця на порожню клітинку нового поля newBoard і викличемо функцію minimax від іншого гравця і поля newBoard, що вийшов. Після цього потрібно помістити властивість score об'єкта, повернутий функцією minimax , як score об'єкта move .

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

І нарешті, функція скидає зміни newBoard і поміщає об'єкт move в масив moves .

// масив зберігання всіх об'єктів var moves = ; // цикл за доступними клітинами for (var i = 0; i< availSpots.length; i++){ //create an object for each and store the index of that spot var move = {}; move.index = newBoard]; // совершить ход за текущего игрока newBoard] = player; //получить очки, заработанные после вызова минимакса от противника текущего игрока if (player == aiPlayer){ var result = minimax(newBoard, huPlayer); move.score = result.score; } else{ var result = minimax(newBoard, aiPlayer); move.score = result.score; } // очистить клетку newBoard] = move.index; // положить объект в массив moves.push(move); }

Потім мінімакс потрібно вибрати найкращий хід move з масиву moves. Йому потрібен move з найбільшим рахунком, якщо ходить ІІ, і з найменшим, якщо це перебіг людини. Таким чином, якщо значення player дорівнює aiPlayer, алгоритм ініціалізує змінну bestScore дуже маленьким числом і йде циклом по масиву moves: якщо хід move приносить більше очок score, ніж bestScore, алгоритм запам'ятовує цей move. У разі ходів з однаковими окулярами алгоритм запам'ятовує перший із них.

У випадку коли player дорівнює huPlayer, все аналогічно - тільки тепер bestScore ініціалізується великим числом, а мінімакс шукає хід move з найменшою кількістю очок.

У результаті мінімакс повертає об'єкт, що зберігається у bestMove.

// якщо це хід ІІ, пройти циклом по ходах і вибрати хід із найбільшою кількістю очок var bestMove; if(player === aiPlayer)( var bestScore = -10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score >bestScore)( bestScore = moves[i].score; bestMove = i; ) ) )else( // інакше пройти циклом по ходах і вибрати хід з найменшою кількістю очок var bestScore = 10000; for(var i = 0; i< moves.length; i++){ if(moves[i].score < bestScore){ bestScore = moves[i].score; bestMove = i; } } } // вернуть выбранный ход (объект) из массива ходов return moves; }

У наступному розділі ми змоделюємо роботу програми, щоб зрозуміти, як вона працює.

Мінімакс у дії

Користуючись нижче схемою, розберемо покрокову модель алгоритму.

Примітка: На схемі великі числа позначають порядковий номер виклику функції, а рівні - те, наскільки ходів пройшов алгоритм.

  1. Алгоритму подаються origBoard та aiPlayer. Він складає список із трьох знайдених порожніх клітин, перевіряє кінцівку стану, і проходить циклом по всіх порожніх клітинах. Потім алгоритм змінює NewBoard , поміщаючи aiPlayer в першу порожню клітку. Після цього він викликає сам себе від newBoard і huPlayer і чекає, доки другий виклик поверне значення.
  2. Поки перший виклик функції все ще працює, запускається другий, створюючи список двох порожніх клітин, перевіряючи кінцівку стану і проходячи циклом по всіх порожніх клітинах. Потім другий виклик змінює NewBoard , поміщаючи huPlayer в першу порожню клітинку. Після цього він викликає сам себе від newBoard та aiPlayer і чекає, поки третій виклик поверне значення.

  3. Оскільки другий виклик виявив дві порожні клітини, мінімакс змінює newBoard , поміщаючи huPlayer у другу вільну клітину. Потім він викликає сам себе від newBoard і aiPlayer.

  4. Алгоритм складає список порожніх клітин та фіксує перемогу гравця після перевірки кінцівки стану. Тому він повертає об'єкт із полем рахунку, рівним (-10).

    У другому виклику функції алгоритм отримує значення, повернуті з нижнього рівня третім та четвертим викликами функції. Оскільки хід huPlayer приніс ці два результати, алгоритм вибирає найменший. Оскільки вони однакові, алгоритм вибирає перший і передає його першому виклику функції.

    Зараз перший виклик функції отримав оцінку ходу aiPlayer в першу порожню клітину. Потім він змінює NewBoard , поміщаючи aiPlayer у другу порожню клітку. Після цього він викликає сам себе від newBoard і huPlayer.

  5. У п'ятому виклику функції алгоритм складає список порожніх клітин та фіксує перемогу ІІ після перевірки кінцівки стану. Тому він повертає об'єкт із полем рахунку, рівним +10.

    Після цього перший виклик змінює NewBoard, поміщаючи aiPlayer в третю порожню клітинку. Потім він викликає сам себе від newBoard і huPlayer.

  6. Шостий виклик складає список із двох порожніх клітин, перевіряє кінцівку стану та йде циклом по всіх порожніх клітинах. Потім він змінює NewBoard , поміщаючи huPlayer в першу порожню клітку. Потім він викликає сам себе від newBoard та aiPlayer і чекає, поки сьомий виклик поверне значення.
  7. Новий виклик складає список з однієї порожньої клітини, перевіряє кінцівку стану та змінює newBoard, поміщаючи aiPlayer у порожню клітинку. Після цього він викликає сам себе від newBoard та huPlayer і чекає, поки цей виклик поверне значення.
  8. Восьмий виклик складає порожній списокпорожніх клітин і фіксує перемогу aiPlayer після перевірки кінцівки стану. Тому він повертає об'єкт з полем рахунку, що дорівнює (+10), на рівень вище, сьомому виклику.

    Сьомий виклик отримав лише одне, позитивне значення від нижніх рівнів. Оскільки це значення було отримано в ході aiPlayer, алгоритм повертає найбільше з отриманих значень. Тому він повертає позитивне значення (+10) на рівень вище, шостий виклик.

    Оскільки шостий виклик виявив дві порожні клітини, мінімакс змінює newBoard , поміщаючи huPlayer у другу порожню клітину. Потім він викликає сам себе від newBoard і aiPlayer.

  9. Після цього алгоритм складає список порожніх клітин і фіксує перемогу aiPlayer після перевірки кінцівки стану. Тому він повертає об'єкт із полем рахунку, рівним (+10), на рівень вище.

    На цьому етапі шостий виклик повинен вибрати між рахунком (+10), який повернув сьомий виклик, та рахунком (-10), який повернув дев'ятий виклик. Оскільки хід huPlayer приніс ці два результати, алгоритм вибирає найменший з них і повертає його на рівень вище як об'єкт з полями рахунку та індексу.

    Нарешті всі три гілки першого виклику оцінюються (-10, +10, -10). Оскільки хід aiPlayer приніс ці три результати, алгоритм вибирає об'єкт, що містить найбільшу кількість очок (+10) та його індекс (4).

У розглянутому вище сценарії мінімакс вирішує, що оптимальним виборомбуде хід у центральну клітину поля.

Кінець!

До цього моменту ви мали зрозуміти, як влаштований алгоритм мінімакс. Спробуйте написати його реалізацію самостійно або перегляньте приклад на GitHub або CodePen і оптимізуйте його.

Якщо вас зацікавила тема ІІ в іграх, радимо почитати наші матеріали на цю тему.

КРОК 1. НАЛАШТУВАННЯ ПАРАМЕТРІВ ФОРМИ1. Для налаштування форми встановіть її розмір
510 точок по горизонталі та 480 точок по
вертикалі. Максимальний та мінімальний
розмір вкажіть рівний тим самим значенням.
2. Назвіть форму словом «Хрестики нуліки».
3. Для фону форми використовуйте файл із папки
Images під назвою фон.png, і розмістіть його
по центру форми.
4. Для піктограми в рядку назви
використовуйте використовуйте файл із папки
Images під назвою menu4.ico.
5. Колір фону форми необхідно встановити
MintCream.

КРОК 2. ДОДАВАННЯ КНОПКИ І НАДПИСУ НА ФОРМУ

1. Для розміщених елементів змінюємо
розмір шрифту на 12 та фон встановлюємо
прозорим.

1. Створюємо рядок меню з пунктами в
відповідно до вказаних на зображенні.

КРОК 3. ДОДАТИ РЯДКИ МЕНЮ НА ФОРМУ

1. У пункті меню Файл створюємо команду
Вихід.
2. Для
команди
Вихід
прописуємо
програмний код аналогічний як і в
попередньому додатку.

КРОК 3. ДОДАТИ РЯДКИ МЕНЮ НА ФОРМУ

1. У пункті меню Гра створюємо команду
Нова гра.
2. Для команди Нова гра пропишемо
програмний код надалі через
кілька кроків.

КРОК 3. ДОДАТИ РЯДКИ МЕНЮ НА ФОРМУ

1. У пункті меню Довідка створюємо команду
Про програму.
2. Для команди Про програму створюємо нову
форму та прописуємо програмний код
аналогічний як і в попередньому
додаток.

1. Перетягнувши на форму об'єкт PictureBox
змінюємо її розмір на 100х100.
2. Задаємо прозоре тло.
3. Маємо PictureBox як показано на
малюнок над першою клітиною поля гри.

КРОК 4. ДОДАВАННЯ ОБ'ЄКТІВ PICTUREBOX НА ФОРМУ

1
2
3
4
5
6
7
8
9
1. Над іншими осередками маємо
об'єкти PictureBox, копії першого
об'єкта, згідно з нумерацією зазначеною на
зображення.

1. Перед тим як написати програмний код
необхідно в папку
\Visual Studio
2010\Projects\Хрестики нуліки \ хрестики
нулі \bin\Debug\ необхідно перекинути
файли x.png, 0.png, none.png із папки Images.
2. Клікаємо двічі лівої миші по першому
PictureBox.

КРОК 5. ДОДАВАННЯ ПРОГРАМНОГО КОДУ ДЛЯ О'ЄКТІВ PICTUREBOX

1. Створюємо двомірний масив доступний для всіх елементів
створених у формі 3х3 елемента, що складається з цілих чисел. Відразу
заповнюємо його при оголошенні нулями. Для порожніх осередків ми
використовуватимемо 0, для «хрестиків» - 1, а для «нуликів» - -1.

КРОК 5. ДОДАВАННЯ ПРОГРАМНОГО КОДУ ДЛЯ О'ЄКТІВ PICTUREBOX

У процедуру при натисканні по першому
PictureBox, додаємо оператор
вибору
Котрий
буде
здійснювати перевірку стану
осередки масиву. Якщо значення
осередки масиву дорівнюватиме 0, що
значить у ній немає ні «нуля» ні
«хрестика», тоді в цей осередок
масиву записується 1 і
PictureBox1
відображається
зображення «хрестика», а якщо
значення осередку масиву буде
одно 1 тоді в ній знаходиться
"хрестик" і в неї записується 0, а
відображається порожній осередок.

КРОК 5. ДОДАВАННЯ ПРОГРАМНОГО КОДУ ДЛЯ О'ЄКТІВ PICTUREBOX

1
2
3
4
5
6
7
8
9



Для інших клітин поля додаємо код
аналогічно як і в першій лише змінюючи
номер об'єкта PictureBox та адреса осередку
масиву.
ПРИКЛАД для другого осередку:

У процедуру при натисканні на кнопку
додаємо
оператор
циклу
який здійснює перевірку
всіх осередків починаючи від першої на
наявність порожніх осередків. І якщо
осередок порожній,
то в неї
записується «нулик», а саме в
осередок масиву записується -1.
Для зручності у подальшій роботі
змінні
I,
j
які
використовуються для ітерації циклів
оголосимо для всієї форми.

КРОК 6. ДОДАВАННЯ ПРОГРАМНОГО КОДУ ДЛЯ КНОПКИ ХОДИТИ

Для відображення нуликів на
ігровому
поле
необхідно
додати програмний код до тіла
циклу перевірки осередків на порожнечу.
За допомогою вкладеного оператора
розгалуження
буде
відбуватися
аналіз адреси осередку масиву для
виведення нуля у правильному
PictureBox.
Також додаємо оператор break
для передчасного закінчення
циклу при знаходженні порожній
комірки.

КРОК 6. ДОДАВАННЯ ПРОГРАМНОГО КОДУ ДЛЯ КНОПКИ ХОДИТИ

Для індикації стану гри
використовується елемент інтерфейсу
Label1. Оскільки гравець завжди ходить
першим
то
при
завантаження
програми
необхідно
в
елементі
Label1
необхідно
відбивати
словосполучення «Ваш
хід».
Для
цього
створимо
змінну
otvet
якої
надамо це словосполучення. А
при завантаженні форми змінну
необхідно надавати елементу
Label1, для створення необхідної
процедури
необхідно
попередньо двічі клацнути
за формою

КРОК 7. ДОДАВАННЯ ПРОГРАМНОГО КОДУ ДЛЯ ПУНКТУ МЕНЮ НОВА ГРА

При натисканні за командою нова
гра відбуватиметься обнулення
всіх осередків масиву, заміна всіх
«хрестиків» та «нуликів» на
порожні комірки. Також висновок
написи «Ваш хід»

КРОК 8. ВИСНОВОК РЕЗУЛЬТАТУ ГРИ

Для перевірки результатів ходів
необхідно
аналізувати
вміст рядків, стовпців та
діагоналей. Якщо всі три елементи
рівні 1 то це перемога гравця, а
якщо три -1 то це поразка
гравця.
Перевірку перемоги необхідно
проводити
перед
ходом
комп'ютера,
а
перевірку
поразки після.
Останньою командою процедури
стане виведення на екран результатів
ходу.

КРОК 8. ВИСНОВОК РЕЗУЛЬТАТУ ГРИ

Програмний код для перевірки перемоги користувача:
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
if (znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1 && znacheniyeYacheyki == 1) otvet = "Ви перемогли";
Програмний код для перевірки перемоги користувача:
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Ви програли";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Ви програли";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Ви програли";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Ви програли";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Ви програли";
if (znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1 & znacheniyeYacheyki == -1) otvet = "Ви програли";
label1.Text = otvet;

КРОК 9 ПОКРАЩЕННЯ «ГРАБЕЛЬНОСТІ»

Для покращення «грабування»
замість послідовного висновку
в перші порожні порожні
осередки «нуликів», реалізуємо
виведення через генератор випадкових
чисел.
Для цього необхідно додати
одну логічну змінну
uslovie, і змінити тип циклу з For
на While, тому що нам невідомо
точну кількість повторень
генератора випадкових чиселБувай
він не потрапить у порожній осередок.

МІНОБРНАУКИ РОСІЇ

федеральна державна бюджетна освітня установа вищої професійної освіти

«Вологодський державний університет»

Кафедра автоматики та обчислювальної техніки

Пояснювальна записка до курсового проекту з дисципліни

Програмування та основи алгоритмізації

"Хрестики нолики"

Виконавстудент групи ЕМ-21

Буторова Л.Ю.

ПрийнявРжеуцька С. Ю.

ВСТУП

1. АНАЛІЗ ЗАВДАННЯ ТА ВИЗНАЧЕННЯ ВИМОГ ДО ПРОГРАМИ, що розробляється

1 Призначення програми, її користувачі, основні функції та цілі, які переслідуються при розробці

2 Огляд відомих програм, які виконують аналогічні функції

3 Теоретичні основи розробки

4 Вибір інструментальних засобів розробки

ПРОЕКТНА ЧАСТИНА РОЗРОБКИ

1 Розробка інтерфейсу користувача

2.2 Розробка структур даних (у зовнішній та оперативній пам'яті)

2.3 Розробка та аналіз алгоритмів

РЕАЛІЗАЦІЯ ПРОГРАМИ НА МОВІ С++

1 Архітектура програми

2 Вибір стандартних візуальних та не візуальних компонентів

РЕЗУЛЬТАТИ ТЕСТУВАННЯ

ВИСНОВОК

Список використаної літератури

Програми

ВСТУП

Хрестики-нуліки - логічна гра між двома супротивниками на квадратному полі 3 на 3 клітини або більшого розміру (аж до "нескінченного поля"). Один із гравців грає «хрестиками», другий – «нуликами». Ця гра стала популярна задовго до появи комп'ютерів, тільки раніше у неї грали за допомогою звичайного аркуша паперу та ручки. У традиційній китайській грі використовуються чорні та білі камені.

У цій курсової роботизбережено основні правила та стандартний розмір поля гри (3х3 клітини). Для зручності гри право першого ходу залишено за користувачем, тобто хрестиками.

Хрестики-нуліки - це програма, яка призначена для розваги користувача, тому її інтерфейс, в даній роботі, виконаний в ігровому стилі з поєднанням позитивних фарб, які загострюють емоційну частину ігрового процесу.

У грі присутні три типи: X проти 0 – користувач проти користувача, «1 рівень з комп'ютером» – для тих хто тільки освоює ази світової гри, та рівень «2 рівень з комп'ютером» – для тих, хто абсолютно впевнений у своїй перемозі. На 1 і 2 рівні можливі три результати: «перемога», «програш» та «нічия». Виграш фіксується, якщо хрестиками чи нуліками повністю заповнюється вертикаль, горизонталь чи діагональ.

Якщо вільні клітини поля закінчилися, але ніхто не здобув перемоги, то вважається, що гра закінчилася «нічиєю».

1. АНАЛІЗ ЗАВДАННЯ ТА ВИЗНАЧЕННЯ ВИМОГ ДО ПРОГРАМИ, що розробляється

програма хрестик інтерфейс

1.1 Призначення програми, її користувачі, основні функції та цілі, які переслідуються при розробці

Призначення цієї програми служить, перш за все, для розваги користувачів, для того, щоб скрасити час очікування людини, адже в будь-якій роботі потрібен відпочинок, а ця простенька гра допоможе розслабитися і відволіктися від повсякденних справ. Так само «хрестики - нуліки» відносять до класу інтелектуальних та логічних ігор, які призначені для тренування логічного мислення, дозволяють сконцентрувати увагу та розвивають пам'ять.

Цільовою аудиторією користувачів є діти та підлітки, а також дорослі. Головними критеріями для використання продукту є вміння читати написаний у програмі текст та вміння вибирати за допомогою кнопок необхідне завдання для комп'ютера.

Звідси можна дійти невтішного висновку, що основними завданнями є: завдання розваги і завдання розвитку логічного потенціалу людини.

1.2 Огляд відомих програм, що виконують аналогічні функції

У мережі Інтернет можна знайти велику кількість робіт, які реалізують цю гру. В даний час існує багато аналогів цієї гри, які відійшли від початкових стандартів. Прикладом таких програм є «Хрестики-нуліки на нескінченному полі» та «Хрестики-нуліки 3D». Також у багатьох іграх «хрестики» і «нуліки» замінюються іншими символами, такі як, наприклад, «камені».

Мій курсовий проект є додатком для ПК. Гра призначена як одного користувача, суперником якого є штучний інтелект(або комп'ютер), так двох користувачів. Вона представлена ​​на класичному полі 3х3.

Найбільш цікавою та незвичайною, на мою думку, виявилася гра «Хрестики-нуліки 3D». Тому саме її я обрала для порівняння.

Тривимірні хрестики-нуліки набагато цікавіші, ніж на папері або на звичайному полі. Тут більше можливостей виграти та програти, і нічия зустрічається рідше. Грати можна одному – проти комп'ютера – або удвох з одним. А найнезвичайніше тут те, що для виграшу можна скласти комбінацію з трьох куль свого кольору (чорного чи білого) не тільки на якомусь одному рівні, а й по площині стінок і навіть по діагоналі всього поля (рис. 1.1).

Мал. 1.1

Серед великої різноманітності ігор подібної тематики можна виділити в кожній роботі неповторну реалізацію задуманого. Кожен проект відрізняється від інших своєю індивідуальністю.

1.3 Теоретичні основи розробки

Аналіз

Для кожної зі сторін загальновідомі алгоритми, які гарантують нічию за будь-якої гри противника, а при його помилці дозволяють виграти. Таким чином, гра перебуває в стані «нічийної смерті»<#"877528.files/image002.gif">

Рис.1.2. Дерево ігрових ситуацій

Часткове дерево ігрових ситуацій, зображене на Рис.1.2 для гри хрестики-нуліки. Дерево ігрових ситуацій для гри хрестики-нуліки, де гравець за «хрестики» ходить першим і надходить за наведеним вище алгоритмом, а гравець за «нуліки» може надходити як завгодно (причому наведено по одній вершині для раціонального та для нераціонального вчинку, тобто будь-якого іншого), складається з 50 вузлів.

1.4 Вибір інструментальних засобів розробки

Для реалізації поставлених нами завдання необхідне інтегроване середовище розробки програм. Тому розробка проекту проводилася серед програмування Microsoft Visual Studio 2008.

Microsoft Visual Studio – лінійка продуктів компанії Microsoft , що включають інтегроване середовище розробки програмного забезпечення та ряд інших інструментальних засобів. Ці продукти дозволяють розробляти як консольні. програми , так і програми з графічним інтерфейсом , у тому числі за допомогою технології Windows Forms , а також веб-сайти , веб-служби як у рідному , так і в керованому коди для всіх платформ, що підтримуються Windows , Windows Mobile , Windows CE , .NET Framework , Xbox , Windows Phone .NET Compact Framework та Silverlight .

2. ПРОЕКТНА ЧАСТИНА РОЗРОБКИ

2.1 Розробка інтерфейсу користувача

При створенні ігрового застосування необхідно врахувати одну, мабуть, з основних складових успіху продукту - це інтерфейс. Інтерфейс програми користувача повинен бути, перш за все, зрозумілим і привабливим для користувача. Потрібно намагатися прибрати всі моменти, які відволікатимуть користувача або викликатимуть дискомфорт. Весь інтерфейс програми можна поділити на дві складові.

) Головне меню програми

Мал. 2.1 - Головне меню програми

Головне меню призначене для того, щоб користувач зміг влитися в ігрову атмосферу, тому інтерфейс виконаний у яскравих ігрових тонах. Через меню можна перейти на ігрове поле, подивитися правила гри або вийти з гри.

) Ігрове поле

Рис 2.2 - Ігрове поле

Ігрове поле містить безпосередню область для гри, куди гравець та комп'ютер ставлять свої значки. Перед початком гри користувач повинен вибрати тип гри, такий як "X проти 0", "1 рівень з комп'ютером" або "2 рівень з комп'ютером", інакше програма видасть повідомлення про те, що потрібно зробити. Кнопка, яка допоможе гравцеві повернутися до головного меню. Наприкінці спливатимуть додаткові вікна, які інформуватимуть учасника про результати поєдинку.

Мал. 2.3 – додаткові вікна результату гри

2.2 Розробка структур даних (у зовнішній та оперативній пам'яті)

Оперативна пам'ять використовується для одномірного масиву, що складається з 9 елементів, який зберігає стани ігрового поля, де кожен осередок масиву відповідає клітині на ігровому полі. Пам'ять також витрачається під статичні змінні: номер рівня, черговість ходу.

Для роботи потрібно 803 Кб вільної пам'яті.

.3 Розробка та аналіз алгоритмів

Для реалізації алгоритму мислення гри необхідно задати статичний масив gcnew array (9); в якому зберігатимуться стани ігрового поля, де кожен осередок масиву відповідає клітині. "0" - відповідає порожній клітині, якщо в клітинку сходив гравець, тобто "X", записується значення "1" і якщо хід зробив комп'ютер, тобто "О", значення "2". Спочатку всі елементи масиву дорівнюють «0». Необхідно встановити статичну змінну lvl, яка зберігає дані про рівень. Всього в цій грі 3 рівня: lvl приймає значення "1", якщо користувач вибрав тип гри "X проти О", значення "2", якщо "1 рівень з комп'ютером", і значення "3", якщо "2 рівень з комп'ютером" ». Змінна player – зберігає черговість ходу («true» – хід гравця, «false» – хід комп'ютера). Оскільки право першого ходу надається користувачеві, то на початку гри player = true. Статична змінна flag зберігає інформацію про те, чи є порожні клітини на ігровому полі чи ні: якщо flag = true - тобто false - порожніх клітин немає. Алгоритм перевірки повинен містити перебір параметрів масиву х і висувати своє рішення, яке буде оптимальним для подальшої гри. У цій програмі представлено 2 рівні гри з комп'ютером. У 1 рівень завдання комп'ютера у тому, щоб обіграти суперника. Тому дана функціяповертає рандомне значення клітини, куди ходитиме комп'ютер. У [Додатку 1] подано код даного алгоритму. На рис.2.4 представлена ​​блок схема реалізації коду.

Найвиграшніший хід на початку гри, це хід у центр полі. У функції dif_level() на початку перевіряється умова: якщо гравець не сходив у центральне поле, туди ходить комп'ютер. Інакше, якщо гравець сходив у центр, викликається функція check(2) для перевірки комбінації комп'ютера і, якщо є можливість виграти, то повернення номера клітини. Якщо комп'ютер наступним ходом виграти не може, то викликається функція check(1): перевірка комбінації гравця. Повертається номер клітини, поставивши в яку гравець виграв. Якщо такої комбінації немає, то викликається функція low_level().

Рис.2.4. - Блок-схема

Рис.2.5. - Блок-схема

3. РЕАЛІЗАЦІЯ ПРОГРАМИ НА МОВІ С++

.1 Архітектура програми

У цій програмі реалізовані 3 форми: головне меню (рис.2.1.), ігрове поле (рис.2.2) та поле допомоги (правила гри); 12 панелей, 9 з яких є основними. Також після закінчення гри з'являється pictureBox з результатом, всього їх 5 (рис 2.3).

За основу можна взяти обробники натискань панелей, яких рівно 9 на ігровому полі. Кожен обробник викликає кілька функцій. На початку йде умова, якщо користувач вибирає тип гри X проти 0, просто клітини заповнюються значеннями 1 або 2 (хрестик або нулик). Далі йдуть функції: індикація ходу (CrossZero()), яка змінює хрестик на нулик і навпаки, блокування зайнятих клітин checkingArray(), перебування переможця winner(). У функції winner() розглянуті всі можливі варіанти виграшу, тому, якщо хтось із гравців вишикує в ряд 3 свої фігури (хрестик або нулік) по вертикалі, горизонталі чи діагоналі, той і переможе. В іншому випадку, якщо поле заповнене, але ніхто з гравців не побудував ряд, то викликається функція (_friend())-перевірка на нічию, яка перевіряє, чи залишилися на полі вільні клітини чи ні. Якщо fr = true, то полі немає вільних клітин. Якщо значення змінилося, отже, на полі знайшлася вільна клітина.

Друга умова працює, якщо вибрано другий або третій тип гри. Тоді викликається функція, у якій здійснено перебіг комп'ютера move(int n). До неї передається номер клітки, на яку натиснув гравець. Далі йдуть функції: індикація ходу (CrossZero()), блокування зайнятих клітин checkingArray(). Потім викликається функція winner(), яка перевіряє, чи переміг гравець цим ходом чи ні. Якщо ні, перевіряється наявність вільних клітин. Якщо є вільні клітини, то ходить комп'ютер. Далі, залежно від того, який рівень вибрав гравець «1» або «2», викликаються функції відповідно: low_level(), dif_level(). Функція low_level() вибирає куди ставити нолік рандомно, а функції dif_level() представлений спеціальний алгоритм перемоги комп'ютера. Далі йдуть функції: індикація ходу (CrossZero()), блокування зайнятих клітин checkingArray(). Потім викликається функція winner(), яка перевіряє, чи переміг комп'ютер цим ходом чи ні. Якщо ні, перевіряється наявність вільних клітин. Якщо є вільні клітини, то ходить гравець.

.2 Вибір стандартних візуальних та не візуальних компонентів

Для реалізації цієї роботи було обрано такі компоненти:

1) Form1, з заданими параметрами Text=Хрестики-нуліки, ControlBox=False

2) f2, із заданими параметрами BackColor, Text=Гра

) comboBox1 із заданими параметрами Items:

X проти 0

1 рівень з комп'ютером

2 рівень з комп'ютером

4) panel, з заданими параметрами BackColor, та різними значеннями параметра Visible та Enabled. Для деяких panel були написані такі події, як Click.

5) button, з заданими параметрами Font, Fore Color, BackColor, Text, всім button були написані такі події як Click.

6) label, з заданими параметрами BackColor, Font, Fore Color, Text.

) pictureBox, з заданими параметрами Image, SizeMode = StretchImage.

) textBox, з заданими параметрами BackColor, Font, Fore Color, Text = "".

4. РЕЗУЛЬТАТИ ТЕСТУВАННЯ

Проведемо тестування програми, пройшовши 3 типи гри.

Пробуємо дії кнопок головного меню. Кнопки працюють справно. Спробуємо розпочати гру, не вибравши типу гри. Програма видає повідомлення про помилку і просить вибрати тип гри. (Рис.4.1)

Рис.4.1.

Виберемо 1 тип гри – «X проти 0», тобто. користувач проти користувача. На даному етапі гри користувач може грати сам з собою. (Рис.4.2)

Рис.4.2.

У процесі гри «1 рівень із комп'ютером» комп'ютер не ставить собі за мету виграти учасника. Він просто ставить нулики в вільні місцяполя. На цьому етапі користувач може легко обіграти комп'ютер. Хоча цьому рівні можливі й інші варіанти розвитку подій.

Рис.4.3.

Тип гри "2 рівень з комп'ютером". На цьому етапі гра аналізує всі ходи і намагається вибрати найбільш оптимальний хід. Тут також можливі всі варіанти розвитку подій, т.к. перший свій хід комп'ютер робить у будь-яку вільну клітину. Найчастіше гра зводиться до нічиєї.

Рис.4.4.

Програма на всіх варіантах тестів працює успішно, без помилок.

ВИСНОВОК

Можна з упевненістю сказати, що завдання, поставлене на початку роботи, виконане. У ході розробки було сплановано та розроблено проект реміксу відомої гри «Хрестики-нуліки». Гра відповідає заданим вимогам та виконує свої функції. У роботі реалізовано різні типиігри та рівні складності.

У ході роботи було освоєно нові методи програмування в інтегральному середовищі розробки. Закріплено старі знання роботи з мовою С++. У ході підготовки до курсової роботи було аналізовано різні методи та алгоритми реалізації цієї гри.

Не дивлячись на зовні простоту цієї програми, він таїть у собі ряд труднощів, які реалізуються з допомогою всіх основних прийомів Visual C++.

Особливостями даної програми є:

Чітко побудований алгоритм;

Інтуїтивно зрозумілий інтерфейс;

Простота використання;

Цілком зрозумілий посібник користувача;

Відсутність зайвих доповнень.

СПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ

1. http://www.pravilaigr.ru/xo.php

2. http://2igroka.com/stuff/sportivnye/krestiki_noliki_3d/15-1-0-14

3. https://www.draw.io/

http://pol-video.ru/QPW9QHEO2GU/uroki_s_krestiki-noliki_ch1.html

ДОДАТОК 1

private: int low_level()(// процедура для легкого противникаr;::Random^ rand = gcnew System::Random();(= rand->Next(0,8);

) while (x [r]! = 0); r;

ДОДАТОК 2

private: bool check(int n)(k = -1; // перевіряє всі комбінації, і повертає правильний хід (x == n) (((x == n)&&(x == 0)) k =2; ((x == n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =6;((x == n)&&(x == 0)) k = 3; ((x = = n) & (x = = 0)) k = 8;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =7;((x = = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =4;((x == n)&&(x == 0)) k =6;((x = = n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =5;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =5;((x = = n)&&(x == 0)) k =4;

)(x == n) (((x == n)&&(x == 0)) k =0;((x == n)&&(x == 0)) k =3;((x = = n)&&(x == 0)) k =1;((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =2;

)(x == n) (((x == n)&&(x == 0)) k =8;((x == n)&&(x == 0)) k =7;

)(x == n) (((x == n)&&(x == 0)) k =6;

)(k!=-1) return true;else return false;

ДОДАТОК 3

private: int dif_level()(//складний противник

//return check(2);(x == 0) return (4);(check(2)) return k; else (check(1)) return k; else low_level();

ДОДАТОК 4

private: void CrossZero()(// змінює хрестик на нулик(індикатор ходу)(player) (->Visible = true;->Visible = false;

) else (-> Visible = true; -> Visible = false;

): void checkingArray()(// функція перевірки, чи є в клітці щось, якщо є, то більше на цю клітинку натискати не можна.(x == 1) (panel1->BackgroundImage = panel11->BackgroundImage;panel1- >Enabled = false;)(x == 2) (panel1->BackgroundImage = panel10->BackgroundImage;panel1->Enabled = false;)(x == 1) (panel2->BackgroundImage = panel11->BackgroundImage;panel2- >Enabled = false;)(x == 2) (panel2->BackgroundImage = panel10->BackgroundImage;panel2->Enabled = false;)(x == 1) (panel3->BackgroundImage = panel11->BackgroundImage;panel3- >Enabled = false;)(x == 2) (panel3->BackgroundImage = panel10->BackgroundImage;panel3->Enabled = false;)(x == 1) (panel4->BackgroundImage = panel11->BackgroundImage;panel4- >Enabled = false;)(x == 2) (panel4->BackgroundImage = panel10->BackgroundImage;panel4->Enabled = false;)(x == 1) (panel5->BackgroundImage = panel11->BackgroundImage;panel5- >Enabled = false;)(x == 2) (panel5->BackgroundImage = panel10->BackgroundImage;panel5->Enabled = false;)(x == 1) (panel6->BackgroundImage = panel11->BackgroundImage;panel6- >Enabled = false;)(x == 2) (panel6->BackgroundImage = panel10->BackgroundImage;panel6->Enabled = false;)(x == 1) (panel7->BackgroundImage = panel11->BackgroundImage;panel7- >Enabled = false;)(x == 2) (panel7->BackgroundImage = panel10->BackgroundImage;panel7->Enabled = false;)(x == 1) (panel8->BackgroundImage = panel11->BackgroundImage;panel8- >Enabled = false;)(x == 2) (panel8->BackgroundImage = panel10->BackgroundImage;panel8->Enabled = false;)(x == 1) (panel9->BackgroundImage = panel11->BackgroundImage;panel9- >Enabled = false;)(x == 2) (panel9->BackgroundImage = panel10->BackgroundImage;panel9->Enabled = false;)

): bool winner()(// перевірка переможця і блокування всіх клітин, що залишилися.

//((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x = = (2)) || ((x == x)&&(x == x)&&(x == 2)) || )) || ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2)) ((x == x)&&(x == x)&&(x == 2)) || ((x == x)&&(x == x)&&(x == 2))))( (lvl==1) ( picturePo->Visible = true;)(picturePr->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false; -> Enabled = false; -> Enabled = false; -> Enabled = false; -> Enabled = false; true;

)(((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((x == x)&&(x == x)&&(x == 1)) || ((( ((x == x)&&(x == x)&&(x == 1)) || ((x = (x == x)&&(x == x)&&(x == 1)))((lvl==1) (picturePx->Visible = true;)(picturePobeda->Visible = true;)->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;->Enabled = false;-> Enabled = false; -> Enabled = false; -> Enabled = false; -> Enabled = false; true;

): void _friend()(fr = true;(int i = 0; i< 9; i++) if (x[i] == 0) {fr = false; break;}(fr) { pictureN->Visible = true;)

): void move(int n)(// функція ходу комп'ютера= false;[n] = 1;= !player;();();(winner()) () ((int i = 0; i< 9; i++) if (x[i] == 0) flag = true;(flag){(lvl == 2) = 2; = 2;= !player;();();();

): System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) (// нова гра>Visible = false;>Visible = false;>Visible = false; >Visible = false; >Visible = false; = comboBox1->Text;(typeGame == "")(::Show("Спочатку вибери тип гри!");

) else ((typeGame == "X проти 0") lvl = 1;(typeGame == "1 рівень з комп'ютером") lvl = 2;(typeGame == "2 рівень з комп'ютером") lvl = 3;(); = true; (int i = 0; i< 9; i++) x[i] = 0;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12-> BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->BackgroundImage = panel12->BackgroundImage;->Enabled = true;->Enabled = true;->Enabled = true;->Enabled = true; -> Enabled = true; -> Enabled = true; -> Enabled = true; -> Enabled = true; -> Enabled = true;

): System::Void panel1_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 0;(lvl == 1)((player)( = 1;

)= !player;();();();

): System::Void panel2_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 1;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel3_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 2;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel4_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 3;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel5_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 4;(lvl == 1)((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel6_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 5;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel7_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 6;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel8_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 7;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void panel9_MouseClick(System::Object^ sender, System::Windows::Forms::MouseEventArgs^ e) (n = 8;(lvl == 1) ((player)( = 1;

)= !player;();();();

) else if ((lvl == 2)||(lvl == 3))((n);

): System::Void button2_Click(System::Object^ sender, System::EventArgs^ e) (();

): System::Void picturePx_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void picturePo_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void picturePobeda_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void picturePr_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

): System::Void pictureN_Click(System::Object^ sender, System::EventArgs^ e) (>Visible = false;

Увага! Перед вами ознайомлювальна версія уроку, матеріали якого можуть бути неповними.

Увійдіть на сайт як учень

Увійдіть як учень, щоб отримати доступ до матеріалів школи

Створення конфігурацій 1С: пишемо "Хрестики-нуліки" частина 1/3

Вчитися ми будемо граючи, а тому нашим першим проектом буде створення всім
знайомої з дитинства гри - "Хрестики-нуліки".

Ви запитаєте яке відношення гри мають до 1С, бухгалтерського обліку та торгівлі? Майже жодного. Але починати треба поступово і згодом ми дійдемо до автоматизації складів. А поки почнемо з малого.

Перед тим як розпочати програмування гри "Хрестики-Нолики" давайте поміркуємо.

Ми вже знаємо, що форма має Елементи, одним з яких є Кнопка. Кнопки здатні виконувати команди, і, водночас, мають властивості, які дозволяють керувати їх відображенням на формі (наприклад, заголовок).

Наприклад, можна використовувати кнопку для того, щоб створити поле з дев'ятьма активними областями (ті клітини на які ми клацаємо та фіксуємо дію, одночасно відображаючи написи у вигляді "О" та "Х"). Кнопка нам більше, ніж підходять для цього.

Що нам знадобиться? Очевидно, нам знадобиться запам'ятовувати наш хід та запам'ятовувати хід комп'ютера. Нам також знадобиться змінювати заголовки кнопок: при нашому натисканні заголовок кнопки завжди "О", при ході комп'ютера - "Х".

А для початку нам знадобиться створити нову базу даних, в якій ми творитимемо нашу гру. Давайте зробимо це.

Крок №1: створення порожньої бази

Створимо порожню базу "Хрестики-нуліки".

Детальні інструкції

Запустимоярлик 1С, щоб відкрився список інформаційних баз на комп'ютері. Ви читаєте ознайомлювальну версію уроку, повноцінні уроки . Нам потрібне створення нової бази, тому тиснемо кнопку " Додати":

Відкриється вікно додавання інформаційної бази, в якому потрібно вибрати перший пункт Створення інформаційної бази" і натиснути кнопку "Далі":

У наступному вікні вибираємо другий пункт " Створення інформаційної бази без конфігурації для розробки нової конфігурації.і знову тиснемо кнопку "Далі":

У наступному вікні нам пропонують ввести найменування нової бази, під якою вона відображатиметься у списку баз. Введемо " Хрестики нолики" і натиснемо кнопку "Далі":

У наступному вікні необхідно вказати шлях до порожньої папки, в якій зберігатиметься наша база. У цьому випадку я створив папку " Хрестики нолики" в папці "Бази 1С" на диску D:

У наступному вікні залишаємо всі налаштування за замовчуванням та натискаємо кнопку " Готово":

Після нетривалої паузи база створена та додана до списку. Є два основні режими роботи з базою: 1с Підприємствоі Конфігуратор:

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

Крок №2: відкриваємо конфігуратор

Натисніть кнопку " Конфігуратор", щоб увійти в режим конфігуратора:

Крок №3: відкриваємо дерево конфігурації

Виконаємо команду меню " Конфігурація"->"Відкрити конфігурацію":

Перед нами відкрилося дерево конфігурації, яке містить різноманітні розділи конфігурації. Тому що ми ще нічого не створювали, поки ці розділи порожні:

Крок №4: додаємо обробку

Для розміщення логіки нашої гри скористаємось розділом "Обробки". Натиснемо правою кнопкоюна розділі " Обробкиі виберемо команду "Додати":

Перед нами відчинилося вікно створення нової обробки. Введемо ім'я Хрестики ноликиСинонім підставиться сам. Цього достатньо для того, щоб зберегти нашу обробку (поки що ще порожню) в базі. Натиснемо кнопку "Закрити":

Крок №5: перше налагодження програми

Перевірити, що можна з режиму користувача ( 1с Підприємство). Щоб потрапити до нього прямо з конфігуратора, виконаємо команду меню " Налагодження"->"Почати налагодження":

Так як ми внесли зміну до бази нас запитують чи згодні ми прийняти цю зміну. Таке питання нам задаватиметься постійно в процесі розробки. Відповідаємо згодою (кнопка " Так"):

База запустилася у режимі "1С:Підприємство". Ви читаєте ознайомлювальну версію уроку, повноцінні уроки . Але як ми бачимо працювати з нею поки складно - просто нема з чого вибирати. Дивно, адже обробку ми вже створили і, за ідеєю, вона повинна з'явитися на жовтій панелі.




Top