Skip to content

Repository files navigation

♟️ Chess WPF

Двогравцева шахова гра, написана на C# та WPF (.NET Framework), з повною реалізацією правил шахів, графічним інтерфейсом та таймером відліку часу для кожного гравця.


🚀 Як запустити локально

  1. Клонуй репозиторій:
    git clone https://github.com/Bohdan-Melnychuk/Final_project_KPZ.git
  2. Відкрий kursach wpf .framework.sln у Visual Studio 2022
  3. Встанови kursach wpf .framework як стартовий проєкт
  4. Натисни F5 для збірки та запуску

Вимоги: Visual Studio 2022, .NET Framework 4.7.2


🎮 Функціональність

Інтерфейс користувача

  • Стартовий екран — запуск гри або вихід з діалогом підтвердження (start.xaml.cs)
  • Шахова дошка — відмальована на WPF Canvas з кольоровими клітинками та декоративною рамкою (Board.cs, рядки 187–215)
  • Маркери ходів — точки для доступних ходів, іконки атаки для захоплення ворожих фігур, червона підсвітка при шаху королю (Board.cs, рядки 256–295)
  • Діалог перетворення пішака — інтерактивне вікно вибору фігури: Ферзь, Тура, Слон або Кінь (ChoosingFigure.xaml.cs, рядки 29–31)
  • Екран результату — відображає переможця або нічию з кнопкою повернення в меню (Page1.xaml.cs)

Шахова логіка

  • Усі 6 типів фігур з правильними правилами ходів: Король, Ферзь, Тура, Слон, Кінь, Пішак
  • Виявлення шаху — усі ходи що залишають Короля під шахом заблоковані (Figure.cs, рядки 93–95)
  • Виявлення мату та пату (Board.cs, рядки 473–476)
  • Рокіровка — коротка та довга (King.cs, рядки 155–188)
  • Перетворення пішака — асинхронний діалог при досягненні останньої горизонталі (Pawn.cs, рядки 126–147)
  • Умови нічиї — недостатній матеріал (≤3 фігури) та правило 50 ходів (Board.cs, рядки 539–554)

Таймер


🏗️ Структура проєкту

kursach wpf .framework/
├── Figure.cs              # Абстрактний базовий клас для всіх шахових фігур
├── Board.cs               # Дошка, логіка ходів, таймер, стан гри
├── Cell.cs                # Представлення клітинки дошки
├── King.cs                # Рух короля, рокіровка, уникнення шаху
├── Queen.cs               # Рух ферзя та захисна логіка
├── Rook.cs                # Рух тури
├── Bishop.cs              # Рух слона
├── Knight.cs              # Рух коня
├── Pawn.cs                # Рух пішака, перетворення
├── MainWindow.xaml(.cs)   # Головне вікно гри
├── start.xaml(.cs)        # Стартовий екран
├── Page1.xaml(.cs)        # Екран результату гри
├── ChoosingFigure.xaml.cs # Діалог перетворення пішака
└── Image/                 # PNG іконки для всіх шахових фігур

🧩 Design Patterns

1. Template Method — Figure.cs

Абстрактний клас Figure визначає скелет алгоритму валідації ходу у методі CanMoveTo() (рядки 81–97):

  1. Перевірка меж дошки
  2. Перевірка зіткнення зі своєю фігурою
  3. Виклик абстрактного CanReach() (рядок 99) — перевизначається у кожному підкласі
  4. Симуляція ходу через WouldKingBeInCheck() (рядки 104–117) — перевіряє чи Король залишився б під шахом

Абстрактні методи що зобов'язані реалізувати всі підкласи оголошені на рядках 28–30. Підкласи перевизначають лише потрібні кроки, не змінюючи загальний алгоритм.

Кожна фігура реалізує власну стратегію руху у MoveFigure(), перемикаючись між двома алгоритмами залежно від стану гри:

Перемикання між стратегіями відбувається через перевірку IsKingInCheck() (Queen.cs, рядок 30). Board викликає MoveFigure() однаково для всіх фігур (Board.cs, рядок 475), не знаючи конкретної стратегії кожної фігури.

3. Composite — Board.cs

Board керує всією колекцією Figure та взаємодіє з ними однаково через абстрактний клас:


🔧 Programming Principles

1. Single Responsibility Principle (SRP)

Кожен клас має одну причину для зміни:

2. Open/Closed Principle (OCP)

Figure відкритий для розширення, але закритий для модифікації. Абстрактні методи IsAttacking(), MoveFigure(), FillArrayAttacksCell() (рядки 28–30) дозволяють додати нову фігуру лише через створення нового підкласу — без жодних змін у Board або існуючих фігурах.

3. Liskov Substitution Principle (LSP)

Всі підкласи Figure можна використовувати там де очікується Figure. Board зберігає всі фігури у масиві ArrFigure[,] (рядок 13) типу Figure[,] та отримує їх через GetAllFigures() (рядок 426) — працюючи з ними поліморфно через IsAttacking() та MoveFigure() без перевірки конкретного типу.

4. DRY (Don't Repeat Yourself)

Спільна логіка сканування напрямків винесена у базовий клас і не дублюється у жодній фігурі:

5. Fail Fast

WouldKingBeInCheck() (рядки 104–117) симулює хід на дошці, одразу перевіряє чи Король опиниться під шахом і скасовує симуляцію. Якщо так — хід негайно відхиляється у CanMoveTo() (рядок 93) ще до відображення маркера гравцю.

6. Separation of Concerns

Ігрова логіка повністю відокремлена від UI. Figure та підкласи містять лише правила шахів. Board відповідає за стан гри та рендеринг маркерів на Canvas. MainWindow, Page1, start — лише UI без жодної ігрової логіки. Таймер інкапсульований у Board через InitializeTimers() (рядки 40–87).


🔨 Refactoring Techniques

1. Extract Method

Довга логіка ходів розбита на приватні методи у кожній фігурі:

2. Extract Superclass

Спільні поля (Color, X, Y, ImageFigure, CellsUnderAttack) та методи (CheckCell, WouldKingBeInCheck, IsBlockedPath, ScanDiagonal, ScanStraight) винесені в абстрактний клас Figure (рядки 17–184), усуваючи дублювання між усіма 6 типами фігур.

3. Replace Conditional with Polymorphism

Замість великого switch на тип фігури — кожен підклас перевизначає IsAttacking(), MoveFigure() та FillArrayAttacksCell(). Board викликає ці методи поліморфно через RefreshAllAttackCell() (рядки 363–375) та IsSquareUnderAttack() (рядки 378–390).

4. Replace Magic Number with Named Constant

Розмір дошки 8 та розмір клітинки 80 зберігаються як іменовані поля boardSize та tileSize (Board.cs, рядки 24–25), що дозволяє змінити розмір дошки в одному місці без пошуку магічних чисел по всьому коду.

5. Separate Query from Modifier

Запити без побічних ефектів відокремлені від модифікуючих методів:

6. Introduce Parameter Object

Методи сканування ScanDiagonal() та ScanStraight() (рядки 161–184) приймають (startX, startY, stepX, stepY) — узгоджену групу параметрів що представляє вектор напрямку. Це замінює розкидану арифметику координат у кожній фігурі єдиним стандартним викликом.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages