ОБЪЕКТИВНОСТЬ БЕЗ КОМПРОМИССОВОбъективность Без Компромиссов В Мире Компьютеров
НОВОСТИ САЙТАТЕСТИРУЕМ ВМЕСТЕИНТЕРНЕТ и ПОВСЯКО-РАЗНОСОФТ ПРОЕКТЫНАШИ ССЫЛКИ
ГЛАВНАЯ >> ИНТЕРНЕТ и ПО >> ПРОГРАММИРОВАНИЕ: Visual Basic 2010 - это просто. "Города РФ"

НАЗВАНИЕ СТАТЬИ: Visual Basic 2010 - это просто. "Города РФ"
АВТОРСТВО: Алексей Набережный
ДАТА НАПИСАНИЯ: Август 2010 года
ДАТА ПЕЧАТНОЙ ПУБЛИКАЦИИ: Октябрь 2010 года ( ISSN 0235-3520 )
ДАТА ПОСЛЕДНЕЙ РЕДАКЦИИ: Август 2010
Алекс Н.

Эффективный процесс обучения строится от простого к сложному. И если в первых двух материалах, посвященных изучению Visual Basic 2010, мы программировали простейшие игры, то сегодня разберем довольно сложную игру «Города РФ». Потребуется багаж школьных знаний, система помощи в Visual Studio и этот материал. Только не пугайтесь, ведь цель наших занятий – учиться программировать с относительного нуля, а значит будем «разжевывать» каждую строку.
Вы уже скачали бесплатную версию Express с ресурса www.microsoft.com/express/downloads/ и установили ее на домашний ПК. Поехали «Пуск – Программы - Microsoft Visual Studio 2010 Express - Microsoft Visual Studio 2010 Express», далее меню «Файл – Создать Проект». Выбираем «Консольное приложение», задаем очередное имя проекта – ConsoleApplication3. Между строчками Sub Main() и End Sub вставляем учебный код игры «Города». Ниже по тексту мы разберем его по полочкам.

10: Dim n, i, j As Integer, city As String, flag As Boolean, f As Char
20: Dim cities() As String = {"Майкоп", "Горно-Алтайск", "Уфа", "Улан-Удэ", "Махачкала", "Магас", "Нальчик", _
      "Элиста", "Черкесск", "Петрозаводск", "Сыктывкар", "Йошкар-Ола", "Саранск", _
      "Якутск", "Владикавказ", "Казань", "Кызыл", "Ижевск", "Абакан", "Грозный", _
      "Чебоксары", "Барнаул", "Чита", "Петропавловск-Камчатский", "Краснодар", _
      "Красноярск", "Пермь", "Владивосток", "Ставрополь", "Хабаровск", "Благовещенск", _
      "Архангельск", "Астрахань", "Белгород", "Брянск", "Владимир", "Волгоград", _
      "Вологда", "Воронеж", "Иваново", "Иркутск", "Калининград", "Калуга", "Кемерово", _
      "Киров", "Кострома", "Курган", "Курск", "Санкт-Петербург", "Липецк", "Магадан", _
      "Москва", "Мурманск", "Нижний Новгород", "Великий Новгород", "Новосибирск", "Омск", _
      "Оренбург", "Орёл", "Пенза", "Псков", "Ростов-на-Дону", "Рязань", "Самара", _
      "Саратов", "Южно-Сахалинск", "Екатеринбург", "Смоленск", "Тамбов", "Тверь", _
      "Томск", "Тула", "Тюмень", "Ульяновск", "Челябинск", "Биробиджан", "Нарьян-Мар", _
      "Ханты-Мансийск", "Анадырь", "Салехард"}
30: n = cities.Length
40: Dim goroda(n - 1) As Boolean
50: Console.WriteLine("В России есть области, края, автономные округа и у каждого федеративного субъекта есть" _
     + "свой центральный город. Пока их " + Str(n) + ". Вот полный список.")
