Root /ArchiveAbout
()

Перемещение робота в четырех направлениях

Перемещение робота в четырех направлениях

Сase10. Робот может перемещаться в четырех направлениях («С» — север, «З» — запад, «Ю» — юг, «В» — восток) и принимать три цифровые команды: 0 — продолжать движение, 1 — поворот налево, −1 — поворот направо. Дан символ C — исходное направление робота и целое число N — посланная ему команда. Вывести направление робота после выполнения полученной команды.

Прочитайте сначала задачу. Здесь идется про механизм (робот), который перемещается только влево, вправо или вперед в зависимости от команды, посланной ему. И есть четыре стороны света — север, запад, юг, восток, куда этот робот может направляться. Нужно после каждой команды определить его ориентацию относительно сторон света, если вначале он "смотрел" на север. Надо отметить, что при N=1 делать проверку не надо, поскольку направление останется прежним.

var
  N: integer;
  S: char;

begin
  S := 'C'; { <-- начальное направление }
  writeln('Введите команду (-1, 0 или 1):');
  readln(N);{ <-- Вводим команду }
  { Проверяем направления: }
  case N of
    { Проверяем команды при направлении направо: }
    -1: case S of
          'С': S := 'В'; { <-- север - восток }
          'З': S := 'С'; { <-- запад - север }
          'Ю': S := 'З'; { <-- юг - запад }
          'В': S := 'Ю'  { <-- восток - юг }
        end;
    { Проверяем команды при направлении налево: }    
     1: case S of
          'С': S := 'З'; { <-- север - запад }
          'З': S := 'Ю'; { <-- запад - юг }
          'Ю': S := 'В'; { <-- юг - восток }
          'В': S := 'С'  { <-- восток - север }
        end
  end;
  writeln('Направление: ', S);
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. * * *

А теперь предположим, что начальное направление не задано и его нужно ввести с клавиатуры. Тогда имеем второе решение задачи Case10, которое отличается от предыдущего ещё и проверкой вводимых данных.

var
  N: integer;
  S: char;

begin
  { Вводим начальное направление: }
  repeat
    writeln('Введите направление (С, З, Ю или В):');
    readln(S);
  until S in ['С','с','З','з','Ю','ю','В','в'];
  { Вводим команду: }
  repeat
    writeln('Введите команду (-1, 0 или 1):');
    readln(N);
  until (N > -2) and (N < 2);
  { Проверяем направления: }
  case N of
    { Проверяем команды при направлении направо: }
    -1: case S of
          'С','с': S := 'В'; { <-- север - восток }
          'З','з': S := 'С'; { <-- запад - север }
          'Ю','ю': S := 'З'; { <-- юг - запад }
          'В','в': S := 'Ю'  { <-- восток - юг }
        end;
    { Проверяем команды при направлении налево: }    
     1: case S of
          'С','с': S := 'З'; { <-- север - запад }
          'З','з': S := 'Ю'; { <-- запад - юг }
          'Ю','ю': S := 'В'; { <-- юг - восток }
          'В','в': S := 'С'  { <-- восток - север }
        end
  end;
  writeln('Направление: ', S);
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. * * *

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

С этой целью будем использовать цикл while, условием вхождения в который будет проверка правильности введенной команды. Если команда введена верная, то после выполнения операторов цикла мы получим новое направление робота, если неверная — мы обойдем цикл и прочитаем в конце сообщение о неправильности введенной команды. А в самом цикле while будем проверять каждое направление по отдельности. Так, если сначала робот "смотрел" на север, то после поворота влево он повернется на запад, а после поворота вправо — на восток, и так все четыре направления. Для проверки направлений используем оператор выбора case.

var
  N: integer;
  S: char;

begin
  S := 'С'; { <-- Начальное направление (по условию) }
  { Далее продолжаем в цикле. Это делается для того, чтобы
  каждый раз не запускать программу, а только вводить новые
  значения. Повторяем команды до тех пор, пока введенное 
  число N находится в пределах интервала [-1, 1]: }
  while (N > -2) and (N < 2) do begin
    { Далее проверяем ТОЛЬКО -1 и 1, поскольку при N = 0
    мы продолжаем движение (в том же направлении): } 
    case N of
     { Проверяем направление вправо: }
     -1: case S of
           'С': S := 'В'; { север - восток }
           'З': S := 'С'; { запад - север }
           'Ю': S := 'З'; { юг - запад }
           'В': S := 'Ю'  { восток - юг }
         end;
     { Проверяем направление влево: }    
      1: case S of
           'С': S := 'З'; { север - запад }
           'З': S := 'Ю'; { запад - юг }
           'Ю': S := 'В'; { юг - восток }
           'В': S := 'С'  { восток - север }
         end
    end;
    writeln('Направление: ', S);
    { Запрашиваем ввод команды: } 
    writeln('Введите команду (-1, 0 или 1):');
    readln(N) { <-- Вводим номер команды } 
  end; 
  writeln;
  { Если N выходит за допустимые границы, то сообщаем: }
  writeln('  Вы ввели неверную команду!');
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. * * *

Отличие четвертого варианта решения задачи Case10 в том, что здесь переменные S и N во вложенных операторах выбора case меняются местами: внешний – по S, а внутренний – по N. Цикл оставляем, но при необходимости его можно убрать.

var
  N: integer;
  S: char;

begin 
  S := 'С'; { <-- Исходное направление (по условию) }
  { Вводим команды -1, 0 и 1 в цикле до первой неверной 
  введенной команды, после которой программа завершится: }
  while (N > -2)and(N < 2) do begin
    { Проверяем ТОЛЬКО -1 и 1, поскольку при N = 0 
    продолжается движение в предыдущем направлении: }
    case S of
      'С': case N of
            -1: S := 'В'; { <-- поворот направо - восток }
             1: S := 'З'  { <-- поворот налево - запад }
           end;
      'З': case N of
            -1: S := 'С'; { <-- поворот направо - север }
             1: S := 'Ю'  { <-- поворот налево - юг }
           end;
      'Ю': case N of
            -1: S := 'З'; { <-- поворот направо - запад }
             1: S := 'В'  { <-- поворот налево - восток }
           end;
      'В': case N of
            -1: S := 'Ю'; { <-- поворот направо - юг }
             1: S := 'С'  { <-- поворот налево - север }
           end
    end;
    writeln('направление:  ', S); { <-- Выводим направление }
    writeln;
    { Запрашиваем ввод новой команды: } 
    writeln('Введите команду (-1, 0 или 1): ');
    readln(N);
  end;
  writeln;
  { Если N выходит за допустимые границы, то сообщаем: } 
  writeln('Вы ввели неверную команду!');
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. Сase11. Локатор ориентирован на одну из сторон света («С» — север, «З» — запад, «Ю» — юг, «В» — восток) и может принимать три цифровые команды поворота: 1 — поворот налево, −1 — поворот направо, 2 — поворот на 180°. Дан символ C — исходная ориентация локатора и целые числа N1 и N2 — две посланные команды. Вывести ориентацию локатора после выполнения этих команд.

Сначала прочитайте условие задачи выше. Здесь речь идет о локаторе, который может поворачивать влево, вправо или на 180 градусов. Как и в задаче case10, он ориентирован по сторонам света и начальная его позиция — на север (символ С). Но в отличие от предыдущей задачи, этому локатору подаются уже две команды поворота, и требуется определить ориентацию локатора после их выполнения. Это простейший вариант решения, используем только условный оператор if и оператор выбота case.

var
  N1, N2: integer; { <-- команды }
  S: char;

begin
  S := 'С'; { <-- Начальное направление на север }
  { Вводим команды: }
  write('N1 = ');
  readln(N1);
  write('N2 = ');
  readln(N2);
  { Проверяем команду N1: }
  case N1 of
    -1: case S of
          'С': S := 'В'; { север - восток }
          'З': S := 'С'; { запад - север }
          'Ю': S := 'З'; { юг - запад }
          'В': S := 'Ю'  { восток - юг }
        end;
     1: case S of
          'С': S := 'З'; { север - запад }
          'З': S := 'Ю'; { запад - юг }
          'Ю': S := 'В'; { юг - восток }
          'В': S := 'С'  { восток - север }
        end;
     2: case S of
          'С': S := 'Ю'; { север - юг }
          'З': S := 'В'; { запад - восток }
          'Ю': S := 'С'; { юг - север }
          'В': S := 'З'  { восток - запад }
        end
     else N1 := 0 { <-- Если команда неверная }
  end;
  if N1 <> 0 then begin
    { Проверяем команду N2: }
    case N2 of
      -1: case S of
            'С': S := 'В'; { север - восток }
            'З': S := 'С'; { запад - север }
            'Ю': S := 'З'; { юг - запад }
            'В': S := 'Ю'  { восток - юг }
          end;  
       1: case S of
            'С': S := 'З'; { север - запад }
            'З': S := 'Ю'; { запад - юг }
            'Ю': S := 'В'; { юг - восток }
            'В': S := 'С'  { восток - север }
          end;
       2: case S of
            'С': S := 'Ю'; { север - юг }
            'З': S := 'В'; { запад - восток }
            'Ю': S := 'С'; { юг - север }
            'В': S := 'З'  { восток - запад }
          end
       else N2 := 0 { <-- Если команда неверная }
    end;
    if N2 <> 0 then writeln('Направление:  ', S)
    else writeln('Ошибка ввода команды!')
  end
  else writeln('Ошибка ввода команды!');
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. * * *

Могу предложить следующий вариант решения. Пусть необходимо посчитать ориентацию робота после M введенных команд (N1, N2, N3 ..., Nm). Естественно, можно было бы сначала вводить числа N1, N2, ..., Nm, а потом определять направление робота. Но можно поступить проще: после каждого ввода команды находить ориентацию робота, а как будут введены все команды, выдать остаточный результат.

Здесь без цикла уже не обойтись. Для команд потребуется только одна переменная N, и еще одна number – для подсчета их количества.

const
  M = 2; { <-- Количество команд для ввода (по условию 2 команды) }

var
  N, number: integer; { N - команда, number - её номер }
  S: char;

begin
  S := 'С'; { <-- Начальное направление на север }
  number := 0; { <-- Номер команды (команд ещё нет) }
  writeln('Введите ', M, ' команд:');
  { Команды будем вводить в цикле до тех пор, пока не будут введены 
  все M команд. После каждой введенной команды N будем увеличивать её 
  порядковый номер number и находить промежуточную ориентацию S. Если
  при этом команда введена неверная (число, отличное от -1, 1 или 2),
  то положим number=0. Выходим из цикла, если number=0 (введена неверная 
  команда) или number=M (все команды правильные). }
  repeat
    read(N); { <-- Вводим команду }
    inc(number); { <-- Находим номер введенной команды }
    case N of
      { Проверяем направление вправо: }
      -1: case S of
            'С': S := 'В'; { север - восток }
            'З': S := 'С'; { запад - север }
            'Ю': S := 'З'; { юг - запад }
            'В': S := 'Ю'  { восток - юг }
          end;
      { Проверяем направление влево: }    
       1: case S of
            'С': S := 'З'; { север - запад }
            'З': S := 'Ю'; { запад - юг }
            'Ю': S := 'В'; { юг - восток }
            'В': S := 'С'  { восток - север }
          end;
      { Проверяем поворот на 180 градусов: }    
       2: case S of
            'С': S := 'Ю'; { север - юг }
            'З': S := 'В'; { запад - восток }
            'Ю': S := 'С'; { юг - север }
            'В': S := 'З'  { восток - запад }
          end
       else number := 0 { <-- Если команда введена неверная }
    end
  until (number = 0) or (number = M);
  writeln;
  { Если все M корманд верные, то выводим конечный результат, 
  в противном случае выводим сообщение об ошибке: }
  if number = M then writeln('Направление:  ', S)
  else writeln('  Вы ввели неверную команду.');
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1 * * *

Если использовать функцию, то предыдущий вариант решения Case11 может выглядеть так (все комментарии в коде):

const
  M = 2; { <-- Количество команд для ввода }

{ Функция возвращает True и направление локатора S, если 
команада N верная. В противном случае мы получим False }
function povorot(N: integer; var S: char): boolean;
begin
  povorot := true;
  case N of
    { Проверяем направление вправо: }
    -1: case S of
          'С': S := 'В'; { север - восток }
          'З': S := 'С'; { запад - север }
          'Ю': S := 'З'; { юг - запад }
          'В': S := 'Ю'  { восток - юг }
        end;
    { Проверяем направление влево: }    
     1: case S of
          'С': S := 'З'; { север - запад }
          'З': S := 'Ю'; { запад - юг }
          'Ю': S := 'В'; { юг - восток }
          'В': S := 'С'  { восток - север }
        end;
    { Проверяем поворот на 180 градусов: }    
     2: case S of
          'С': S := 'Ю'; { север - юг }
          'З': S := 'В'; { запад - восток }
          'Ю': S := 'С'; { юг - север }
          'В': S := 'З'  { восток - запад }
        end
     else povorot := false { <-- Команда введена неверная }
  end
end;

var
  N, number: integer; { N - команда, number - её номер }
  S: char;
  bln: boolean;

begin
  S := 'С'; { <-- Начальное направление на север }
  number := 0; { <-- Количество введенных команд }
  writeln('Введите ', M, ' команд:');
  repeat
    inc(number); { <-- Увеличиваем номер команды }
    repeat
      write('N', number, ' = ');
      readln(N); { <-- Вводим команду }
      bln := povorot(N, S); { <-- Определяем правильность команды }
      { Если команда неверная, то сообщаем: }
      if not bln then writeln(' Введите другую команду!');
    until bln; { <-- Если ввели правильную команду, то выходим }
  until number = M; { <-- Если ввели все M команд, то выходим }
  writeln;
  writeln('Направление:  ', S);
  readln
end.

**type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. **type** boolean;: Представляет логическое значение. **const** true = True;: Представляет логическое значение. **const** false = False;: Представляет логическое значение. **type** integer;: Представляет 32-битовое целое число со знаком.Диапазон значений: -2 147 483 648 .. 2 147 483 647 **type** char;: Представляет символ Юникода. **type** boolean;: Представляет логическое значение. **procedure** Inc(**var** i: integer);: Увеличивает значение переменной i на 1