Кодерские работы 👾
104 subscribers
166 photos
17 videos
1 file
39 links
Теперь я тут обитаю и немного программирую.
Download Telegram
🧩 Рефакторинг Game of Life — Часть 1: Игровая логика


Привет! 👋 Сегодня начну разбор тотального рефакторинга моего старого проекта — игры «Жизнь».
Покажу, как я вычистил игровую логику: от монолитной кучи до внятной архитектуры 🔄


🚨 Проблема №1: God Object — когда один класс правит всем


🧠 Всё в одном классе: логика, отрисовка, ввод, состояния.
💀 Результат:
• Невозможно понять, где что происходит
• Одно изменение ломает три других
• Логика намертво привязана к WinForms

📸 Старый код на изображении 1

✅ Решение: разделяй и властвуй


Я разнёс код по модулям по смыслу 👇 (изображение 2)
Теперь:
• Каждый класс делает только своё дело
• Чтобы понять работу с полем — читаю только TileMap (100 строк вместо 500)
• Изменения изолированы
• Таймеры, графика и мышь теперь не зависят от логики игры

🚨 Проблема №2: Неявное управление состоянием


Пауза, рисование и возобновление были размазаны по коду 😵 (изображение 3)

Почему это проблема? 😤
❌ Неочевидное поведение
❌ Баги при добавлении функций
❌ Добавил «режим редактирования»? Теперь нужно обновить *все места*, где проверяется isStop. Забыл одно — баг 🐛

✅ Решение: State Machine 🧠


Добавил систему состояний (изображение 4)
Теперь переходы прозрачны (изображение 5)
Добавить новое состояние? Просто создаёшь новый класс. Всё.

🚨 Проблема №3: Логика и отрисовка перемешаны 🤦‍♂️


Расчёт поколений и рисование были в одном методе (изображение 6)
Итог:
• нельзя рассчитать без рисования (1000 поколений = 1000 отрисовок)
• нельзя перерисовать без пересчёта
• профилировать больно

✅ Решение: Model и View отдельно 🎨


Model — чистая логика (изображение 7)
View — отдельный рендерер

Теперь:
✅ Можно рассчитать без рисования
✅ Можно перерисовать без логики
✅ Можно менять визуал хоть на OpenGL

🚨 Проблема №4: Массивы повсюду


Три массива (arrayCell, nextArrayCell, lastArrayCell) в разных методах.
Постоянные проверки x < columns && y < rows и куча багов с индексами 🐛 (изображение 8)

✅ Решение: инкапсуляция в TileMap


Всё спрятано в одном месте 👇 (изображение 9)
Теперь:
• Один источник правды
• Нет багов с индексами
• Оптимизация централизована

🚨 Проблема №5: Правила игры захардкожены


if (!hasLife && textBoxB.Text.Contains(...))
😬 Логика зависела от UI.

✅ Решение: GameSettings + CellType Registry (изображение 10)


Теперь каждый тип клетки знает свои правила,
а логика просто спрашивает у неё, что делать.

🔥 Можно легко добавить свои типы клеток
🔥 Свои правила
🔥 Даже комбинировать их — никаких ограничений!


🎯 Главные принципы


1️⃣ Single Responsibility Principle — каждый класс делает одно дело
2️⃣ Separation of Concerns — логика, UI, данные — раздельно
3️⃣ Encapsulation — детали реализации скрыты
4️⃣ Open/Closed Principle — легко расширять, не меняя старый код
5️⃣ Dependency Inversion — логика не зависит от UI



🔥 Выводы

Рефакторинг — это не «переписать красиво».
Это решение конкретных проблем 👇

1️⃣ Сложно понять код? → Раздели на классы
2️⃣ Баги при изменениях? → Инкапсулируй
3️⃣ Невозможно тестировать? → Отдели логику от UI
4️⃣ Трудно расширять? → Используй паттерны (State, Registry)

Ставь 🔥 если было полезно!
🔥7💋1
Game of Life: Иморт изображений.


😜 Иногда я могу так скажем сильно увлечься.
🫡 Собственно, как сейчас.

👾 В старом проекте была возомжность имортнуть файл и он бы отрисовлася по клеткам, там просто бралось среднее значение по RGB и если больше определенного значения, то клетка в белый красилась.

🚀 Но в новом я решил пойти дальше и юзаю различные алгоритмы для обработки краев, чтобы сделать контур.

⚙️ Но это не все, ведь пользователь сможет сам выбрать нужный пресет, по которому потом создатся поле.

🛠 Пока готова просто обработка фоток и их превью.
❤2🔥1💋1
👾 Ура, оно работает!
⚙️ Можно импортнуть любую фотку выбрать пресет и она конвертируется в поле клеточное.
💻 Также чутка обновил интерфейс.
🔥8💋1
Channel name was changed to «Кодерские работы 👾»
🏎 Пытаюсь как-то оптимзировать рендер, чтобы GPS (Generation Per Second) был как можно выше при больших размерах карты.

👀 Сначала делал это на глаз, иногда было очевидно, хуже сделали мои нововведения или лучше.

☝️ Но не всегда.
📊 Поэтому добавил в правый верхний угол такую удобную менюшку со статистикой.
🔥6💋1
👾 Game of Life First Release


⚙️ Главной целью было отрефакторить старый код, но я сделал куда больше:
- WinForms > Wpf
- Импорт фото
- Запись эволюции

🔗 Потестировать можете тут (https://github.com/W1xon/Game-of-Life/releases/tag/v1.0.0)

🏎️ Оптимизация
🐢 Как оказалось двумерный массив int [,] в качестве поя- не прям уж эффективен, перешел на int[].

🛠️ Затем изменил логику обработки поля, вместо вложенных циклов, которые перебирают int[,] заюзал unsafe код и указатели в одном цикле.

✏️ Отрисовку картинки тоже изменил, вместо рисования всей картинки фиксируем только изменившееся клетки и перерисовывает эти области.

🏆 Как итог средний прирост GPS и составил примерно в 2 - 2.5 раза, то особенно заметно стало при импорте больших изображений.

Окно слева - старый
окно справа - новый


⚠️ В версии 1.0.0 используется не оптимизированный рендеринг, он будет в следующем релизе.
❤2🔥2💋1