60: For Each ij As String In cities
70:   Console.Write(ij + ", ")
80: Next ij
90: Console.WriteLine("... Для продолжения нажмите любую клавишу.")
100:  Console.ReadKey()
110:  Console.Clear()
120:  Randomize() : i = Math.Round(Rnd() * (n - 1))
130:  city = cities(i) : goroda(i) = True
140:  f = Right(city, 1)
150:  If f = "ь" Then f = Mid(city, city.Length - 1, 1)
160:  If f = "ы" Then f = Mid(city, city.Length - 1, 1)
170:  Console.WriteLine("Играем в города-центры РФ. Нельзя ошибаться и повторяться. Если город оканчивается на ""ь""" _
     + " или ""ы"" берем предпоследнюю букву, если на ""й"" - думаем. Начнем с города " + city)
180:  For i = 0 To n - 1
190:  flag = False
200:  Console.ForegroundColor = ConsoleColor.Red
210:  Console.Write("Твой вариант: ")
220:  city = Console.ReadLine : city = city.ToLower
230:  Console.ForegroundColor = ConsoleColor.White
240:  If f <> Left(city, 1) Then
250:  Console.WriteLine("Вы проиграли. Нужен был город РФ, начинающийся с буквы " + f)
260:  Exit For
270:  Else
280:  For j = 0 To n - 1
290:    If city = cities(j).ToLower And goroda(j) = False And flag = False Then
300:    Console.WriteLine("Знаю такой город. Название принято.")
310:    goroda(j) = True
320:    flag = True
330:    f = Right(city, 1)
340:    If f = "ь" Then f = Mid(city, city.Length - 1, 1)
350:    If f = "ы" Then f = Mid(city, city.Length - 1, 1)
360:    End If
370:  Next j
380:  If flag = False Then
390:    Console.WriteLine("Нужен был город РФ без ошибок и повторов. Вы в проигрыше.")
400:    Exit For
410:  End If
420:  End If
430:  flag = False
440:  Console.ForegroundColor = ConsoleColor.Green
450:  For j = 0 To n - 1
460:  If f = Left(cities(j), 1).ToLower And goroda(j) = False And flag = False Then
470:    Console.WriteLine("Мой ответ: " + cities(j))
480:    Console.ForegroundColor = ConsoleColor.White
490:    goroda(j) = True
500:    flag = True
510:    f = Right(cities(j), 1)
520:    If f = "ь" Then f = Mid(cities(j), cities(j).Length - 1, 1)
530:    If f = "ы" Then f = Mid(cities(j), cities(j).Length - 1, 1)
540:  End If
550:  Next j
560:  If flag = False Then
570:  Console.WriteLine("Я проиграл, поскольку не знаю города РФ, подходящего для ответа")
580:  Exit For
590:  End If
600:  Next i
610:  Console.WriteLine("Игра окончена. Нажмите Enter.")
620:  Console.ReadLine()

