Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 

Repository files navigation

🎮 2048 — Классическая головоломка

.NET C# WinForms JSON Newtonsoft.Json

Реализация игры 2048 на Windows Forms. Без анимаций и таймеров — всё построено на прямом управлении Label-элементами, тройных вложенных циклах и линейном поиске. Поддерживается выбор размера поля от 4×4 до 8×8.


✨ Особенности

  • 🎯 Полная механика игры 2048: движение, слияние плиток, подсчёт очков
  • 🧩 Игровое поле собрано из WinForms-элементов Label
  • 📐 Настраиваемый размер поля — можно играть на сетке от 4×4 до 8×8
  • 💾 Сохранение результатов всех игроков в result.json с поиском лучшего счёта по имени
  • 🏁 Игра продолжается и по достижении 2048, поражение засчитывается если нет доступных ходов
  • 📋 Используется Newtonsoft.Json для сериализации и собственный FileManager для работы с файлами

🧱 Как устроена логика

Игровое поле — это не просто двумерный массив чисел, а сетка из Label-элементов. Её размер задаётся переменной mapSize и может быть от 4 до 8. Все алгоритмы (движение, слияние, спавн) написаны через циклы, привязанные к mapSize, поэтому работают корректно при любом размере поля.

image

При нажатии на стрелки происходит следующее:

  1. Движение плитки с помощью тройного цикла.
  2. Сравнение текста — у двух Label-элементов считывается свойство Text. Если значения равны — происходит слияние с удвоением.
  3. Визуальное обновление — победившая плитка перекрашивается, проигравшая очищается и становится серой.
  4. Генерация новой плитки — после каждого хода в случайную свободную клетку добавляется 2 (с шансом 75%) или 4 (с шансом 25%).

Движение вправо (реальный код)

private void PressRight()
{
    for (var i = 0; i < mapSize; i++)
    {
        for (var j = mapSize - 1; j >= 0; j--)
        {
            if (labelsMap[i, j].Text != string.Empty)
            {
                for (var k = j - 1; k >= 0; k--)
                {
                    if (labelsMap[i, k].Text != string.Empty)
                    {
                        if (labelsMap[i, j].Text == labelsMap[i, k].Text)
                        {
                            var number = int.Parse(labelsMap[i, j].Text);
                            score += number * 2;

                            labelsMap[i, j].Text = (number * 2).ToString();
                            SetColor(labelsMap[i, j]);

                            labelsMap[i, k].Text = string.Empty;
                            labelsMap[i, k].BackColor = Color.Silver;
                        }
                        break;
                    }
                }
            }
        }
    }
    GenerateNumber();
    ShowScore();
}

Поиск пустой клетки для спавна

private List<(int, int)> LinearSearch()
{
    var emptyLabels = new List<(int Row, int Column)>();

    for (var i = 0; i < mapSize; i++)
    {
        for (var j = 0; j < mapSize; j++)
        {
            if (labelsMap[i, j].Text == string.Empty)
            {
                emptyLabels.Add((i, j));
            }
        }
    }

    return emptyLabels;
}

💾

Сохранение результатов

Все результаты хранятся в файле result.json. После каждого завершения игры запись добавляется в общую таблицу рекордов.

// Получение лучшего результата игрока по имени
public static int GetBestResult(string name)
{
    var usersResult = GetAll();
    var results = new List<string[]>();

    // Фильтруем — собираем все партии этого игрока
    foreach (var result in usersResult)
    {
        if (result[0] == name)
        {
            results.Add(result);
        }
    }

    // Ищем максимальный счёт линейным перебором
    var bestResult = 0;
    foreach (var result in results)
    {
        if (int.Parse(result[1]) > bestResult)
        {
            bestResult = int.Parse(result[1]);
        }
    }

    return bestResult;
}
// Сохранение всего списка результатов в JSON
public static void Save(List<string[]> results)
{
    var data = JsonConvert.SerializeObject(results, Formatting.Indented);
    FileManager.Save(Path, data);
}

🎮 Как играть

  1. При запуске выберите размер поля (от 4×4 до 8×8).
  2. Управляйте плитками стрелками на клавиатуре (← ↑ → ↓ или клавишами wasd).
  3. Одинаковые плитки при столкновении сливаются, удваивая номинал.
  4. Цель — добраться до плитки с числом 2048 или выше.
  5. Игра заканчивается в случае выхода или поражением (не осталось ходов).

🖼️ Как это выглядит

image image image image image

🛠️ Технологии и инструменты

Что применял в коде

  • Прямое управление Label-элементами.
  • Динамическая генерация интерфейса.
  • Тройные вложенные циклы.
  • Линейный поиск.
  • Newtonsoft.JsonJsonConvert.SerializeObject() с Formatting.Indented, JsonConvert.DeserializeObject<List<string[]»().
  • Собственный FileManager.
  • ООП.
  • Работа со строками и числамиint.Parse() / ToString() для преобразования значений на плитках.

About

Реализация игры 2048 на Windows Forms.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages