Содержание

Практика

Создадим игру, в которой нужно угадать число от 0 до 100, "загаданное" программой.

Игра будет состоять из 3 логических блоков: "загадывание", "отгадывание" и хранение числа.

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

Для этого создадим переменную, которая будет хранить "загаданное" число:

let number = -1;

Изначально присвоим переменной значение -1. Это будет означать, что число ещё не "загадано" или другими словами — игра ещё не началась.

Напишем функцию, которая будет "загадывать" число:

function newGame() {
  number = Math.ceil(Math.random() * Math.floor(100));
  return "Новая игра. Угадайте число от 0 до 100.";
}

Эта функция генерирует случайное число от 0 до 100 и выводит сообщение, что можно начинать играть.

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

Если тебе интересно, как же всё-таки работает генерация случайного числа, можешь почитать про конструкции Math.random(), Math.floor() и Math.ceil() на MDN: Math.random, Math.floor, Math.ceil.

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

function check(guess) {
  if (number == -1) {
    return "Чтобы начать новую игру, вызовите newGame()";
  }

  if (guess == number) {
    let message = "Поздравляем! Вы угадали число " + number;
    number = -1;
    return message;
  } else if (number > guess) {
    return "Больше!";
  } else if (number < guess) {
    return "Меньше!";
  }
}

Вот и всё, игра готова. Давайте попробуем поиграть.

Вызови check(10).

Результат: "Чтобы начать новую игру, вызовите newGame()". Всё верно, число ещё не "загадано".

Теперь необходимо начать игру newGame().

Результат: "Новая игра. Угадайте число от 0 до 100.". Всё верно.

Начнём угадывать число check(50). Алгоритм будет подсказывать нам ответами "Больше!" или "Меньше!".

Поиграй дальше и попробуй угадать число.

Маленькая хитрость, чтобы быстрее угадать: дели интервал, в котором находится число, пополам и вызывай функцию со средним значением.

Например, загадано число 68.

Искомый интервал от 0 до 100. Середина этого интервала - 50. Значит, сначала проверь check(50). Результат будет "Больше!".

Значит, новый интервал для поиска сократился вдвое и стал от 51 до 100. Его середина равна 75. Проверяем check(75). Результат будет "Меньше!".

И снова интервал сократился вдвое: от 51 до 74. Середина примерно 62. Проверяем check(62). Результат будет "Больше!".

Далее интервал от 63 до 74. Середина 68. Проверяем check(68). Результат будет "Поздравляем! Вы угадали число 68".

Сокращение интервала поиска вдвое - это самый быстрый способ угадать число, если подсказками могут быть либо "больше", либо "меньше".

База студентов

Давай создадим приложение, имитирующее работу с базой данных студентов.

Из каких блоков будет состоять наша программа?

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

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

В этом задании нам понадобятся знания о функциях, массивах, условиях, циклах и объектах.

Какую информацию о студентах мы хотим хранить?

Итак, создадим переменную, которая будет хранить в себе массив студентов:

let students = [
  {
    id: 0,
    name: "Николай",
    age: 20,
    gender: "м",
    beginnerCourse: false
  },
  {
    id: 1,
    name: "Анастасия",
    age: 21,
    gender: "ж",
    beginnerCourse: true
  },
  {
    id: 2,
    name: "Павел",
    age: 28,
    gender: "м",
    beginnerCourse: false
  },
  {
    id: 3,
    name: "Мария",
    age: 24,
    gender: "ж",
    beginnerCourse: true
  },
  {
    id: 4,
    name: "Николай",
    age: 21,
    gender: "м",
    beginnerCourse: true
  }
];

Так как переменная students служит для имитации базы данных, то напрямую с ней мы работать не будем, а напишем отдельную функцию. Эта функция будет возвращать "из базы" информацию о студентах:

function getStudents() {
  return students;
}

Теперь напишем функцию, которая будет искать студента по его идентификатору id:

function findById(id) {
  let studentsDatabase = getStudents();
  for (let i = 0; i < studentsDatabase.length; i = i + 1) {
    if (studentsDatabase[i].id == id) {
      return studentsDatabase[i];
    }
  }
}

Эта функция получает всех студентов "из базы". Затем перебирает их и сравнивает свойство id с заданным.

Как только найдёт, сразу вернёт данного студента.

Если не найдёт, то ничего не вернёт. А если быть точным, вернёт неопределённое значение undefined.

Напишем ещё одну функцию, с помощью которой мы сможем отфильтровать студентов по имени и возрасту

function filter(name, ageMin, ageMax) {
  let studentsFiltered = [];
  let studentsDatabase = getStudents();
  for (let i = 0; i < studentsDatabase.length; i = i + 1) {
    if (studentsDatabase[i].name == name &&
        studentsDatabase[i].age >= ageMin &&
        studentsDatabase[i].age <= ageMax)
    {
      studentsFiltered.push(students[i]);
    }
  }
  return studentsFiltered;
}

Напишем функцию, с помощью которой будем конкретному студенту выставлять отметку за экзамен:

function setMark(id, mark) {
  let student = findById(id);
  if (student == undefined) {
    return "Ошибка. Студент не найден.";
  }
  student.mark = mark;
}

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

Сначала с помощью функции findById() мы находим студента.

Если студента с таким идентификатором не существует, findById ничего не вернёт. Вернее, JS отдаст нам undefined.

Поэтому проверяем значение переменной student. Если он равен undefined, возвращаем ошибку с текстом, что студент не найден.

Если же студен был найден, выставляем ему отметку. Если свойство mark в объекте не было, оно будет добавлено.

Давай протестируем наше приложение.

Для начала получим всех студентов:

getStudents();

Вернётся массив из 5 объектов.

Отлично! Предположим, студент по имени Николай получил за экзамен 5, и мы хотим проставить эту отметку в базе.

Мы точно не знаем его возраст, но знаем, что он проходил курс по JS.

Отфильтруем студентов по имени "Николай" и возрасту от 20 до 30 лет:

filter("Николай", 20, 30);

Вернётся массив из 2 объектов.

Если мы их проглядим, то увидим, что студент с id == 4 проходил начальный курс beginnerCourse == true.

Тогда этому студенту и выставим отметку:

setMark(4, 5);

Посмотрим, записалась ли отметка "в базу". Для этого воспользуемся функцией поиска :


findById(4);

Результат:

{
  id: 4,
  name: "Николай",
  age: 21,
  gender: "м",
  beginnerCourse: true,
  mark: 5
}

Отметка сохранилась mark: 5