В строке под номером 10 оператор Dim объявляет несколько переменных. В целочисленной переменной n будем держать число центральных городов РФ – вдруг увеличиться. Переменные i и j – это счетчики циклов, выполняющие группу операторов несколько раз (в соответствии с диапазоном счетчика). В строковую переменную city (тип String) мы собираемся вносить название очередного города. Переменную flag мы объявили булевой (т.е. логической). У нее может быть лишь два значения – false или true (нам больше и не понадобится). Объявленная переменная f могла быть строковой (тип String), однако в нашем алгоритме в ячейке f будет храниться лишь одна последняя буква введенного города, и для этого случая оптимально использовать символьный типа данных (тип Char).
В 20-й строке мы создаем (и сразу же заполняем) строковый массив cities() со всеми названиями центров субъектов Российской Федерации. Кстати, города идут в том же порядке, что и в 65-й статье Конституции РФ. Разумеется, эта строка должна быть очень длинной и чтобы сохранить читабельность журнальной статьи мы использовали служебный символ с нижним подчеркиванием («_»). После него командные строки Visual Basic можно разрывать в любом месте. Однако помните, что перед нижним подчеркиванием в обязательном порядке должен быть пробел. По пути отметим, что список центральных городов России можно дополнить названиями обычных городов и тогда процесс игры станет еще интереснее.
В строке 30 задействовано свойство Length, благодаря которому выясняем число элементов массива cities() и записываем его в переменную n. Обратите внимание, что в таблице cities() сейчас 80 городов-элементов, но последний из них будет иметь порядковый 79. Т.е. крайний номер на единицу меньше длины массива. Так cities(79) – это город Салехард, а cities(0) – это элемент строкового массива, содержащий название города Майкоп. Вы уже поняли, что нумерация любого массива в Visual Basic 2010 начинается с нуля?
В следующей строке создаем вспомогательный массив goroda(). С его помощью мы будем учитывать использованные названия городов. Естественно, количество элементов в логическом массиве goroda() совпадет с числом городов cities() – учитывайте, что элементы нумеруются с нуля. По умолчанию, все логические флажки массива goroda() будут иметь значение false, но как только в процессе игры будет озвучен какой-либо город-центр из cities(), то соответствующий по номеру элемент goroda() получит значение True. Кстати, проверку состояния элементов goroda() увидите дальше, в программных строках 290 и 460.
Теперь все внимание на то, как построен вывод на консоль в сточке 50. Фраза склеена из трех частей. Первая и последняя – это обычные строки. А чтобы между ними «вклеить» число задействованных городов пришлось целочисленную переменную n превращать в строку с помощью функции Str(n). Интересно, что в ряде других версий языка Basic такая операция и не нужна. А в Visual Basic слагаемые склейки придется приводить к одному типу данных. Отвлечемся и скажем, чтобы провести обратную операцию с строку «123» превратить в число 123, надо задействовать метод Val("123").
В трех последующих строчках 60, 70 и 80 представлена циклическая конструкция, удобная для вывода содержания массива cities() на консоль. В результате выполнения цикла For Each... Next пользователь видит все центральные города РФ. Возьмите этот шаблон для вывода массива на заметку – пригодиться в будущих программах.
Список городов удерживается на экране до тех пор, пока не будет нажата любая кнопка на клавиатуре. Это происходит благодаря команде Console.ReadKey() из 100-й строки. Затем вызывается метод Console.Clear()и консоль очищается.
В строке 120 разместились сразу две командных конструкции – они разделены двоеточием. Первая инициализирует генератор случайных чисел, вторая записывает в переменную i округление до целого произведения случайного вещественного числа (от 0 до 1) на число элементов в массиве cities(). Простыми словами с помощью выражения Math.Round(Rnd() * (n - 1) мы вытягиваем для первого хода случайный номер из соответствующего списка городов.
В строке 130 в переменную city мы записываем само название выбранного города из массива cities(). Здесь же в вспомогательный массив goroda() мы вносим пометку, позволяющую игнорировать определенный мегаполис в процессе будущих ходов.
В строке 140 в переменную f заносим последнюю букву избранного города. Функция Right() возвращает подстроку, содержащую указанное число знаков справой стороны. В нашем случае Right(city, 1), это один последний символ из переменной city.
В строках 150 и 160 на всякий случай проверяем на какую букву заканчивается случайно выбранный город. Вдруг это Казань или Чебоксары, тогда нужно брать не последнюю в названии, а предпоследнюю. Это можно сделать с помощью другой функции - Mid(city, city.Length - 1, 1). Она из переменной city возвращает строку из одного знака, начиная с позиции city.Length – 1 (длина называния города, минус один).
Кстати, если забыть про город Йошкар-Ола, то при выпадении городов Грозный или Петропавловск-Камчатский нам потребовалась бы дополнительная проверка с функцией Mid(city, city.Length - 2, 1) – берем пред-пред- последнюю букву. Но не будем фантазировать, в строке 170 сообщаем правила нашей игры и стартовый город.
А все инструкции между строками 180 и 600 – это и есть главная часть нашего алгоритма. По логике программы ход человека и ответ компьютера повторяются много раз в цикле. Очевидно, что число исполнений тела цикла не может превышать количество городов-элементов в массиве cities(). Именно поэтому счетчик ключевого цикла запущен с 0 до n-1 -– по умолчанию шаг цикла равен единице.
Командный кусочек 190–420 -– ход человека, 430-590 -– отклик ЭВМ. Обе половинки схожи. Строки 190 и 430 – сбрасываем логический флажок. В 200 и 440 устанавливаются разные цвета для вывода текста на консоль. И т.д.
В строке 220 считываем с консоли название города в переменную city. Следом, введенное слово переводим в нижний регистр с помощью метода ToLower (city = city.ToLower).
Строки 240–420 – конструкция ветвления в зависимости от последней буквы в обновившейся переменной city. Если человек указал город, первая буква которого не совпадает со значением переменной f, хранящей последнюю букву от прошлого города, то пользователь увидит сообщение «Вы проиграли...». Первую букву в переменной city выясняем с помощью метода Left(city, 1).
В строке 260 находится важный оператор Exit For. По нему происходит немедленный выход из цикла For и выполнение алгоритма продолжается с команды, следующей за оператором Next. Т.е. переходим к завершающим строкам 610 и 620. Кстати, при использовании вложенных циклов For команда Exit For закрывает самый внутренний цикл и передает управление следующему уровню вложения.
Строки 280-410 будут выполняться, если в ответе человека первая буква в названном городе совпадет с переменной f. Запускается вложенный цикл 280-370 в котором перебираются абсолютно все элементы массива cities(). Метод cities(j).ToLower приводит название города к нижнему регистру для корректного поиска, ведь мы «опустили» и саму переменную city. Помимо вхождения значения city в список городов, программа смотрит на значение соответствующего элемента из массива goroda() – вдруг название мегаполиса уже звучало в игровом процессе, тогда ячейка goroda(j) должны быть в значение True. По пути проверяется сигнальная переменная flag, если она в положении True, то мы уже одобрили ход человека и вычеркнули названный город из списка оставшихся.
Если исполнитель алгоритма попадет в строки 300-350 на экране появится одобрительная фраза "Знаю такой город. Название принято" (строка 300). Соответствующий элемент массива goroda(j) и переменная flag получат значение True (строки 310 и 320). В переменной f появится последняя буква названного города (строка 330). Назначение строк 340/350 аналогично строчкам 150/160.
Если после выполнения циклической конструкции 280-370 значение флажка f будет равно False, значит человек не смог назвать подходящего города. Будут исполнены команды из строк 390 и 400. Появится сообщение «Вы в проигрыше», а далее Exit For отошлет нас на концовку проекта (т.е. к строке 610).
Как писали выше, фрагмент программы между строками 430 и 590 – это ответный ход ЭВМ. В строке 430 сбрасываем флажок flag, в 440-ой устанавливаем зеленый цвет шрифта для компьютерных ответов. В цикле 450 – 550 перебираем города из массива cities(), ищем подходящее название, чтобы последняя буква города, введенного человеком совпала с первой буквой элемента cities(j). При этом алгоритм следит за соответствующим значением goroda(j) – вдруг этот город был назван. И еще смотрим на состояние переменной flag.
По большому счету компьютер проиграет лишь, когда кончатся все подходящие города из массива cities(j) – запустятся команды из ветки 560-590. Иначе программа найдет правильный ответ (строка 460), выведет его на экран (строка 470), в элемент goroda(j) и переменную flag запишет значения True (строки 490 и 500). И самое главное, компьютерный ход отразиться в переменной f – в нее попадет последняя буква названного города (строка 330). Если последней будет буква «ь» или «ы», то в f запишем предпоследнюю букву из названия города (строки 520 и 530). А далее Next i bp строки 600 и возврат к строке 180 – круг замкнулся.
Отметим, что в игре может быть ничейный исход. Это когда все города названы и выход из главного цикла 180-600 осуществится сам по себе, за счет перебора всех значений счетчика i от 0 до n-1. Тогда на экране появится лишь одна дежурная надпись «Игра окончена. Нажмите Enter», после которой ЭВМ будет ожидать нажатие клавиши Enter за счет оператора Console.ReadLine() из последней строки (под номером 620). Кстати, вопрос для внимательных читателей – чем Console.ReadLine() отличается от Console.ReadKey()?

Создаем игровой проект в Visual Studio 2010
Visual Basic 2010

В завершении повествования, есть предложение по самостоятельной работе. Во-первых, попробуйте сделать игру «Столицы Мира». Во-вторых, подумайте, как можно обойтись в ней без вспомогательного массива goroda(). Например, можно просто затирать названия использованных городов.
Вот и все на сегодня. Возникнут вопросы по алгоритму – вдумчиво перечитайте статью. Если будут сомнения по поводу предназначения различных операторов, встаньте курсором на нужном месте и нажмите клавишу F1 – загрузиться русифицированная система помощи с необходимым пояснением. Грызите.

>> НАВЕРХ СТРАНИЦЫ <<

Rambler's Top100 Рейтинг@Mail.ru