Лабораторная работа 4: циклы и последовательности

Кувшинов Д.Р.

2016


Общее оглавление


Вариант 1

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

Итак, есть четыре команды

Возможные команды робота
Код Мнемоника Смысл
0 halt останов
1 move вперёд
2 left налево
3 right направо


У команд 1–3 есть однобайтовый параметр — дальность хода (move) в метрах и угол поворота (left, right) в градусах. Таким образом, команда halt занимает один байт в памяти, а команды move, left и right — два байта (код команды и аргумент команды).

Пример программы робота (uint8_t определён в <cstdint>):

std::uint8_t program[]
{
    1, 5,   // продвинуться вперёд на 5 метров
    3, 45,  // повернуться направо на 45 градусов
    1, 3,   // продвинуться вперёд на 3 метра
    2, 90,  // повернуться налево на 90 градусов
    1, 3,   // продвинуться вперёд на 3 метра
    2, 135, // повернуться налево на 135 градусов
    1, 5,   // продвинуться вперёд на 5 метров
    2, 45,  // повернуться налево на 45 градусов
    1, 3,   // продвинуться вперёд на 3 метра
    3, 90,  // повернуться направо на 90 градусов
    1, 3,   // продвинуться вперёд на 3 метра
    3, 135, //повернуться направо на 135 градусов
    0       // останов
};

Предположим, что состояние робота описывается тремя переменными: координатами на плоскости x, y и углом поворота α (удобнее в радианах или в градусах?). Напишем функцию, принимающую начальное состояние робота и программу, заданную массивом байт, и возвращающую конечное состояние робота после выполнения данной программы.

Так как нам придётся принимать и возвращать состояние робота, состоящее из трёх значений, удобно описать это состояние структурой, содержащей три поля.

#include <cstdint> // std::uint8_t

// Состояние робота.
struct Robot_state
{
  double x, y, alpha;
};

// Определение операции вывода состояния робота в поток выводы.
std::ostream& operator<<(std::ostream & os, const Robot_state & robot)
{
  return os << "(" << robot.x << ", " << robot.y << "; " << robot.alpha << ")";
}

Теперь можно оперировать группой из трёх значений как одним значением, в частности возвращать из функции “разом”:

Robot_state robot_walk(Robot_state robot, uint8_t program[], size_t max_commands)
{
  // ???
}

В объектно-ориентированном стиле можно поручить исполнение конкретной команды, изменяющей состояние, самому объекту Robot_state, это состояние содержащему:

enum Command : uint8_t { /* ... */ };

struct Robot_state
{
  double x, y, alpha;
  void perform(Command cmd, uint8_t param = 0)
  {
    // Изменяем x, y, alpha текущего объекта
    // соответственно команде.
  }
};

void robot_walk(Robot_state & robot, uint8_t program[], size_t max_commands)
{
  // Для каждой команды в массиве вызываем robot.perform(код команды, параметр).
}


Табуляция

Табуляция функции — представление функции в табличной форме. Обычно означает вычисление функции в заданных точках и запись вычисленных значений в массив. При этом индекс массива взаимно-однозначно отображается в область определения функции.

Пример

Табуляция функции, 8 узлов.
индекс x f(x) = x2
0 0.0 0
1 0.5 0.25
2 1.0 1.0
3 1.5 2.25
4 2.0 4.0
5 2.5 6.25
6 3.0 9.0
7 3.5 12.25

Пример в коде

// Функция f(x).
double f(double x)
{
  return x * x;
}

// fx    -- массив значений функции f(x);
// nodes -- количество узлов (размер массива);
// x0    -- положение нулевого узла;
// dx    -- расстояние между соседними узлами (x = x0 + dx * i)
void tabulate_x2(double fx[], size_t nodes, double x0, double dx)
{
  for (size_t i = 0; i < nodes; ++i)
    fx[i] = f(x0 + dx * i);
}


Дополнить код robot_walk табуляцией значений шагов — сохранением состояний робота в некоторый массив после выполнения каждой команды из переданной программы.

Вариант 2

Вместо данной работы можно попробовать выполнить более сложную работу 4а.


Общее оглавление

Кувшинов Д.Р. © 2016