Урок начинается с разбора домашнего задания, выполненного школьником, на тему "вычисление суммы и произведения элементов массива при заданных ограничениях на элементы". Выполненная работа отвечает всем правилам, о которых шла речь на прошлых занятиях. Переменные нужным образом объявлялись, правильно были проинициализированы. В операторе if фильтр позволял отобрать нужные элементы для вычисления суммы и произведения.
В предложенном решении прекрасно то, что выполняются требования хорошего стиля программирования, - все элементы управления в форме, все переменные в программном коде имеют содержательные имена, облегчающие понимание сути предлагаемого решения. Что крайне важно, для вычисления суммы и произведения написаны специальные функции.
Единственное существенное замечание состоит в том, что написанные функции следовало снабдить заголовочными комментариями. При их наличии решение может служить эталоном для задач данного типа.
На этом уроке мы откажемся от рассмотрения таких "скучных" задач, как вычисление сумм и нахождения максимумов, а будем играть в умные игры и будем учиться, как создавать программы, реализующие такие игры.
Рассмотрим игру "Отгадай задуманное число" и поиграем в нее. Практически все, кто сыграл в эту игру с компьютером, отгадали задуманное число, получив звание "Магистра игры".
Интерфейс игры показан на рис. 4.1. рис 4.1
(рис 4.1) Интерфейс игры "Задумай число"
Кажется, что спроектированный интерфейс интуитивно понятен. Пользователь может задать уровень игры в соответствующем окне. Кнопка "Новая игра" позволяет очистить окна и перейти к новой игре. Кнопка "Компьютер, задумай число" позволяет начать игру. В зависимости от выбранного уровня игры компьютер выбирает некоторым образом интервал [min, max] и задумывает число в этом интервале. Сообщения о результатах этой работы появляются в соответствующих окошках. После этого пользователь может приступить к отгадыванию задуманного числа, задавая вопросы с помощью кнопок: "Число больше", "Число меньше", "Число равно". Ответы на его вопросы появляются в окне элемента управления ListBox "Вопросы и ответы". Когда пользователь отгадает число, то его результат отображается в окне "Результат". При успехе он получает звание "Магистра игры.
Вот как выглядит интерфейс в процессе игры:
(рис 4.2) Интерфейс проекта в процессе игры
Одна из задач, которую приходится решать в этом проекте, - это генерирование случайных чисел. Числа, которые задумывает компьютер, - это случайные числа.
Для генерирования случайных чисел в библиотеке классов FCL (Framework Class Library), доступной в проектах на C#, есть специальный класс Random, методы которого позволяют генерировать равномерно распределенные случайные числа. Фактически, эти числа нельзя назвать случайными, поскольку они генерируются по определенному алгоритму. Такие числа называют псевдослучайными. Тем не менее генерируемая последовательность чисел отвечает критериям, действующих для "настоящих" случайных чисел.
Чтобы получить случайное число или последовательность таких чисел, как всегда, нужно объявить переменную класса Random. Одного объявления недостаточно, эту переменную (объект) нужно еще и создать, вызвав конструктор объектов класса Random.
Конструктору можно передать целочисленный параметр, например, так:
Random rnd1 = new Random(100);
Переданный конструктору параметр преобразуется по определенным правилам в начальное значение генерируемой последовательности. В этом случае последовательность будет фиксированной. Всякий раз, когда для генерации случайных чисел будет использоваться переменная rnd1, создаваемая последовательность чисел будет одной и той же.
Можно, как обычно делается, параметр конструктору не передавать:
Random rnd = new Random();
В этом случае начальное значение строится по текущему времени компьютера. Поскольку оно всегда разное, то каждый раз генерируется новая последовательность чисел.
У класса Random есть несколько полезных методов. Метод Next, вызываемый переменной класса Random, позволяет получить следующее равномерно распределенное случайное число типа int в заданном интервале [min, max]:
int random_number = rnd.Next(min, max);
Метод NextDouble позволяет получить очередное равномерно распределенное случайное число типа double в интервале [0, 1]:
double drn = rnd.NextDouble();
Если необходимо получать вещественные числа в заданном интервале [min, max], то полученное число несложно привести к нужному интервалу следующими операциями:
drn = drn * (max – min) + min;
Алгоритм, реализующий задуманный сценарий игры, достаточно понятен и относительно прост. Однако, следует признать, что для начинающих программистов проект является сложным. Во многом сложность проекта объясняется тем, что, как для всякой игры, необходимо ввести большое число переменных, позволяющих менять параметры игры (в нашем случае –это уровень игры, границы интервала для задуманного числа, число вопросов для получения звания "Магистр игры", другие параметры). Организация разумного диалога с пользователем требует задания большого числа констант типа string.
Приведу описание констант и переменных, введенных в нашем проекте:
Random rnd = new Random(); //генератор случайных чисел
int number; //задуманное число
int N; //число вопросов для звания Магистр
int level_game; //уровень игры
int countQuestion = 0; //текущее число заданных вопросов
string question; //очередной вопрос
int min; //нижняя граница задуманного числа
int max; //верхняя граница задуманного числа
//границы случайных значений min и max
//меняются в зависимости от уровня игры
int limit_min = 10;
int limit_max = 100;
//константы для организации диалога
const string ANSW =
"Я задумал число в замкнутом интервале [";
const string ANSW1 =
"Если отгадаешь число за ";
const string ANSW2 =
" вопросов, - станешь Магистром игры!\r\n";
const string ANSW3 =
"Ответом на вопрос может быть только 'Да' или 'Нет'";
const string ANSW4 =
"Поздравляю! Вы Магистр игры!\r\n";
const string ANSW44 = "Ваш уровень - ";
const string ANSW5 = "Вы угадали! Я задумал число ";
const string COMP = "----------- COMPUTER ----------";
const string COMP_ANSWER = "Я компьютер - Магистр игры! Я отгадал задуманное число ";
Поскольку все переменные снабжены содержательными комментариями, то я не буду останавливаться на пояснении их смысла.
Рассмотрим, какие действия следует выполнить, чтобы компьютер мог "задумать число". Вот как устроен обработчик события кнопки "Компьютер, задумай число":
/// <summary>
/// Компьютер задумывает число и определяет N
/// число вопросов, достаточное для отгадывания
/// и получения звания Магистр игры
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonThink_Click(object sender, EventArgs e)
{
//Уровень игры
//определяет границы интервала,
//в котором находится задуманное число
level_game = int.Parse(textBoxLevelGame.Text);
//нижняя и верхняя граница интервала
//формируются как случайные числа
min = rnd.Next(0, limit_min * level_game * level_game);
max = rnd.Next(min, limit_max * level_game * level_game);
//задуманное случайное число
number = rnd.Next(min, max);
//Функция log2 подсчитывает число вопросов
//для звания Магистр
N = Log2(max - min);
//Вывод ответа компьютера о задуманном числе
textBoxMin.Text = min.ToString();
textBoxMax.Text = max.ToString();
string answer = ANSW + min + ", " + max + "]\r\n" +
ANSW1 + N + ANSW2 + ANSW3;
textBoxAnswer.Text = answer;
}
Первым делом определяется заданный пользователем уровень игры. Уровень влияет на границы интервала, в котором находится задуманное число. Заметьте, не только задуманное число является случайным, но и границы интервала формируются как случайные числа. Для формирования трех случайных значений используется переменная rnd класса Random, которая вызывает метод Next.
Зная границы интервала, можно подсчитать N - число вопросов, достаточное для определения задуманного числа. Для подсчета N используется функция Log2 (M), которая вычисляет двоичный логарифм числа M, округленный в большую сторону до ближайшего целого.
Вычисленные значения выводятся в соответствующие окна, информируя пользователя. После того, как число задумано, отгадать задуманное может пользователь, либо можно посмотреть, как эту работу выполняет компьютер.
Чтобы отгадать задуманное число, пользователь может задавать компьютеру вопросы, получая ответы "да" или "нет". Задаваемые вопросы могут быть трех типов. Каждому типу вопроса соответствует своя командная кнопка. Рассмотрим, как устроен обработчик события Click кнопки "Число больше", позволяющий выяснить больше ли задуманное число, чем число n, указанное пользователем в вопросе:
/// <summary>
/// Ответ компьютера на кнопку
/// Задуманное больше X
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonGreat_Click(object sender, EventArgs e)
{
countQuestion++;
question = countQuestion.ToString() + ". ";
question += "Число больше ";
int n = int.Parse(textBoxG.Text);
question += n + "?";
if (number > n)
question += " - Да!";
else
question += " - Нет!";
listBoxQA.Items.Add(question);
}
Компьютеру просто ответить на заданный вопрос. Достаточно из соответствующего окна прочесть значение числа n, указанное пользователем, и сравнить с задуманным числом number. Основная работа в этом обработчике связана с формированием ответа в понятной для пользователя форме.
Не буду приводить текст обработчика события Click командной кнопки "Число меньше". Он немногим отличается от приведенного выше текста.
Чуть сложнее устроен обработчик события Click командной кнопки "Число равно", поскольку в этом случае, если число отгадано, то игра завершается и должно быть сформировано сообщение о результате игры. Если игрок использовал оптимальную стратегию, то его следует поздравить с получением звания "Магистр игры". Вот код данного обработчика события:
/// <summary>
/// Ответ компьютера на кнопку
/// Задуманное равно X
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonEqual_Click(object sender, EventArgs e)
{
countQuestion++;
question = countQuestion.ToString() + ". ";
question += "Число равно ";
int n = int.Parse(textBoxE.Text);
question += n + "?";
if (number == n)
{
question += " - Да!";
if (countQuestion <= N)
textBoxResult.Text = ANSW4 + ANSW44 +
level_game + "!\r\n" + ANSW5 + number;
else
textBoxResult.Text = ANSW5 + number;
}
else
question += " - Нет!";
listBoxQA.Items.Add(question);
}
Домашняя работа
Дома следует разобрать код проекта, посмотреть, как он работает в отладочном режиме.
В интерфейс проекта следует добавить одну – две командные кнопки и написать для них обработчики событий.
Урок начинается с разбора домашнего задания, выполненного школьником, на тему "вычисление суммы и произведения элементов массива при заданных ограничениях на элементы". Выполненная работа отвечает всем правилам, о которых шла речь на прошлых занятиях. Переменные нужным образом объявлялись, правильно были проинициализированы. В операторе if фильтр позволял отобрать нужные элементы для вычисления суммы и произведения.
В предложенном решении прекрасно то, что выполняются требования хорошего стиля программирования, - все элементы управления в форме, все переменные в программном коде имеют содержательные имена, облегчающие понимание сути предлагаемого решения. Что крайне важно, для вычисления суммы и произведения написаны специальные функции.
Единственное существенное замечание состоит в том, что написанные функции следовало снабдить заголовочными комментариями. При их наличии решение может служить эталоном для задач данного типа.
На этом уроке мы откажемся от рассмотрения таких "скучных" задач, как вычисление сумм и нахождения максимумов, а будем играть в умные игры и будем учиться, как создавать программы, реализующие такие игры.
Рассмотрим игру "Отгадай задуманное число" и поиграем в нее. Практически все, кто сыграл в эту игру с компьютером, отгадали задуманное число, получив звание "Магистра игры".
Интерфейс игры показан на рис. 4.1. рис 4.1
(рис 4.1) Интерфейс игры "Задумай число"
Кажется, что спроектированный интерфейс интуитивно понятен. Пользователь может задать уровень игры в соответствующем окне. Кнопка "Новая игра" позволяет очистить окна и перейти к новой игре. Кнопка "Компьютер, задумай число" позволяет начать игру. В зависимости от выбранного уровня игры компьютер выбирает некоторым образом интервал [min, max] и задумывает число в этом интервале. Сообщения о результатах этой работы появляются в соответствующих окошках. После этого пользователь может приступить к отгадыванию задуманного числа, задавая вопросы с помощью кнопок: "Число больше", "Число меньше", "Число равно". Ответы на его вопросы появляются в окне элемента управления ListBox "Вопросы и ответы". Когда пользователь отгадает число, то его результат отображается в окне "Результат". При успехе он получает звание "Магистра игры.
Вот как выглядит интерфейс в процессе игры:
(рис 4.2) Интерфейс проекта в процессе игры
Одна из задач, которую приходится решать в этом проекте, - это генерирование случайных чисел. Числа, которые задумывает компьютер, - это случайные числа.
Для генерирования случайных чисел в библиотеке классов FCL (Framework Class Library), доступной в проектах на C#, есть специальный класс Random, методы которого позволяют генерировать равномерно распределенные случайные числа. Фактически, эти числа нельзя назвать случайными, поскольку они генерируются по определенному алгоритму. Такие числа называют псевдослучайными. Тем не менее генерируемая последовательность чисел отвечает критериям, действующих для "настоящих" случайных чисел.
Чтобы получить случайное число или последовательность таких чисел, как всегда, нужно объявить переменную класса Random. Одного объявления недостаточно, эту переменную (объект) нужно еще и создать, вызвав конструктор объектов класса Random.
Конструктору можно передать целочисленный параметр, например, так:
Random rnd1 = new Random(100);
Переданный конструктору параметр преобразуется по определенным правилам в начальное значение генерируемой последовательности. В этом случае последовательность будет фиксированной. Всякий раз, когда для генерации случайных чисел будет использоваться переменная rnd1, создаваемая последовательность чисел будет одной и той же.
Можно, как обычно делается, параметр конструктору не передавать:
Random rnd = new Random();
В этом случае начальное значение строится по текущему времени компьютера. Поскольку оно всегда разное, то каждый раз генерируется новая последовательность чисел.
У класса Random есть несколько полезных методов. Метод Next, вызываемый переменной класса Random, позволяет получить следующее равномерно распределенное случайное число типа int в заданном интервале [min, max]:
int random_number = rnd.Next(min, max);
Метод NextDouble позволяет получить очередное равномерно распределенное случайное число типа double в интервале [0, 1]:
double drn = rnd.NextDouble();
Если необходимо получать вещественные числа в заданном интервале [min, max], то полученное число несложно привести к нужному интервалу следующими операциями:
drn = drn * (max – min) + min;
Алгоритм, реализующий задуманный сценарий игры, достаточно понятен и относительно прост. Однако, следует признать, что для начинающих программистов проект является сложным. Во многом сложность проекта объясняется тем, что, как для всякой игры, необходимо ввести большое число переменных, позволяющих менять параметры игры (в нашем случае –это уровень игры, границы интервала для задуманного числа, число вопросов для получения звания "Магистр игры", другие параметры). Организация разумного диалога с пользователем требует задания большого числа констант типа string.
Приведу описание констант и переменных, введенных в нашем проекте:
Random rnd = new Random(); //генератор случайных чисел
int number; //задуманное число
int N; //число вопросов для звания Магистр
int level_game; //уровень игры
int countQuestion = 0; //текущее число заданных вопросов
string question; //очередной вопрос
int min; //нижняя граница задуманного числа
int max; //верхняя граница задуманного числа
//границы случайных значений min и max
//меняются в зависимости от уровня игры
int limit_min = 10;
int limit_max = 100;
//константы для организации диалога
const string ANSW =
"Я задумал число в замкнутом интервале [";
const string ANSW1 =
"Если отгадаешь число за ";
const string ANSW2 =
" вопросов, - станешь Магистром игры!\r\n";
const string ANSW3 =
"Ответом на вопрос может быть только 'Да' или 'Нет'";
const string ANSW4 =
"Поздравляю! Вы Магистр игры!\r\n";
const string ANSW44 = "Ваш уровень - ";
const string ANSW5 = "Вы угадали! Я задумал число ";
const string COMP = "----------- COMPUTER ----------";
const string COMP_ANSWER = "Я компьютер - Магистр игры! Я отгадал задуманное число ";
Поскольку все переменные снабжены содержательными комментариями, то я не буду останавливаться на пояснении их смысла.
Рассмотрим, какие действия следует выполнить, чтобы компьютер мог "задумать число". Вот как устроен обработчик события кнопки "Компьютер, задумай число":
/// <summary>
/// Компьютер задумывает число и определяет N
/// число вопросов, достаточное для отгадывания
/// и получения звания Магистр игры
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonThink_Click(object sender, EventArgs e)
{
//Уровень игры
//определяет границы интервала,
//в котором находится задуманное число
level_game = int.Parse(textBoxLevelGame.Text);
//нижняя и верхняя граница интервала
//формируются как случайные числа
min = rnd.Next(0, limit_min * level_game * level_game);
max = rnd.Next(min, limit_max * level_game * level_game);
//задуманное случайное число
number = rnd.Next(min, max);
//Функция log2 подсчитывает число вопросов
//для звания Магистр
N = Log2(max - min);
//Вывод ответа компьютера о задуманном числе
textBoxMin.Text = min.ToString();
textBoxMax.Text = max.ToString();
string answer = ANSW + min + ", " + max + "]\r\n" +
ANSW1 + N + ANSW2 + ANSW3;
textBoxAnswer.Text = answer;
}
Первым делом определяется заданный пользователем уровень игры. Уровень влияет на границы интервала, в котором находится задуманное число. Заметьте, не только задуманное число является случайным, но и границы интервала формируются как случайные числа. Для формирования трех случайных значений используется переменная rnd класса Random, которая вызывает метод Next.
Зная границы интервала, можно подсчитать N - число вопросов, достаточное для определения задуманного числа. Для подсчета N используется функция Log2 (M), которая вычисляет двоичный логарифм числа M, округленный в большую сторону до ближайшего целого.
Вычисленные значения выводятся в соответствующие окна, информируя пользователя. После того, как число задумано, отгадать задуманное может пользователь, либо можно посмотреть, как эту работу выполняет компьютер.
Чтобы отгадать задуманное число, пользователь может задавать компьютеру вопросы, получая ответы "да" или "нет". Задаваемые вопросы могут быть трех типов. Каждому типу вопроса соответствует своя командная кнопка. Рассмотрим, как устроен обработчик события Click кнопки "Число больше", позволяющий выяснить больше ли задуманное число, чем число n, указанное пользователем в вопросе:
/// <summary>
/// Ответ компьютера на кнопку
/// Задуманное больше X
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonGreat_Click(object sender, EventArgs e)
{
countQuestion++;
question = countQuestion.ToString() + ". ";
question += "Число больше ";
int n = int.Parse(textBoxG.Text);
question += n + "?";
if (number > n)
question += " - Да!";
else
question += " - Нет!";
listBoxQA.Items.Add(question);
}
Компьютеру просто ответить на заданный вопрос. Достаточно из соответствующего окна прочесть значение числа n, указанное пользователем, и сравнить с задуманным числом number. Основная работа в этом обработчике связана с формированием ответа в понятной для пользователя форме.
Не буду приводить текст обработчика события Click командной кнопки "Число меньше". Он немногим отличается от приведенного выше текста.
Чуть сложнее устроен обработчик события Click командной кнопки "Число равно", поскольку в этом случае, если число отгадано, то игра завершается и должно быть сформировано сообщение о результате игры. Если игрок использовал оптимальную стратегию, то его следует поздравить с получением звания "Магистр игры". Вот код данного обработчика события:
/// <summary>
/// Ответ компьютера на кнопку
/// Задуманное равно X
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void buttonEqual_Click(object sender, EventArgs e)
{
countQuestion++;
question = countQuestion.ToString() + ". ";
question += "Число равно ";
int n = int.Parse(textBoxE.Text);
question += n + "?";
if (number == n)
{
question += " - Да!";
if (countQuestion <= N)
textBoxResult.Text = ANSW4 + ANSW44 +
level_game + "!\r\n" + ANSW5 + number;
else
textBoxResult.Text = ANSW5 + number;
}
else
question += " - Нет!";
listBoxQA.Items.Add(question);
}
Домашняя работа
Дома следует разобрать код проекта, посмотреть, как он работает в отладочном режиме.
В интерфейс проекта следует добавить одну – две командные кнопки и написать для них обработчики событий.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.