Олдфаг
			
			
				
					
				
			
		- Статус
 - Оффлайн
 
- Регистрация
 - 18 Фев 2019
 
- Сообщения
 - 2,842
 
- Реакции
 - 1,853
 
Всем привет! Моя недавняя тема по созданию простейшей игры на C# получила относительную для этого раздела популярность. Я давно хотел ее продолжить, но что-то никак не доходили руки 
. Во второй части создания этого "чудо" проекта я покажу, как сохранять всю информацию в реестр и воспроизводить ее от-туда (до этого хотел показать создание многопользовательской игры, посредствам передачи сокетов, но подумал отложить это идею до лучших времен).
Показывать, как размещать элементы на форме (как передвинуть кнопки и добавить menuStrip), я не буду, так как эта информация не пригодится почти никому (я полагаю, что большая часть, читающая данную тему понимает, как добавить элемент на форму) и займет достаточно много места в самой статье.
Первым делом создадим переменную, в которой будет храниться история побед. Формат записи: 0/1/2, где 0 - ничья, 1 - победа Х, а 2 - победа 0, / - разделитель
Далее, будем добавлять один символ в WinsReg после победы одной из сторон или ничьи
Добавим сразу после
		
		
	
	
		
	
Аналогично делаем с крестиками (+="/1") и ничьей (+="/0").
Отлично, теперь нужно создать класс для работы с реестром и начинать работу с ним. Я назвал класс Memory, вы можете придумать что-то более оригинальное.
Для начала, подключим класс для работы с самим реестром системы
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Чтобы было меньше кода, я создал переменную regKeyName, в которой будет храниться "путь" к нашему ключу в реестре.
WinsKey нужен для загрузки побед в WinsReg из нашей первой формы. Были и другие идеи, но эта оказалась наиболее простой и красивой (но это не точно
).
Теперь, создадим функцию записи значений в реестр (также она создает ключ по нашему "пути")
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Теперь, написав 
.
После создания функции записи в реестр, нужно также создать функцию чтения реестра
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Теперь, написав 
.
Осталось только использовать наши функции из класса Memory в главном файле - Form1.cs
Запихиваем это в обработчик загрузки формы (Form1_Load())
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Дальнейший код я хотел расписать более подробно в самой статье, но из-за ограничения на повторяющиеся BB-коды, я запихну все в один элемент
	
	
	
	
	
	
		
			
			
			
			
			
		
	
	
	
		
	
	
		
	
Обработчики событий этих элементов вы найдете сами, надеюсь, что не глупые 
А вот и итоговый скриншот нашей игры:
		
	
Также можно добавить запрос на запуск с правами администратора. Для этого, добавьте в Program.cs следующий код:
Если же у вас есть пожелания к новым урокам или я допустил ошибку в коде/в оформлении гайда, прошу отписать мне в лс или же в саму тему.
Готовый исходник игры с дополнительными пояснениями:
Готовая игра:
VT на игру:
				
			
. Во второй части создания этого "чудо" проекта я покажу, как сохранять всю информацию в реестр и воспроизводить ее от-туда (до этого хотел показать создание многопользовательской игры, посредствам передачи сокетов, но подумал отложить это идею до лучших времен).Показывать, как размещать элементы на форме (как передвинуть кнопки и добавить menuStrip), я не буду, так как эта информация не пригодится почти никому (я полагаю, что большая часть, читающая данную тему понимает, как добавить элемент на форму) и займет достаточно много места в самой статье.
Первым делом создадим переменную, в которой будет храниться история побед. Формат записи: 0/1/2, где 0 - ничья, 1 - победа Х, а 2 - победа 0, / - разделитель
string WinsReg = "";Далее, будем добавлять один символ в WinsReg после победы одной из сторон или ничьи
WinsReg += "/2";Добавим сразу после
Аналогично делаем с крестиками (+="/1") и ничьей (+="/0").
Отлично, теперь нужно создать класс для работы с реестром и начинать работу с ним. Я назвал класс Memory, вы можете придумать что-то более оригинальное.
Для начала, подключим класс для работы с самим реестром системы
using Microsoft.Win32; и напишем нужные для нас функции.
			
				Код:
			
		
		
		static string regKeyName = "Software\\Yougame.biz\\TicTacToe";
public static string WinsKey = "";
	WinsKey нужен для загрузки побед в WinsReg из нашей первой формы. Были и другие идеи, но эта оказалась наиболее простой и красивой (но это не точно
).Теперь, создадим функцию записи значений в реестр (также она создает ключ по нашему "пути")
			
				Код:
			
		
		
		public static void WriteMemory(string Wins) // Публичная функция записи переменных в реестр
        {
            // Wins - переменная со статистикой побед. Записывать их мы будем в формате 1/2/1/1/2/0, где 0 - ничья, 1 - крестики, 2 - нолики, а / - разделитель
            RegistryKey rk = null; // Создаем переменную класса RegistryKey для работы с ключами реестра
            try // try (с англ. "пытаться") - пробуем занести переменные в реестр
            {
                rk = Registry.CurrentUser.CreateSubKey(regKeyName); // Создаем ключ в реестре по пути, указанном в regKeyName
                if (rk == null) return; // Если создание ключа не удалось (по каким-либо причинам закрыт доступ к реестру), то rk остается равным null (нулю)
                rk.SetValue("Wins", Wins); // Создаем еще один ключ из переменной Wins
            }
            finally // Цикл, выполняющийся при ошибке/при успешном выполнении try(), т.е. всегда
            {
                if (rk != null) rk.Close(); // Если программа создала новый ключ (rk получит доступ к реестру и создаст коюч из regKeyName), закрываем поток
            }
        }
	Memory.WriteMemory("Irval") в любой (почти) части кода из Form1.cs, мы получим это (
	Пожалуйста, авторизуйтесь для просмотра ссылки.
), но то, что мы получили никак не касается "Крестиков-ноликов", поэтому нужно это удалить 
.После создания функции записи в реестр, нужно также создать функцию чтения реестра
			
				Код:
			
		
		
		public static void ReadMemory() // Функция чтение реестра
        {
            RegistryKey rk = null; // Повторно создаем переменную класса для работы с ключами
            try
            {
                rk = Registry.CurrentUser.CreateSubKey(regKeyName); // Создаем новый ключ
                if (rk != null) // Если создание ключа удалось, то выполняем следующие действия
                {
                    WinsKey = (string)rk.GetValue("Wins"); // Записываем информацию в переменную Wins
                }
            }
            finally
            {
                if (rk != null) rk.Close(); // Закрываем поток
            }
        }
	Memory.ReadMemory() там же, где мы писали вызов функции WriteMemory(), мы изменим значения переменной WinsKey на "Irval", так как программа считала значение с реестра. Поздравляю, этот код тоже нужно стирать 
