IQ Marathon, Part II.

Поле, строки, файлы, параметры функций

Тема лабораторной

На данном занятии мы продолжаем написание облегчённой версии игры IQ Marathon.

Objectives

  • Научиться работать с файлами.
  • Работать с параметрами функций.
  • Работать со строками.
  • Работать с многомерными полями (массивами)
  • Научиться работать с тернарными оператором.

Postup

Step 1: Part II.

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

Task 1.1

В коде программы iq_marathon.c создайте функцию int solve_maze(const int height, const int width, char world[][width+1]), которая решит задание игры, при этом вернув количество изменений направления. Поведение самой функции реализуйте в следующих заданиях.

Логика нашего варианта игры будет следующая: Корова будет идти всегда прямо, пока не наткнётся на стену (знак X). Затем сменит своё направление. Если настоящее направление коровы W или E, новым направление может быть только S или N согласно тому, в какой стороне финиш. Аналогично, если актуальное направление коровы S или N, новым направление могут быть W и E.

Task 1.2

В функцию solve_maze() добавьте вызов функций find_cow() и find_finish() таким образом, чтобы могли сохранить направление движения коровы, её координаты и координаты финиша.
  • Координаты запишите в отдельные переменные, например int x, y для исходной позиции и int finish_x, finish_y для конечной.
  • Вместе с исходной позицией важно сохранить и направление коровы, например в переменной char direction.

Task 1.3

В функцию solve_maze() добавьте цикл, с помощью которого вы будете постепенно вести корову к финишу. Функция на игровом поле обозначит места, когда должно поменяться направление, вернув в конце их количество.
  • Бурёнка будет идти прямо пока не наткнётся на стену (знак X). Затем изменит своё направление на 90 градусов в зависимости от того, в которой стороне находится финишная позиция. При этом на месте поворота в массиве нужно поместить знак <, v, > или ^.
  • Игру нельзя выиграть, если после поворота коровка сразу упрётся в другую стену.

Task 1.4

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

Пример игры для карты maze2:

$ ./iq_marathon
Before:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X       X X                  X
X    X               X  XX   X
X                            X
X               X            X
X                    X       X
X    X   XX          X       X
X           X    XXXXXXXXXXXXX
X    N                  X   XX
X       X               X    X
X  XXXXXX         XX         X
X X               X       X  X
X  X XX   X             X    X
X     X              XXXX    X
X     X          X           X
X     X        XXXXXXXXXX  X X
X   X XX                X   XX
X     X    X    X       X    X
X              X     F       X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

After:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X       X X                  X
X    X               X  XX   X
X                            X
X               X            X
X                    X       X
X    X   XX          X       X
X    >     vX    XXXXXXXXXXXXX
X    N                  X   XX
X       X               X    X
X  XXXXXX         XX         X
X X               X       X  X
X  X XX   X             X    X
X     X              XXXX    X
X     X          X           X
X     X        XXXXXXXXXX  X X
X   X XX   >           vX   XX
X     X    X    X       X    X
X              X     F <     X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Number of direction changes: 5

Пример игры для карты maze1:

$ ./iq_marathon
Before:
XXXXXXXXXX
X F X    X
XXXXX    X
X E      X
XXXXXXXXXX

No solution here.

Step 2: Command Line Arguments

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

Task 2.1

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

Task 2.2

Измените главную функцию main() так, чтобы программа работала с файлом, указанным в качестве аргумента командной строки при её запуске.

Task 2.3

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

Пример использования программы может быть следующим:

$ ./iq_marathon
Error: Too few arguments
$ ./iq_marathon maze1
Before:
XXXXXXXXXX
X F X    X
XXXXX    X
X E      X
XXXXXXXXXX

No solution here!
$ ./iq_marathon maze2
Before:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X       X X                  X
X    X               X  XX   X
X                            X
X               X            X
X                    X       X
X    X   XX          X       X
X           X    XXXXXXXXXXXXX
X    N                  X   XX
X       X               X    X
X  XXXXXX         XX         X
X X               X       X  X
X  X XX   X             X    X
X     X              XXXX    X
X     X          X           X
X     X        XXXXXXXXXX  X X
X   X XX                X   XX
X     X    X    X       X    X
X              X     F       X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

After:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
X       X X                  X
X    X               X  XX   X
X                            X
X               X            X
X                    X       X
X    X   XX          X       X
X    >     vX    XXXXXXXXXXXXX
X    N                  X   XX
X       X               X    X
X  XXXXXX         XX         X
X X               X       X  X
X  X XX   X             X    X
X     X              XXXX    X
X     X          X           X
X     X        XXXXXXXXXX  X X
X   X XX  >           vX   XX
X     X    X    X       X    X
X              X     F <     X
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Number of direction changes: 5

Additional Tasks

Task A.1

Наш алгоритм не сможет всегда найти решение для игры, даже если оно существует. Причиной этому служит то, что изменение направления происходит только в том случае, если коровка уткнётся в стену. Измените (улучшите) алгоритм так, чтобы благодаря ему можно было решить и остальные случаи игры. Можете использовать например алгоритм поиска по ширине: Depth first search. Проверьте решение на файле карты maze4.

Task A.2

Создайте модификацию данной игры для робота Карла. Роботу нужно будет найти клад. Карл идёт всегда прямо. Если на позиции количество значков равняется 1, Карл повернётся на север и снова продолжит идти прямо. Если на позиции количество значков равняется 2, Карл повернётся на запад и продолжит идти прямо. Если на позиции количество значков равняется 3, Карл повернётся на юг и продолжит идти прямо. Если на позиции количество значков равняется 4, Карл повернётся на восток и продолжит идти прямо. Если на позиции количество значков равняется 5, это будет означать, что Карл нашёл клад и игра завершается.

Сначала программа содержит в себе карту мира со стенами и позицию, на которой находится клад (5 значков). На карту нужно разместить значки так, чтобы Карл постепенно менял направление, таким образом добравшись к сокровищнице. Робот сначала считает карту мира, согласно которой дойдёт до финиша. Карл может идти только прямо и поворачиваться, если найдет на своей позиции соответствующий значок. Значки затем должны быть собраны.

Реализацию проверьте на файлах карт treasuremap1.kw и treasuremap2.kw.

Additional Resources

  1. Тернарный оператор
  2. Функция fopen(): c-reference, cplusplus.com - Opens a file and returns a file stream associated with that file.
  3. Функция fclose(): c-reference, cplusplus.com - Closes the given file stream.
  4. Функция fscanf(): c-reference, cplusplus.com - Reads data from stdin, interprets it according to format and stores the results into given locations.
  5. Функция fprintf(): c-reference, cplusplus.com - Loads the data from the given locations, converts them to character string equivalents and writes the results to stdout.
  6. Функция perror(): c-reference, cplusplus.com - Displays a character string corresponding of the current error to stderr.
  7. Функция fgetc(): c-reference, cplusplus.com - Reads the next character from the given input stream.
  8. Функция fputc(): c-reference, cplusplus.com - Writes a character ch to the given output stream stream.
  9. Функция fgets(): c-reference, cplusplus.com - Gets a character string from a file stream.
  10. Функция fputs(): c-reference, cplusplus.com - Writes a character string to a file stream.
  11. Функция putchar(): c-reference, cplusplus.com - Writes a character to stdout.

Video

Тернарный оператор с Миланом