Задача №558. Игра "черный ящик"
Загрузить архив проверяющих библиотек
В игру «черный ящик» играют с помощью квадратного черного ящика, который располагается на плоском столе. На каждой из сторон ящика есть n отверстий (всего 4n отверстий), в которые можно вбрасывать шар. Вброшенный шар через некоторое время вылетит наружу через одно из 4n отверстий, возможно, через то же отверстие, в которое он был вброшен.

Содержимое черного ящика можно рассматривать в виде сетки размером n x n. Отверстия в сторонах ящика – это начала и концы строк и столбцов сетки. Каждая клетка сетки либо пустая, либо занята отражателем. Отражатель – это устройство, которое изменяет направление движения шара на 90 градусов. Рассмотрим пример ящика размером 5x 5.
Вброшенный шар движется по прямой, пока не попадает в отражатель или не вылетит наружу. Когда шар попадает в отражатель, шар меняет направление своего движения, а отражатель меняет свое положение (под словом «меняет» подразумевается поворот на 90 градусов). На примере показаны действия отражателя.
a)
Первый шар вброшен через отверстие. Он попал в отражатель и изменил направление движения.
b)
После попадания первого шара отражатель изменил свое положение. Новый шар вбросили в то же отверстие, он попал в тот же отражатель, и отразился в направлении, противоположном направлению первого шара после отражения.
c)
Отражатель изменил свое положение. После каждого попадания положение отражателя изменяется.
Когда шар попадает в отражатель, раздается звуковой сигнал. Количество отражений шара можно узнать, посчитав количество сигналов. Можно доказать, что шар всегда вылетает из ящика. У ящика есть одна кнопка, которая приводит его в исходное положение, и другая кнопка, которая меняет положение всех отражателей на противоположное.
ЗАДАНИЕ
Вам будет предоставлен интерфейс к 15 черным ящикам с помощью библиотеки функций Pascal
или C/C++. Вы должны определить содержимое каждого из ящиков как можно точнее и отправить на проверку файлы, описывающие каждый ящик. Интерфейс также предоставляет возможность создания собственных ящиков для тестирования.
ОГРАНИЧЕНИЯ
1 ≤ n ≤ 30
ВЫВОД
Вы должны предоставить на проверку файлы, содержащие следующие данные для каждого из 15 черных ящиков:
blackboxK.out |
ОПИСАНИЕ |
#FILE blackbox K ..... .../. .... .../. .?.?. |
СТРОКА 1: Заголовок файла, который должен иметь вид #FILE blackbox K где K (число в диапазоне 1..15) соответствует ящику, для которого найдено решение. n СТРОК:
Каждая строка описывает строку ящика, начиная с верхней и заканчивая нижней. Каждая строка должна содержать ровно n
символов, соответствующих клеткам, находящимся на пересечении этой строки и столбцов (слева направо).
·
Символ ‘.’ обозначает, что клетка пуста.
·
Символ ‘/’ обозначает, что в клетке находится отражатель с исходным положением ‘/’
·
Символ ‘’ обозначает, что в клетке находится отражатель с исходным положением ‘’
·
Символ ‘?’ обозначает, что Вы не смогли определить исходное содержимое клетки |
БИБЛИОТЕКА
Вам будет предоставлена библиотека, которая содержит следующие функции:
ФУНКЦИЯ |
Описание |
PASCAL function Initialize(box: integer): integer; C/C++ int Initialize(int box); |
Инициализирует библиотеку. Эта функция должна вызываться один раз в начале программы. Она возвращает значение n
– количество отверстий на каждой стороне ящика. Параметр box
должен содержать целое число в пределах от 1 до 15, указывающее номер ящика, который Вы хотите использовать, или 0, если Вы хотите использовать ящик, созданный Вами.
|
PASCAL function throwBall(holeIn, sideIn: integer; var holeOut, sideOut: integer): longint; C int throwBall(int holeIn, int sideIn, int *holeOut, int *sideOut); C++ int throwBall(int holeIn, int sideIn, int &holeOut, int &sideOut); |
Вбрасывает шар в ящик через отверстие с номером holeIn на стороне sideIn.
Стороны пронумерованы следующим образом: 1 – Верхняя, 2 – Правая, 3 – Нижняя и 4 – Левая. Отверстия пронумерованы слева направо и сверху вниз, начиная с номера 1 на каждой стороне. В параметрах holeOut
и sideOut
функция возвращает номер отверстия и номер стороны – место, где шар вылетел наружу. В качестве своего значения функция throwBall
возвращает количество звуковых сигналов, вызванных попаданиями шара в отражатели.
|
PASCAL procedure ResetBox; C/C++ Void ResetBox(); |
Возвращает все отражатели в исходное положение. |
PASCAL procedure ToggleDeflectors; C/C++ Void ToggleDeflectors(); |
Меняет положения всех отражателей в ящике на противоположные. |
PASCAL procedure Finalize; C/C++ Void Finalize(); |
Корректно заканчивает взаимодействие с ящиком. Эта функция должна вызываться в конце Вашей программы. |
Чтобы использовать библиотеку в Вашей программе, необходимо выполнить следующее:
·
FreePascal: В каталоге задачи есть файлы pbblib
.o и pbblib.
ppu. Чтобы их использовать, необходимо добавить следующую строку в Вашу программу
uses pbblib;
В файле pblackbox.pas представлен пример использования библиотеки.
·
C: В каталоге задачи есть файлы
cbblib.o и
cbblib.h. Чтобы их использовать, необходимо добавить следующую директиву в Вашу программу
#include “cbblib.h”
В файле cblackbox.c
представлен пример использования библиотеки. Чтобы скомпилировать код, используйте следующую команду
gcc –o yourprogram cbblib.o yourprogram.c
·
C++: В каталоге задачи есть файлы
cppbblib.o
и cppbblib.h. Чтобы их использовать, необходимо добавить следующую директиву в Вашу программу
#include “cppbblib.h”
В файле cppblackbox
.cpp представлен пример использования библиотеки. Чтобы скомпилировать код, используйте следующую команду
g++ –o yourprogram cppbblib.o yourprogram.cpp
ЗАМЕЧАНИЕ: В любой момент времени может быть запущено не более одной программы, работающей с библиотекой.
ПРИМЕР ВЗАИМОДЕЙСТВИЯ
Ниже представлен пример взаимодействия с ящиком, изображенным ранее на рисунке:
ВЫЗОВ ФУНКЦИИ |
ВОЗВРАЩЕННОЕ ЗНАЧЕНИЕ |
Initialize(0); |
Пусть программа взаимодействует с ящиком, изображенным на рисунке. Тогда функция возвращает значение 5, означая, что n
= 5.
|
PASCAL throwBall(3,4,holeOut,sideOut
);
C throwBall(3,4,&holeOut,&sideOut); C++ throwBall(3,4,holeOut,sideOut); |
Шар вбрасывается в отверстие с номером 3 (третье сверху) на левой стороне. Возвращается значение 1 – это означает, что шар отразился один раз. После возврата из функции, переменная holeOut
содержит значение 2, а переменная sideOut
содержит значение 3, то есть шар вылетел через отверстие с номером 2 (второе слева) нижней стороны ящика.
|
ЭКСПЕРИМЕНТИРОВАНИЕ
Если Вы передадите значение 0 в функцию Initialize, библиотека прочитает содержимое ящика из файла
blackbox.in. Так Вы сможете экспериментировать с библиотекой. Формат
файла blackbox.in
описан ниже.
blackbox.in |
ОПИСАНИЕ |
5 3 2 3 4 2 / 4 4 / |
СТРОКА 1: Содержит целое число n,
которое задает количество отверстий на каждой стороне. СТРОКА 2: Содержит целое число d
, которое задает количество отражателей в ящике.
СЛЕДУЮЩИЕ d СТРОК:
Каждый отражатель описывается одной строкой. Каждая строка содержит два целых числа, разделенных пробелом, которые задают номер столбца и строки, где расположен отражатель. После второго числа через один пробел записан
символ, который может быть ‘/’ или ‘’ и определяет исходное положение отражателя.
|
ЗАМЕЧАНИЕ: Файл blackbox.
in из примера описывает ящик, изображенный вверху страницы 1.
СООБЩЕНИЯ ОБ ОШИБКАХ
В случае любых проблем библиотека выведет сообщение об ошибке в стандартный поток вывода ошибок. Возможные сообщения об ошибке и их значения приведены в нижеследующей таблице.
СООБЩЕНИЕ |
ЗНАЧЕНИЕ |
ERR 1 More than one app |
Только одна программа может одновременно работать с черными ящиками, перезапустите все программы и запускайте их строго по одной. |
ERR 2 Invalid box |
Переданный вами номер ящика не лежит в пределах от 0 до 15. |
ERR 3 Invalid deflector |
В файле blackbox.in находится отражатель в некорректной клетке. |
ERR 4 Invalid symbol |
В файле blackbox.in обнаружен недопустимый символ. |
ERR 5 Invalid size |
Размер ящика в файле blackbox.
in задан неверно. |
ERR 6 Invalid input hole |
Либо сторона, либо отверстие вбрасывания шара заданы неверно. |
ERR 7 ALARM |
Пожалуйста, обратитесь к техническому персоналу. |