.Осталось только использовать наши функции из класса Memory в главном файле - Form1.cs
Запихиваем это в обработчик загрузки формы (Form1_Load())
			
				Код:
			
		
		
		// Обновляем  Wins
            Memory.ReadMemory();
            WinsReg = Memory.WinsKey;
            if (WinsReg == null)
                Memory.WriteMemory(""); // Создаем ключ в реестре с победами, если его нет или он был удален
            Memory.ReadMemory();
            WinsReg = Memory.WinsKey; // Повторно задаем значения WinsReg. Можно было сделать иначе, например создать функцию обновления, но я посчитал это лишним
	
			
				Код:
			
		
		
		private void Form1_FormClosing(object sender, FormClosingEventArgs e) // Обработчик события выхода из формы. Возникает до того, как форма была закрыта
        {
            Memory.WriteMemory(WinsReg); // Записываем значение WinsReg в реестр
        }
        private void ВыходToolStripMenuItem_Click(object sender, EventArgs e) // Событие нажатия на "Выход" из нашего ToolStrip
        {
            this.Close(); // Закрываем форму
        }
        private void СтатистикаToolStripMenuItem_Click(object sender, EventArgs e) // Событие нажатия на "Статистику" из ToolStrip на форме
        {
            String[] AllWins = WinsReg.Split(new char[] { '/' }, StringSplitOptions.None); // Массив с победами. Он понадобится для подсчета выигрышей каждой стороны
            int[] EachWins = { 0, 0, 0 }; // Итоговый массив побед
            for (int i = 0; i < AllWins.Length; i++) // Перебираем все элементы массива AllWins. Можно было использовать foreach
            {
                switch(AllWins[i]) // switch для каждого из трех значений элемента из AllWins
                {
                    case "0": // 0 значение - ничья
                        {
                            EachWins[0]++; // Прибавляем 1 к ничьим
                            break; // Выход из switch
                        }
                    case "1": // 1 значение - победа крестиков
                        {
                            EachWins[1]++; // Прибавляем 1 к крестикам
                            break;
                        }
                    case "2": // 2 значение - победа ноликов
                        {
                            EachWins[2]++; // Прибавляем 1 к ноликам
                            break;
                        }
                }
            }
          
            // Объявление переменных с процентом побед
            decimal Wx = 0;
            decimal Wo = 0;
            decimal Draw = 0;
            if (EachWins[0] + EachWins[1] + EachWins[2] != 0)  // Если произойдет попытка деления на ноль
            {
                //Подсчет процентов побед
                Wx = (Int32)(EachWins[1] / ((EachWins[0] + EachWins[1] + EachWins[2]) / 100M));
                Wo = (Int32)(EachWins[2] / ((EachWins[0] + EachWins[1] + EachWins[2]) / 100M));
                Draw = (Int32)(EachWins[0] / ((EachWins[0] + EachWins[1] + EachWins[2]) / 100M));
            }
            MessageBox.Show("Побед крестиков: " + EachWins[1] + " (" + Wx + "%)" + "\n" + "Побед ноликов: " + EachWins[2] + " (" + Wo + "%)" + "\n" + "Ничьих: " + EachWins[0] + " (" + Draw + "%)", "Статистика", MessageBoxButtons.OK); // Выводим MessageBox со статистикой побед
        private void СбросToolStripMenuItem_Click(object sender, EventArgs e) // Событие нажатия на кнопку сброса из ToolStrip
        {
            WinsReg = ""; // Сбрасываем переменную WinReg. При закрытии формы, ее значение занесется в реестр
            MessageBox.Show("Статистика была обнулена!", "Статистика", MessageBoxButtons.OK); // Вывод сообщения о сбросе статистики
        }
	
А вот и итоговый скриншот нашей игры:
Также можно добавить запрос на запуск с правами администратора. Для этого, добавьте в Program.cs следующий код:
	Пожалуйста, авторизуйтесь для просмотра ссылки.
Если же у вас есть пожелания к новым урокам или я допустил ошибку в коде/в оформлении гайда, прошу отписать мне в лс или же в саму тему.
Готовый исходник игры с дополнительными пояснениями:
	Пожалуйста, авторизуйтесь для просмотра ссылки.
Готовая игра:
	Пожалуйста, авторизуйтесь для просмотра ссылки.
VT на игру:
	Пожалуйста, авторизуйтесь для просмотра ссылки.
			
				Последнее редактирование: