Курсова робота 121. !записка_Бачурський (3). 1 Постановка задачі Основна частина
2.5 Інструкція користувача програми 2.5.1 Налаштування режимів роботи програми; Програма має деякий набір налаштувань, функціонал яких описаний нище. Рисунок 2.7 – Вікно програми Auto submit – перевіряє правильність розв’язку головоломки кожного разу , коли користувач його змінює. Hide timer – ховає ігровий таймер. Night theme – перемикає темну тему гри. Рисунок 2.8 – темна тема гри Last change – виділяє останню обрану користувачем клітинку. Рисунок 2.9 – поле з налаштуванням Last change Show errors – підсвічує червоним кольором помилки. Рисунок 2.10 – ігрове поле з Show errors Show coordinates – показує координати поля. Рисунок 2.11 – ігрове поле з Show coordinates Show counters – якщо умови виконані поле отримує символ “ок”. Рисунок 2.12 – ігрове поле з Show counters Show complited – змінює колір на сірий якщо виконані умови. Рисунок 2.13 – ігрове поле з Show complited Show water – додає сині клітинки в місцях, де завершено знаходження корабля. Рисунок 2.14 – ігрове поле з Show water 2.5.2 Правила і формати підготовки вхідних даних: Користувачу заборонено змінювати програмні файли гри, щоб забеспечити найбільш комфортну та безпечну гру 2.5.3 Перелік і формати отримуваних результатів; При неправильному розв’язку головоломки користувач отримає про це повідомлення При правильному розв’язку головоломки користувач отримує про це повідомлення та зможе побачити скільки часу головоломка зайняла Рисунок 2.15 – повідомлення про не правильний розв’язок головоломки Рисунок 2.16 – повідомлення про правильний розв’язок головоломки2.6 Вимоги до складу та параметрів технічних та програмних засобів Для повноцінної роботи програми необхідний персональний комп’ютер з операційною системою Windows v.7/v.8.1/10 Конфігурація комп’ютеру повинна бути такою: - процесор Pentium з частотою 1.6 ГГц або швидший; - не менш 2ГБ оперативної пам'яті; - не менше 150 МБ вільного місця на жорсткому диску; - клавіатура, миша чи сумісний вказівний пристрій; - монітор з розподільною здатністю мінімально1024х768 pх;2.7 Тестування програми При тестуванні програми були перевірені всі варіанти взаємодії тестуючої програми, її налаштувань та режимів роботи панелі інструментів з різними рівнями ігрового поля, та його розміру. Після того я користувач зберіг своє ігрове поле, та перезапустив його, програма видалення збережень , а при натисканні на завантеження без попереднього збереження нічого не відбудеться, що продемонстровано на рисунка 2.17 та 2.18 Таймер зупиниться якщо користувач пройде рівень, але якщо користувач пройде рівень та натисне кнопку “Restart”, таймер почне рахунок з початку Неможливо додати на поле в одне місце корабель та воду, вони будуть змінювати один одного Рисунок 2.17 – Збереження після змін на полі Рисунок 2.18 – Натискання завантаження при відсутніх збереженнях Рисунок 2.20 – Таймер продовжив роботу Неможливо додати на поле в одне місце корабель та воду, вони будуть змінювати один одного Рисунок 2.21 – Користувач додав корабель на воду Якщо 2 рази натиснути в одне місце з вімкненим налаштуванням lastChange, буде виділена сама ця клітинка Рисунок 2.22 – Налаштування lastChange2. 8 Результати реалізації програми Під час розробки та програмування користувацького інтерфейсу і логіки роботи гри “ Battleships ”, були використані засоби мови C#, а саме додаток Windows Presentation Foundation та фреймворк .Net. Головна задача головоломки знаходження та розташування бойових кораблів була здійснена за допомогою генераціїї клітинок та розташуванню в них елементів: button, border, canvas. Умови, що лінкори не можуть торкатися один одного (навіть по діагоналі) та числа за межами сітки показують кількість клітинок, зайнятих лінкорами в цьому рядку/стовпці, були реалізовані за допомогою циклу for та перевірки if else. Під час складання результуючого класу MainWindow було додано додаткові атрибути-класи Settings та Kletka, також було передбачено обробку виключних ситуацій, можливість роботи декількох налаштувань разом, збереження та завантаження рішення зі зрозумілим інтерфейсом для користувача. ВИСНОВКИ ПО РОБОТІ В даній курсовій роботі була розроблена гра «Battleships відповідно постановки задачі курсової роботи. Застосована під час реалізації програми Windows Presentation Foundation - графічна підсистема, дала змогу вдосконалити знання по створенню двовимірних та тривимірних інтерфейсів. Під час створення логіки гри я досконально вивчив принципи: складання класів, визначення методів, мови xaml. Розроблену програму можна вдосконалити доданням нових функцій для зручності користувача, налаштувань, рівнів. Перевірку потрібно покращити. ПЕРЕЛІК ВИКОРИСТАНИХ ДЖЕРЕЛ 1 Коваленко І.В. програмування мовою C # 7.0. Тернопіль, 2017. – 302 с. 2 Джон Скіт. C# для профессионалов: тонкости программирования, 3-е издание, новый перевод = C# in Depth, 3rd ed.. — М.: «Вильямс», 2014. —608 с. — ISBN 978-5-8459-1909-0. 3 Крістіан Нейгел и др. C# 5.0 и платформа .NET 4.5 для профессионалов = Professional C# 5.0 and .NET 4.5. — М.: «Диалектика», 2013. — 1440 с. — ISBN 978-5-8459-1850-5. 4 А. Хейлсберг, М. Торгерсен, С. Вилтамут, П. Голд. Язык программирования C#. Классика Computers Science. 4-е издание = C# Programming Language (Covering C#4.0), 4th Ed. — СПб.: «Питер», 2012. — 784 с. — ISBN 978-5-459-00283-6.5 5 . Е. Стіллмен, Дж. Грин. Изучаем C#. 2-е издание = Head First C#, 2ed. — СПб.: «Питер», 2012. — 704 с. — ISBN 978-5-4461-0105-4. Додаток Б Лістинг програми //MainWindow.xaml.cs using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; using System.Collections; namespace kurs_bogdan_reference { /// /// Логика взаимодействия для MainWindow.xaml /// /// public class Kletka { public int x = 0; public int y = 0; public CornerRadius radius = new CornerRadius(0, 0, 0, 0); public SolidColorBrush bg = Brushes.Transparent; public string id = ""; public bool granica = false; public bool selected = false; public bool lastChange = false; public bool autoCreatedGranica = false; public Kletka(int x, int y, string id) { this.x = x; this.y = y; this.id = id.ToString(); } } public class Settings { public bool autoSubmit = false; public bool hideTimer = false; public bool nightMode = false; public bool lastChange = false; public bool errors = false; public bool complited = false; public bool coordinates = false; public bool autoWater = false; public bool showCounters = false; } public partial class MainWindow : Window { const int gridSize = 6; int cellGap = 0; int cellSize = 50; int startX = 100; int startY = 100; int textGap = 50; Kletka[,] cellList = new Kletka[gridSize, gridSize]; string[,] answers = { { " ttft", "1ffft", " fttf", " ttft ", " fftt" }, { " ftft", " ftft", "3tftt", "0ffff", "3tttf" }, { " ftft", " fftt", "3tttf", " ftft", " tftt" }, { " ffft", " tftf", "1tfff", "1fftf", "2ttff" }, { "3fttt", " ttft", "3fttt", " ttft", " fttt" }, }; string[] xCords = { "2", "1", "2", "3", "1", "1" }; string[] yCords = { "1", "4", "0", "4", "0", "1" }; DispatcherTimer gameTimer = new DispatcherTimer(); int secondsPlayed = 0; Settings settings = new Settings(); Kletka[,] save1 = new Kletka[gridSize, gridSize]; Kletka[,] save2 = new Kletka[gridSize, gridSize]; Kletka[,] save3 = new Kletka[gridSize, gridSize]; public MainWindow() { InitializeComponent(); gameTimer.Interval = TimeSpan.FromSeconds(1); gameTimer.Tick += GameLoop; gameTimer.Start(); for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { save1[i, j] = new Kletka(0, 0, "id"); save2[i, j] = new Kletka(0, 0, "id"); save3[i, j] = new Kletka(0, 0, "id"); } } for (int i = 0; i < gridSize; i++) { Label newLabel = new Label { Content = xCords[i].ToString(), FontSize = 24, Tag = "x" + i, }; Canvas.SetTop(newLabel, startY - gridSize * 6.5); Canvas.SetLeft(newLabel, startX + gridSize * 2 + i * textGap); GameField.Children.Add(newLabel); } for (int i = 0; i < gridSize; i++) { Label newLabel = new Label { Content = yCords[i].ToString(), FontSize = 24, Tag = "y" + i, }; Canvas.SetTop(newLabel, startY + i * textGap); Canvas.SetLeft(newLabel, startX - gridSize * 6); GameField.Children.Add(newLabel); } for (int j = 0; j < gridSize; j++) { int yPos = startY + (cellSize * j) + cellGap * (j - 1); for (int i = 0; i < gridSize; i++) { int xPos = startX + (cellSize * i) + cellGap * (i - 1); string id = j.ToString() + "-" + i.ToString(); GenerateCell(id, "2", xPos, yPos); cellList[j, i] = new Kletka(xPos, yPos, id); }; } Button Check = new Button { Content = "DONE", Background = Brushes.AliceBlue, BorderBrush = Brushes.Transparent, Padding = new Thickness(20, 10, 20, 10), Width = 160, Height = 50, FontSize = 18, }; Button Restart = new Button { Content = "RESTART", Background = Brushes.AliceBlue, BorderBrush = Brushes.Transparent, Padding = new Thickness(20, 10, 20, 10), Width = 160, Height = 50, FontSize = 18, }; Check.Click += handleCheck; Restart.Click += restart_click; Canvas.SetTop(Check, cellSize * (gridSize * 1.75)); Canvas.SetLeft(Check, cellSize * (gridSize / 1.5)); Canvas.SetTop(Restart, cellSize * (gridSize * 1.75)); Canvas.SetLeft(Restart, cellSize * (gridSize / 1.5) + 190); GameField.Children.Add(Check); GameField.Children.Add(Restart); } private void GameLoop(object sender, EventArgs e) { secondsPlayed++; TimeSpan time = TimeSpan.FromSeconds(secondsPlayed); string formattedTime = string.Format("{0:D2}:{1:D2}:{2:D2}", time.Hours, time.Minutes, time.Seconds); GameTimer.Content = formattedTime; } private void GenerateCell(string id, string value = "2", int x = 0, int y = 0) { char[] charArray = id.ToCharArray(); Array.Reverse(charArray); string reversedId = new string(charArray); Border kletka = new Border { Width = cellSize, Height = cellSize, BorderBrush = Brushes.Black, BorderThickness = new Thickness(1,1,1,1) }; Border cell = new Border { Tag = id, Width = cellSize - 10, Height = cellSize - 10, BorderBrush = Brushes.Transparent, BorderThickness = new Thickness(1), Background = Brushes.Transparent, }; cell.MouseRightButtonDown += kletka_right_click; cell.MouseLeftButtonDown += kletka_click; Canvas.SetLeft(kletka, x); Canvas.SetTop(kletka, y); Canvas.SetLeft(cell, x + 5); Canvas.SetTop(cell, y + 5); GameField.Children.Add(kletka); GameField.Children.Add(cell); } private void draw() { int i = 0; int j = 0; int[] xCordsCur = {0,0,0,0,0,0}; int[] yCordsCur = {0,0,0,0,0,0}; string cache = ""; calcCounters(); for (int k = 0; k < gridSize; k++) { for(int n = 0; n < gridSize; n++) { if(cellList[k,n].autoCreatedGranica == true && cellList[k, n].granica == false) { if (!cache.Contains((k.ToString() + n.ToString()))) { cellList[k, n].autoCreatedGranica = false; cellList[k, n].bg = Brushes.Transparent; } } if (settings.autoWater && cellList[k,n].selected == true) { if (n - 1 >= 0 && k - 1 >= 0) { if (cellList[k - 1, n - 1].selected == false) { cellList[k - 1, n - 1].autoCreatedGranica = true; cellList[k - 1, n - 1].radius = new CornerRadius(0); cellList[k - 1, n - 1].bg = Brushes.Aqua; } } if (n - 1 >= 0 && k + 1 <= gridSize - 1) { if (cellList[k + 1, n - 1].selected == false) { cellList[k + 1, n - 1].autoCreatedGranica = true; cellList[k + 1, n - 1].radius = new CornerRadius(0); cellList[k + 1, n - 1].bg = Brushes.Aqua; cache += (k + 1).ToString() + (n - 1).ToString(); } } if (n + 1 <= gridSize - 1 && k - 1 >= 0) { if (cellList[k - 1, n + 1].selected == false) { cellList[k - 1, n + 1].autoCreatedGranica = true; cellList[k - 1, n + 1].radius = new CornerRadius(0); cellList[k - 1, n + 1].bg = Brushes.Aqua; } } if (n + 1 <= gridSize - 1 && k + 1 <= gridSize - 1) { if (cellList[k + 1, n + 1].selected == false) { cellList[k + 1, n + 1].autoCreatedGranica = true; cellList[k + 1, n + 1].radius = new CornerRadius(0); cellList[k + 1, n + 1].bg = Brushes.Aqua; cache += (k + 1).ToString() + (n + 1).ToString(); } } } } } foreach (var x in GameField.Children.OfType()) { if (x.Tag == null) { continue; } if(j > gridSize - 1) { j = 0; i++; } if (settings.lastChange && cellList[i, j].lastChange == true) { x.BorderBrush = Brushes.Red; } else { x.BorderBrush = Brushes.Transparent; } if (cellList[i,j].selected == true) { xCordsCur[j]++; yCordsCur[i]++; if (!rightGranica(i,j) || cellList[i,j].radius == new CornerRadius(0,0,0,0)) { cellList[i, j].radius = new CornerRadius(0); if ((j - 1 < 0 || cellList[i, j - 1].autoCreatedGranica == true || cellList[i, j - 1].granica == true) && j + 1 <= gridSize - 1 && cellList[i, j + 1].selected == true) { cellList[i, j].radius = new CornerRadius(30, 0, 0, 30); } if ((j + 1 > gridSize - 1 || cellList[i, j + 1].granica == true || cellList[i, j + 1].autoCreatedGranica == true) && j - 1 >= 0 && cellList[i, j - 1].selected == true) { cellList[i, j].radius = new CornerRadius(0, 30, 30, 0); } if ((i - 1 < 0 || cellList[i - 1, j].granica == true || cellList[i - 1, j].autoCreatedGranica == true) && i + 1 <= gridSize - 1 && cellList[i + 1, j].selected == true) { cellList[i, j].radius = new CornerRadius(30, 30, 0, 0); } if ((i + 1 > gridSize - 1 || cellList[i + 1, j].granica == true || cellList[i + 1, j].autoCreatedGranica == true) && i - 1 >= 0 && cellList[i - 1, j].selected == true) { cellList[i, j].radius = new CornerRadius(0, 0, 30, 30); } } if(settings.errors) { cellList[i, j].bg = Brushes.Black; if (i > 0 && j > 0) { if (cellList[i - 1, j - 1].selected == true) { cellList[i,j].bg = Brushes.Red; } } if (i < gridSize - 1 && j < gridSize - 1) { if (cellList[i + 1, j + 1].selected == true) { cellList[i, j].bg = Brushes.Red; } } if (i < gridSize - 1 && j > 0) { if (cellList[i + 1, j - 1].selected == true) { cellList[i, j].bg = Brushes.Red; } } if (i > 0 && j < gridSize - 1) { if (cellList[i - 1, j + 1].selected == true) { cellList[i, j].bg = Brushes.Red; } } } if (cellList[i, j].radius == new CornerRadius(30, 0, 0, 30) && cellList[i, j + 1].selected != true) { radiuses(i,j); } if (cellList[i, j].radius == new CornerRadius(0, 30, 30, 0) && cellList[i, j - 1].selected != true) { radiuses(i, j); } if (cellList[i, j].radius == new CornerRadius(30, 30, 0, 0) && cellList[i + 1, j].selected != true) { radiuses(i, j); } if (cellList[i, j].radius == new CornerRadius(0, 0, 30, 30) && cellList[i - 1, j].selected != true) { radiuses(i, j); } } x.CornerRadius = cellList[i, j].radius; x.Background = cellList[i, j].bg; j++; } foreach (var x in GameField.Children.OfType()) { if (x.Tag == null) { continue; } string tag = (x as Label).Tag.ToString(); if (tag[0].ToString() == "x") { if (xCordsCur[Int32.Parse(x.Tag.ToString()[1].ToString())] > Int32.Parse(xCords[Int32.Parse(x.Tag.ToString()[1].ToString())])) { x.Foreground = Brushes.Red; } else { x.Foreground = Brushes.Black; } } if (tag[0].ToString() == "y") { if (yCordsCur[Int32.Parse(x.Tag.ToString()[1].ToString())] > Int32.Parse(yCords[Int32.Parse(x.Tag.ToString()[1].ToString())])) { x.Foreground = Brushes.Red; } else { x.Foreground = Brushes.Black; } } } checkSelectedShips(); } private void checkSelectedShips() { bigShip.IsChecked = false; mediumShip1.IsChecked = false; mediumShip2.IsChecked = false; smallShip1.IsChecked = false; smallShip2.IsChecked = false; smallShip3.IsChecked = false; int bigShips = 0; int mediumShips = 0; int smallShips = 0; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { if ((j - 1 >= 0 && cellList[i, j - 1].selected == true && cellList[i,j].selected == true && j + 1 <= gridSize - 1 && cellList[i, j + 1].selected) || (i - 1 >= 0 && cellList[i - 1, j].selected == true && cellList[i, j].selected == true && i + 1 <= gridSize - 1 && cellList[i + 1, j].selected)) { if(((j - 2 < 0 || cellList[i, j - 2].granica == true || cellList[i, j - 2].autoCreatedGranica == true) && (j + 2 > gridSize - 1 || cellList[i, j + 2].granica == true || cellList[i, j + 2].autoCreatedGranica == true)) || ((i - 2 < 0 || cellList[i - 2, j].granica == true || cellList[i - 2, j].autoCreatedGranica == true) && (i + 2 > gridSize - 1 || cellList[i + 2, j].granica == true || cellList[i + 2, j].autoCreatedGranica == true))) { bigShips++; } } if ((j - 1 >= 0 && cellList[i, j - 1].selected == true && cellList[i, j].selected == true) || (i - 1 >= 0 && cellList[i - 1, j].selected == true && cellList[i, j].selected == true)) { if (((j - 2 < 0 || cellList[i, j - 2].granica == true || cellList[i, j - 2].autoCreatedGranica == true) && (j + 1 > gridSize - 1 || cellList[i, j + 1].granica == true || cellList[i, j + 1].autoCreatedGranica == true)) || ((i - 2 < 0 || cellList[i - 2, j].granica == true || cellList[i - 2, j].autoCreatedGranica == true) && (i + 1 > gridSize - 1 || cellList[i + 1, j].granica == true || cellList[i + 1, j].autoCreatedGranica == true))) { mediumShips++; } } if (cellList[i, j].selected == true) { if (((j - 1 < 0 || cellList[i, j - 1].autoCreatedGranica == true || cellList[i, j - 1].granica == true) && (j + 1 > gridSize - 1 || cellList[i, j + 1].granica == true || cellList[i, j + 1].autoCreatedGranica == true)) && ((i - 1 < 0 || cellList[i - 1, j].granica == true || cellList[i - 1, j].autoCreatedGranica == true) && (i + 1 > gridSize - 1 || cellList[i + 1, j].granica == true || cellList[i + 1, j].autoCreatedGranica == true))) { smallShips++; } } } } if (bigShips >= 1) { bigShip.IsChecked = true; } else { bigShip.IsChecked = false; } if(mediumShips >= 1) { mediumShip1.IsChecked = true; } if(mediumShips >= 2) { mediumShip1.IsChecked = true; mediumShip2.IsChecked = true; } if(smallShips >= 1) { smallShip1.IsChecked = true; } if(smallShips >= 2) { smallShip1.IsChecked = true; smallShip2.IsChecked = true; } if(smallShips >= 3) { smallShip1.IsChecked = true; smallShip2.IsChecked = true; smallShip3.IsChecked = true; } } private void radiuses(int i, int j) { if ((j - 1 < 0 || cellList[i, j - 1].granica == true || cellList[i, j - 1].autoCreatedGranica == true) && cellList[i, j + 1].selected == true) { cellList[i, j].radius = new CornerRadius(30, 0, 0, 30); return; } if ((j + 1 > gridSize - 1 || cellList[i, j + 1].granica == true || cellList[i, j + 1].autoCreatedGranica == true) && cellList[i, j - 1].selected == true) { cellList[i, j].radius = new CornerRadius(0, 30, 30, 0); return; } if ((i - 1 < 0 || cellList[i - 1, j].granica == true || cellList[i - 1, j].autoCreatedGranica == true) && cellList[i + 1, j].selected == true) { cellList[i, j].radius = new CornerRadius(30, 30, 0, 0); return; } if ((i + 1 > gridSize - 1 || cellList[i + 1, j].granica == true || cellList[i + 1, j].autoCreatedGranica == true) && cellList[i - 1, j].selected == true) { cellList[i, j].radius = new CornerRadius(0, 0, 30, 30); return; } cellList[i, j].radius = new CornerRadius(0); } private bool rightGranica(int i, int j) { if (cellList[i, j].radius == new CornerRadius(30,0,0,30) && cellList[i, j + 1].selected != true) { return false; } if (cellList[i, j].radius == new CornerRadius(0, 30, 30, 0) && cellList[i, j - 1].selected != true) { return false; } if (cellList[i, j].radius == new CornerRadius(30, 30, 0, 0) && cellList[i + 1, j].selected != true) { return false; } if (cellList[i, j].radius == new CornerRadius(0, 0, 30, 30) && cellList[i - 1, j].selected != true) { return false; } if (cellList[i, j].radius == new CornerRadius(30, 0, 0, 30) && j - 1 > 0 && cellList[i, j - 1].granica != true) { return false; } if (cellList[i, j].radius == new CornerRadius(0, 30, 30, 0) && j + 1 < gridSize - 1 && cellList[i, j + 1].granica != true) { return false; } if (cellList[i, j].radius == new CornerRadius(30, 30, 0, 0) && i - 1 > 0 && cellList[i - 1, j].granica != true) { return false; } if (cellList[i, j].radius == new CornerRadius(0, 0, 30, 30) && i + 1 < gridSize - 1 && cellList[i + 1, j].granica != true) { return false; } return true; } private void calcCounters() { int k = 0; int n = 0; if (settings.showCounters == true) { foreach (var x in GameField.Children.OfType()) { if (x.Tag != null && x.Tag.ToString() == "сounterX" + k) { int counter = 0; for(int i = 0; i < gridSize; i++) { if(cellList[i, k].selected) { counter++; } } if(counter.ToString() == xCords[k]) { x.Content = "✔️"; x.Foreground = Brushes.Green; } else { x.Content = counter; x.Foreground = Brushes.Black; } k++; } if (x.Tag != null && x.Tag.ToString() == "сounterY" + n) { int counter = 0; for (int i = 0; i < gridSize; i++) { if (cellList[n, i].selected) { counter++; } } if (counter.ToString() == yCords[k]) { x.Content = "✔️"; x.Foreground = Brushes.Green; } else { x.Content = counter; x.Foreground = Brushes.Black; } n++; } } } } private void kletka_click(object sender, MouseButtonEventArgs e) { string tag = (sender as Border).Tag.ToString(); string name = (sender as Border).Name.ToString(); int i = Int32.Parse(tag[0].ToString()); int j = Int32.Parse(tag[2].ToString()); cellList[i, j].selected = !cellList[i, j].selected; cellList[i, j].granica = false; cellList[i, j].autoCreatedGranica = false; for (int k = 0; k < gridSize; k++) { for (int n = 0; n < gridSize; n++) { cellList[k, n].lastChange = false; } } cellList[i, j].lastChange = true; if (cellList[i, j].selected) { cellList[i, j].bg = Brushes.Black; } else { cellList[i, j].bg = Brushes.Transparent; } if ((j - 1 < 0 || cellList[i, j - 1].granica == true || cellList[i, j - 1].autoCreatedGranica == true) && j + 1 < gridSize - 1 && cellList[i, j + 1].selected == true) { cellList[i, j].radius = new CornerRadius(30, 0, 0, 30); draw(); return; } if ((j + 1 > gridSize - 1 || cellList[i, j + 1].autoCreatedGranica == true || cellList[i, j + 1].granica == true) && j - 1 > 0 && cellList[i, j - 1].selected == true) { cellList[i, j].radius = new CornerRadius(0, 30, 30, 0); draw(); return; } if ((i - 1 < 0 || cellList[i - 1, j].granica == true || cellList[i - 1, j].autoCreatedGranica == true) && i + 1 < gridSize - 1 && cellList[i + 1, j].selected == true) { cellList[i, j].radius = new CornerRadius(30, 30, 0, 0); draw(); return; } if ((i + 1 > gridSize - 1 || cellList[i + 1, j].granica == true || cellList[i + 1, j].autoCreatedGranica == true) && i - 1 > 0 && cellList[i - 1, j].selected == true) { cellList[i, j].radius = new CornerRadius(0, 0, 30, 30); draw(); return; } draw(); if(settings.autoSubmit) { if(checkAnswers() == true) { MessageBox.Show("success!!"); } } if(settings.complited) { checkAnswers(); } return; } private void kletka_right_click(object sender, MouseButtonEventArgs e) { string tag = (sender as Border).Tag.ToString(); string name = (sender as Border).Name.ToString(); int i = Int32.Parse(tag[0].ToString()); int j = Int32.Parse(tag[2].ToString()); for (int k = 0; k < gridSize; k++) { for (int n = 0; n < gridSize; n++) { cellList[n, k].lastChange = false; } } cellList[i, j].lastChange = true; if (cellList[i, j].granica == true) { cellList[i, j].selected = false; cellList[i, j].bg = Brushes.Transparent; cellList[i, j].granica = false; cellList[i, j].radius = new CornerRadius(0); } else { cellList[i, j].selected = false; cellList[i, j].bg = Brushes.Aqua; cellList[i, j].granica = true; cellList[i, j].radius = new CornerRadius(0); } cellList[i, j].lastChange = true; draw(); } private void handleCheck(object sender, RoutedEventArgs e) { bool result = checkAnswers(); if (result) { MessageBox.Show("Ви пройшли рівень!!!"); gameTimer.Stop(); } else { MessageBox.Show("У рішенні є помилка!!!"); } } private void restart_click(object sender, RoutedEventArgs e) { for (int j = 0; j < gridSize; j++) { int yPos = startY + (cellSize * j) + cellGap * (j - 1); for (int i = 0; i < gridSize; i++) { int xPos = startX + (cellSize * i) + cellGap * (i - 1); string id = j.ToString() + "-" + i.ToString(); cellList[j, i] = new Kletka(xPos, yPos, id); } } secondsPlayed = 0; TimeSpan time = TimeSpan.FromSeconds(secondsPlayed); string formattedTime = string.Format("{0:D2}:{1:D2}:{2:D2}", time.Hours, time.Minutes, time.Seconds); GameTimer.Content = formattedTime; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { save1[i, j] = new Kletka(0, 0, "id"); save2[i, j] = new Kletka(0, 0, "id"); save3[i, j] = new Kletka(0, 0, "id"); } } draw(); } private bool checkAnswers() { int i = 0; int j = 0; int[] xCordsCur = { 0, 0, 0, 0, 0, 0 }; int[] yCordsCur = { 0, 0, 0, 0, 0, 0 }; bool res = true; foreach (var x in GameField.Children.OfType()) { if (x.Tag == null) { continue; } if (j > gridSize - 1) { j = 0; i++; } if (cellList[i, j].selected == true) { xCordsCur[j]++; yCordsCur[i]++; } j++; } for(int k = 0; k < xCordsCur.Length; k++) { if (xCordsCur[k].ToString() != xCords[k]) { res = false; } else { if(settings.complited == true) { foreach (var x in GameField.Children.OfType()) { if(x.Tag != null && x.Tag.ToString() == "x" + k) { x.Opacity = 0.35; } else { x.Opacity = 1; } } } } } for (int k = 0; k < yCordsCur.Length; k++) { if (yCordsCur[k].ToString() != yCords[k]) { res = false; } else { if (settings.complited == true) { foreach (var x in GameField.Children.OfType()) { if (x.Tag != null && x.Tag.ToString() == "y" + k) { x.Opacity = 0.6; } } } } } return res; } private void save(object sender, RoutedEventArgs e) { string tag = (sender as Button).Tag.ToString(); if (tag == "save1") { for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { save1[i, j].bg = cellList[i, j].bg; save1[i, j].selected = cellList[i, j].selected; save1[i, j].x = cellList[i, j].x; save1[i, j].y = cellList[i, j].y; save1[i, j].radius = cellList[i, j].radius; save1[i, j].y = cellList[i, j].y; save1[i, j].id = cellList[i, j].id; save1[i, j].granica = cellList[i, j].granica; } } } if (tag == "save2") { for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { save2[i, j].bg = cellList[i, j].bg; save2[i, j].selected = cellList[i, j].selected; save2[i, j].x = cellList[i, j].x; save2[i, j].y = cellList[i, j].y; save2[i, j].radius = cellList[i, j].radius; save2[i, j].y = cellList[i, j].y; save2[i, j].id = cellList[i, j].id; save2[i, j].granica = cellList[i, j].granica; } } } if (tag == "save3") { for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { save3[i, j].bg = cellList[i, j].bg; save3[i, j].selected = cellList[i, j].selected; save3[i, j].x = cellList[i, j].x; save3[i, j].y = cellList[i, j].y; save3[i, j].radius = cellList[i, j].radius; save3[i, j].y = cellList[i, j].y; save3[i, j].id = cellList[i, j].id; save3[i, j].granica = cellList[i, j].granica; } } } } private void load(object sender, RoutedEventArgs e) { string tag = (sender as Button).Tag.ToString(); if (tag == "save1" && save1 != null) { bool empty = true; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { if(save1[i, j].id != "id") { empty = false; } } } if (empty) return; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { cellList[i, j].bg = save1[i, j].bg; cellList[i, j].selected = save1[i, j].selected; cellList[i, j].x = save1[i, j].x; cellList[i, j].y = save1[i, j].y; cellList[i, j].radius = save1[i, j].radius; cellList[i, j].y = save1[i, j].y; cellList[i, j].id = save1[i, j].id; cellList[i, j].granica = save1[i, j].granica; } } draw(); } if (tag == "save2" && save2 != null) { bool empty = true; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { if (save2[i, j].id != "id") { empty = false; } } } if (empty) return; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { cellList[i, j].bg = save2[i, j].bg; cellList[i, j].selected = save2[i, j].selected; cellList[i, j].x = save2[i, j].x; cellList[i, j].y = save2[i, j].y; cellList[i, j].radius = save2[i, j].radius; cellList[i, j].y = save2[i, j].y; cellList[i, j].id = save2[i, j].id; cellList[i, j].granica = save2[i, j].granica; } } draw(); } if (tag == "save3" && save3 != null) { bool empty = true; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { if (save3[i, j].id != "id") { empty = false; } } } if (empty) return; for (int i = 0; i < gridSize; i++) { for (int j = 0; j < gridSize; j++) { cellList[i, j].bg = save3[i, j].bg; cellList[i, j].selected = save3[i, j].selected; cellList[i, j].x = save3[i, j].x; cellList[i, j].y = save3[i, j].y; cellList[i, j].radius = save3[i, j].radius; cellList[i, j].y = save3[i, j].y; cellList[i, j].id = save3[i, j].id; cellList[i, j].granica = save3[i, j].granica; } } draw(); } } private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) { } private void CheckBox_Click(object sender, RoutedEventArgs e) { string tag = (sender as CheckBox).Tag.ToString(); switch (tag) { case "autoSubmit": { settings.autoSubmit = !settings.autoSubmit; break; } case "hideTimer": { settings.hideTimer = !settings.hideTimer; GameTimer.Opacity = settings.hideTimer ? 0 : 100; break; } case "nightMode": { settings.nightMode = !settings.nightMode; GameField.Background = settings.nightMode ? Brushes.Gray : Brushes.BlanchedAlmond; break; } case "lastChange": { settings.lastChange = !settings.lastChange; break; } case "errors": { settings.errors = !settings.errors; draw(); break; } case "complited": { settings.complited = !settings.complited; break; } case "coordinates": { string cords = "abcdef"; settings.coordinates = !settings.coordinates; if (settings.coordinates) { for(int i = 0; i < gridSize; i++) { Label newLabel = new Label { Content = cords[i], FontSize = 22, Foreground = Brushes.Gray, Tag = "coord", }; Canvas.SetLeft(newLabel, startX + (cellSize / 2) - 11 + (i * gridSize * 8.4)); Canvas.SetTop(newLabel, startY - cellSize * 1.25); GameField.Children.Add(newLabel); Label newLabel2 = new Label { Content = cords[i], FontSize = 22, Foreground = Brushes.Gray, Tag = "coord", }; Canvas.SetLeft(newLabel2, startX + (cellSize / 2) - 11 + (i * gridSize * 8.4)); Canvas.SetTop(newLabel2, startY - cellSize * 1.25 + gridSize * 64); GameField.Children.Add(newLabel2); } for (int i = 0; i < gridSize; i++) { Label newLabel = new Label { Content = i + 1, FontSize = 22, Foreground = Brushes.Gray, Tag = "coord", }; Canvas.SetTop(newLabel, startX + (cellSize / 2) - 22 + (i * gridSize * 8.4)); Canvas.SetLeft(newLabel, startY - cellSize * 1.25); GameField.Children.Add(newLabel); Label newLabel2 = new Label { Content = i + 1, FontSize = 22, Foreground = Brushes.Gray, Tag = "coord", }; Canvas.SetTop(newLabel2, startX + (cellSize / 2) - 22 + (i * gridSize * 8.4)); Canvas.SetLeft(newLabel2, startY - cellSize * 1.25 + gridSize * 64); GameField.Children.Add(newLabel2); } } else { foreach (var x in GameField.Children.OfType()) { if(x.Tag != null && x.Tag.ToString() == "coord") { x.Opacity = 0; } } } break; } case "autoWater": { settings.autoWater = !settings.autoWater; break; } case "showCounters": { settings.showCounters = !settings.showCounters; if(settings.showCounters) { for (int i = 0; i < gridSize; i++) { Label newLabel = new Label { Content = 1, FontSize = 14, Foreground = Brushes.Gray, Tag = "сounterY" + i, }; Canvas.SetLeft(newLabel, startX + (cellSize / 2) - 11 + gridSize * 48); Canvas.SetTop(newLabel, startY + (i * gridSize * 8.4) + 11); GameField.Children.Add(newLabel); Label newLabel2 = new Label { Content = 1, FontSize = 14, Foreground = Brushes.Gray, Tag = "сounterX" + i, }; Canvas.SetLeft(newLabel2, startX + (cellSize / 2) - 11 + (i * gridSize * 8.4)); Canvas.SetTop(newLabel2, startY - cellSize * 1.75 + gridSize * 64); GameField.Children.Add(newLabel2); } calcCounters(); } else { foreach (var x in GameField.Children.OfType()) { if (x.Tag != null && x.Tag.ToString().StartsWith("сounter")) { x.Opacity = 0; } } } break; } } } } } ///MainWindow.xaml xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:kurs_bogdan_reference" mc:Ignorable="d" Title="MainWindow" Height="800" Width="800"> Бачурський Б.І.