Уважаемые пользователи Голос!
Сайт доступен в режиме «чтение» до сентября 2020 года. Операции с токенами Golos, Cyber можно проводить, используя альтернативные клиенты или через эксплорер Cyberway. Подробности здесь: https://golos.io/@goloscore/operacii-s-tokenami-golos-cyber-1594822432061
С уважением, команда “Голос”
GOLOS
RU
EN
UA
archual
7 лет назад

Программирование игр. Урок 2. Основные структуры в алгоритме.

Основные структуры в алгоритме.

На прошлом занятии мы познакомились с вами с алгоритмами, сегодня мы рассмотрим основные структуры в алгоритме для управления ходом выполнения нашей программы, а также напишем формальный алгоритм для нашей первой игры "Быки и коровы".

Для первой игры нам понадобятся две структуры - это цикл и условие.

Цикл - это повторение одного и того же действия пока не будет выполнено определённое условие.

В нашем первом алгоритме для приготовления чая цикл был из действия перемешивание, а условием для прекращения цикла было растворение сахара, тогда можно прекратить перемешивать чай (остановить цикл).

Циклы в программировании используются очень часто: перебор списка элементов, расчёт каких либо периодически величин (расчёт сумм в бухгалтерии для отчёта по месяцам), регулярные опросы устройств Ввода-вывода. В нашей игре один из главных циклов будет вопрос к игроку, пока игрок не разгадает загадку.
Цикл состоит из условия и тела цикла. Условие определяет будет ли выполняться тело цикл, а тело цикла содержит в себе различные команды, которые будут выполнены.

Условие - структура, которая позволяет выбрать какие действия мы должны выполнить, если наше условие истинно (true) или ложно (false).

К примеру в нашем первом алгоритме было несколько условий, одно из них "проверить есть ли в чайнике вода". Простое условие, если вода есть, наше условие истинно, если нет - ложно. И в зависимости от результата проверки мы либо выполняем действие "включить чайник", либо действие "налить в него воды".

Есть некоторые тонкости с циклами и условиями, но я не хочу перегружать вас информацией, в конце урока я дам вам ссылки, где можно будет почитать подробнее, а пока для наших целей этой информации будет достаточно.

Давайте же наконец приступим к написанию алгоритма для нашей первой игры.

Игра "Быки и коровы".
Это очень простая игра, в которую можно играть вдвоём и без компьютера. Но именно её простота позволяет понять и научится строить алгоритмы, которые потом можно легко запрограммировать.

Быки и коровы — логическая игра, в ходе которой за несколько попыток один из игроков должен определить, что задумал другой игрок. Варианты игры могут зависеть от типа отгадываемой последовательности — это могут быть числа, цвета, пиктограммы или слова. После каждой попытки задумавший игрок выставляет «оценку», указывая количество угаданного без совпадения с их позициями (количество «коров») и полных совпадений (количество «быков»)

Мы возьмём вариант с 4х значным числом и в качестве второго игрока у нас будет компьютер. Для начала напишем весьма упрощённый алгоритм, и будем постепенно усложнять.

  1. Компьютер загадывает 4х значительно число и сохраняет его в памяти.
  2. Компьютер предлагает пользователю отгадать число, появляется форма для ввода числа.
  3. Пользователь вводит свой вариант.
  4. Компьютер берет вариант пользователя и сравнивает со своим загаданным числом (тут будет наиболее сложная часть программы, но это потом). Вычисляет сколько пользователь угадал цифр на неверных позициях - число "коров" и сколько угадал абсолютно верно - число "быков". Заносит эти данные в переменные.
  5. Проверяет сколько получилось быков, если их 4, то пользователь угадал число, поздравляем его и идём к шагу (пока не знаем к какому, после написания алгоритма это шаг 8), иначе переходим к шагу 6. (условие)
  6. Выводит на экран информацию для пользователя о количестве "быков" и "коров" из соответствующих переменных.
  7. Так как пользователь ещё не отгадал число, переходит к шагу 2 и даёт пользователю ещё одну попытку (цикл).
  8. Поздравляем пользователя с успешной попыткой! Предлагаем пользователю сыграть ещё раз. Выводим диалог с вопросом и двумя кнопками "ок" и "отмена".
  9. Если пользователь выбирает "ок" идём к шагу 1, иначе завершаем программу (условие).

Вот такой получился общий алгоритм для нашей игры, но в нем пока не хватает самой сложной математической части - проверки сколько цифр угадал пользователь и подсчёта "быков" и "коров".
Эти действия должны выполняться на шаге 4 нашего общего алгоритма. Давайте напишем отдельный небольшой алгоритм который будет заниматься именно этим. В программировании так делают очень часто и в большинстве языков программирования это называется "функция".

Стоит немного рассказать о функциях в программировании. Функция - это специальная конструкция в языке программирования, которая может принимать аргументы, делать различные вычисления и может, но не обязана возвращать результат. Аргументы - это переменные, которые передаются в функцию в момент вызова. Помните в математике были тригонометрические функции косинуса и синуса?

Y = sin(X)

Вот в программирование все примерно также, sin - это название функции, X - передаваемый аргумент (их может быть несколько, через запятую), а Y - возвращаемое значение.

Так вот, наш подалгоритм будет функцией, которая будет принимать два аргумента - числа: то что загадал компьютер, и то которое указал пользователь. Она будет проводить сравнение и вычислять сколько "быков" и "коров" угадал пользователь и возвращать эту информацию как результат выполнения функции.

 4.1. Компьютер вызывает функцию проверки и передаёт в неё свое число и число введённое пользователем. 

4.2. Компьютер производит расчёт "коров".

4.3. Компьютер производит расчёт "быков".

4.4. Компьютер возвращает результат расчётов.

Вроде уже почти все есть, но остаётся вопрос: "как нам рассчитать число "коров" и "быков"? Для этого нам надо ещё уточнить два шага нашего алгоритма: 4.2 и 4.3.

Для подсчёта "коров" и "быков" мы должны работать с отдельными цифрами в наших числах, а для этого разбить наши числа на отдельные элементы и сохранить в форме, удобной для дальнейших манипуляций с ними. В программировании такой формой является массив.

"Массив" - (array) - структура данных в виде набора компонентов (элементов массива), расположенных в памяти непосредственно друг за другом, что позволяет обращаться к элементам по числовому индексу.

Преимущества массива в том, что мы можем обратиться к каждому его элементу по индексу, и таким образом мы можем обойти весь массив элементов используя цикл. Давайте посмотрим на примере.

Пусть у нас будет массив фруктов с названием "фрукты" :
['яблоко', 'груша', 'персик', 'манго'].

Получить конкретный элемент массива можно так:

фрукты[0]

Программа вернёт нам наше яблоко. Заметьте что элементы в массиве начинаются с 0.
А чтобы напечатать (или выполнить какие то другие действия) со всеми элементами нашего массива мы можем использовать цикл:

  1. Создать переменную счётчик и присвоить ей первоначальное значение 0.
  2. Если переменная счётчик ещё не больше длины массива фрукты перейти к шагу 3, иначе перейти к шагу 6.
  3. Напечатать элемент массива фрукты [переменная счётчик].
  4. Увеличить переменную счётчик на один.
  5. Перейти к шагу два.
  6. Массив распечатан, можно завершить программу.

Вот так все просто. Я оставлю ссылку, что почитать о массивах. Там ещё много всяких тонкостей, но пока нам хватит этого.

Мы объединим два шага для вычисления "коров" и "быков" в один. Для начала разобьем наши числа на составляющие и сохраним в два массива:

    4.2.1. Создадим пустой массив numberPcArray. 

   4.2.2. Создадим пустой массив numberUserArray.

   4.2.3. Сохраним в нулевую ячейку каждого массива значение тысяч соответствующего числа.

   4.2.4. Сохраним в первую ячейку каждого массива значение сотен соответствующего числа.

   4.2.5. Сохраним во вторую ячейку каждого массива значение десятков соответствующего числа.

   4.2.6. Сохраним в третью ячейку каждого массива значение единиц соответствующего числа.

Вы возможно спросите, а как нам получить значения тысяч, сотен, десятков и единиц. Тут нам поможет математика и специальные функции в языках программирования.

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

Для целочисленного деления в JavaScript
(а мы в дальнейшем будем писать на нем) используется обычное деление, но результат округляется в меньшую сторону.

Math.floor(x/y)

Math - это специальная математическая библиотека в языке JavaScript, которая представляет множество полезных функций. Например мы используем функцию floor - она позволяет округлить число в меньшую сторону (floor с английского пол).

А для получения остатка от деления есть специальный оператор "%"

x % y

Давайте посмотрим на примере.
Возьмём число 3572. Ну а почему бы и нет)
Нам надо его программно разбить на "3", "5", "7" и "2".
Сохраним наше число в переменную number:

number = 3572

Получим из него количество тысяч:

thousands = Math.floor(number/1000)

В итоге получаем 3.

Для получения сотен, нам надо убрать из нашего числа тысячи.

number = number % 1000

Таким образом мы перезаписываем нашу переменную number новым значением, а именно остатком от деления на тысячу. Сейчас в нашей переменной число 572.

Теперь нам нужно повторить эти операции чтобы получить сотни, десятки.

hundreds = Math.floor(number/100)

Получаем 5.

number = number % 100

Остается 72

tens = Math.floor(number/10)

Получаем 7.

singles = number % 10

И остаются единицы 2.

Таким образом мы смогли разбить наше четырехзначное число на четыре отдельных переменных. Вместо переменных правильнее было взять массив и записать значение для каждого разряда в отдельный элемент. Давайте так и сделаем:

numberPcArray = [];

numberUserArray = [];

numberPcArray[0] = Math.floor(numberPc/1000);

numberPc = numberPc % 1000;

numberUserArray[0] = Math.floor(numberUser/1000);

numberUser = numberUser % 1000;



numberPcArray[1] = Math.floor(numberPc/100);

numberPc = numberPc % 100;

numberUserArray[1] = Math.floor(numberUser/100);

numberUser = numberUser % 100;



numberPcArray[2] = Math.floor(numberPc/10);

numberPcArray[3] = numberPc % 10;

numberUserArray[2] = Math.floor(numberUser/10);

numberUserArray[3] = numberUser % 10;

Обратите внимание на точку с запятой в конце каждой строки - это специальный разделитель команд в языках программирования, не во всех конечно так, но в JavaScript именно так.
В итоге мы получили два массива с нашими разбитыми на составляющие числами.
Теперь мы можем сравнивать их по отдельности и посчитать количество наших "коров" и "быков". Для этого нам понадобятся: две переменных счётчика для хранения количества "коров" и "быков", два цикла и пара условий.

    4.2.7. Создадим переменную cows и присвоим ей первоначальное значение 0.

   4.2.8. Создадим переменную bulls и присвоим ей первоначальное значение 0.

   4.2.9. Создадим переменную счётчик для первого цикла (в программировании часто для простых итерации используют переменные с именами i, j, k) i и присвоим ей первоначальное значение 0.

   4.2.10. Создадим переменную счётчик для второго цикла j и присвоим ей первоначальное значение 0.

   4.2.11. Если i = j (значит мы будем сравнивать цифры наших чисел, стоящие на одинаковых позициях, а это "Быки"), перейти к шагу 4.2.12, иначе перейти к шагу 4.2.13.

   4.2.12. Если numberPcArray[i] = numberUserArray[j], то увеличить переменную bulls на один и перейти к шагу 4.2.14, иначе перейти к шагу 4.2.14.

   4.2.13. Если numberPcArray[i] = numberUserArray[j], то увеличить переменную cows на один и перейти к шагу 4.2.14, иначе перейти к шагу 4.2.14.

   4.2.14. Увеличить переменную счётчик второго цикла на один.

   4.2.15. Если j < длинны массива numberPcArray, увеличиваем j на один и переходим к шагу 4.2.11, иначе присваиваем переменной j значение 0 и переходим к шагу 4.2.16.

   4.2.16. Если i < длинны массива numberPcArray, увеличиваем i на один и переходим к шагу 4.2.11, иначе переходим к шагу 4.2.17.

   4.2.17. Наши циклы отработали и количество "коров" и "быков" посчитано.

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

Полный алгоритм

Компьютер загадывает 4х значительно число и сохраняет его в памяти.

Компьютер предлагает пользователю отгадать число, появляется форма для ввода числа.

Пользователь вводит свой вариант.

Компьютер берет вариант пользователя и сравнивает со своим числом. Вычисляет сколько пользователь угадал цифр на неверных позициях - число "коров" и сколько угадал абсолютно верно - число "быков". Заносит эти данные в переменные.

4.1. Компьютер вызывает функцию проверки и передаёт в неё свое число и число введённое пользователем.
4.2. Компьютер производит расчёт "коров" и "быков".
4.2.1. Создадим пустой массив numberPcArray.
4.2.2. Создадим пустой массив numberUserArray.
4.2.3. Сохраним в нулевую ячейку каждого массива значение тысяч соответствующего числа.
4.2.4. Сохраним в первую ячейку каждого массива значение сотен соответствующего числа.
4.2.5. Сохраним во вторую ячейку каждого массива значение десятков соответствующего числа.
4.2.6. Сохраним в третью ячейку каждого массива значение единиц соответствующего числа.
4.2.7. Создадим переменную cows и присвоим ей первоначальное значение 0.
4.2.8. Создадим переменную bulls и присвоим ей первоначальное значение 0.
4.2.9. Создадим переменную счётчик для первого цикла (в программировании часто для простых итерации используют переменные с именами i, j, k) i и присвоим ей первоначальное значение 0.
4.2.10. Создадим переменную счётчик для второго цикла j и присвоим ей первоначальное значение 0.
4.2.11. Если i = j (значит мы будем сравнивать цифры наших чисел, стоящие на одинаковых позициях, а это "Быки"), перейти к шагу 4.2.12, иначе перейти к шагу 4.2.13.
4.2.12. Если numberPcArray[i] = numberUserArray[j], то увеличить переменную bulls на один и переходим к шагу 4.2.14, иначе переходим к шагу 4.2.14.
4.2.13. Если numberPcArray[i] = numberUserArray[j], то увеличить переменную cows на один и переходим к шагу 4.2.14, иначе переходим к шагу 4.2.14.
4.2.14. Увеличить переменную счётчик второго цикла на один.
4.2.15. Если j < длинны массива numberPcArray, увеличиваем j на один и переходим к шагу 4.2.11, иначе присваивает переменной j значение 0 и переходим к шагу 4.2.16.
4.2.16. Если i < длинны массива numberPcArray, увеличиваем i на один и переходим к шагу 4.2.11, иначе переходим к шагу 4.2.17.
4.2.17. Наши циклы отработали и количество "коров" и "быков" посчитано.
4.3. Компьютер возвращает результат расчётов.

Проверяет сколько получилось быков, если их 4, то пользователь угадал число, поздравляем его и идём к шагу 8, иначе переходим к шагу 6. (условие)

Выводит на экран информацию для пользователя о количестве "быков" и "коров" из соответствующих переменных.

Так как пользователь ещё не отгадал число, переходит к шагу 2 и даёт пользователю ещё одну попытку (цикл).

Поздравляем пользователя с успешной попыткой! Предлагаем пользователю сыграть ещё раз. Выводим диалог с вопросом и двумя кнопки "ок" и" отмена".

Если пользователь выбирает "ок" идём к шагу 1, иначе завершаем программу (условие).

Ну вот мы с вами и написали алгоритм для нашей первой игры. Наверное какие-то моменты получились несколько сумбурные и не до конца понятные. Как обычно я дам ссылки, чтобы почитать подробнее про новые понятия, и буду давать их сразу для языка программирования JavaScript.

На следующем уроке мы начнём программировать. По плану у нас было изучение системы контроля версий, но мы отложим это дело на одно занятие.

Ссылка на первое занятие: Урок 1 - Программирование. Как работает компьютер. Что такое алгоритм.

Ссылки на материалы, чтобы больше узнать о циклах, условиях, массивах, функциях и переменных:

Теги которые я буду использовать и по которым можно будет найти мои статьи:

программированиеигр,

javascript,

phaserjs.

P. S. Данный пост также написан на телефоне, с использованием редактора Markor. Есть незначительные минусы у этого редактора в плане отображения информации.

P. P. S. Клавиатура на телефоне (я использую SwiftKey) не предназначена для набора программ, постоянно пытается вмешаться и все сделать по своему.

P. P. P. S. Писать статьи не так просто, особенно их проверять и редактировать ошибки. Так как я пишу в основном в маршрутке, я уже трижды проезжал свою остановку на пару остановок дальше).
Программировать можно и на телефоне, не очень удобно правда. Попробуйте приложение JS Run. Наша первая программа вполне может быть написана в нем (что я и сделаю на следующем уроке).

0
0.000 GOLOS
На Golos с January 2018
Комментарии (7)
Сортировать по:
Сначала старые