Книга: Выразительный JavaScript
Программный интерфейс существ
Программный интерфейс существ
Перед тем, как заняться конструктором мира World
, нам надо определиться с объектами существ, населяющих его. Я упомянул, что мир будет спрашивать существ, какие они хотят произвести действия. Работать это будет так: у каждого объекта существа есть метод act
, который при вызове возвращает действие action
. Action
– объект типа property
, который называет тип действия, которое хочет совершить существо, к примеру “move”
. Action
может содержать дополнительную информацию – такую, как направление движения.
Существа ужасно близоруки и видят только непосредственно прилегающие к ним клетки. Но и это может пригодиться при выборе действий. При вызове метода act
ему даётся объект view
, который позволяет существу изучить прилегающую местность. Мы называем восемь соседних клеток их направлениями по компасу: “n”
на север, “ne”
на северо-восток, и т. п. Вот какой объект будет использоваться для преобразования из названий направлений в смещения по координатам:
var directions = {
"n": new Vector( 0, -1),
"ne": new Vector( 1, -1),
"e": new Vector( 1, 0),
"se": new Vector( 1, 1),
"s": new Vector( 0, 1),
"sw": new Vector(-1, 1),
"w": new Vector(-1, 0),
"nw": new Vector(-1, -1)
};
У объекта view
есть метод look
, который принимает направление и возвращает символ, к примеру "#"
, если там стена, или пробел, если там ничего нет. Объект также предоставляет удобные методы find
и findAll
. Оба принимают один из символов, представляющих вещи на карте, как аргумент. Первый возвращает направление, в котором этот предмет можно найти рядом с существом, или же null
, если такого предмета рядом нет. Второй возвращает массив со всеми возможными направлениями, где найден такой предмет. Например, существо слева от стены (на западе) получит [“ne”, “e”, “se”]
при вызове findAll
с аргументом “#”
.
Вот простое тупое существо, которое просто идёт, пока не врезается в препятствие, а затем отскакивает в случайном направлении.
function randomElement(array) {
return array[Math.floor(Math.random() * array.length)];
}
function BouncingCritter() {
this.direction = randomElement(Object.keys(directions));
};
BouncingCritter.prototype.act = function(view) {
if (view.look(this.direction) != " ")
this.direction = view.find(" ") || "s";
return {type: "move", direction: this.direction};
};
Вспомогательная функция randomElement
просто выбирает случайный элемент массива, используя Math.random
и немного арифметики, чтобы получить случайный индекс. Мы и дальше будем использовать случайность, так как она – полезная штука в симуляциях.
Конструктор BouncingCritter
вызывает Object.keys
. Мы видели эту функцию в предыдущей главе – она возвращает массив со всеми именами свойств объекта. Тут она получает все имена направлений из объекта directions
, заданного ранее.
Конструкция || "s"
в методе act
нужна, чтобы this.direction
не получил null
, в случае если существо забилось в угол без свободного пространства вокруг – например, окружено другими существами.
- Другие инструменты для осуществления резервного копирования
- 12. Лекция: Создание приложений с графическим интерфейсом пользователя.
- 5.21 IP-адреса, интерфейсы и множественное пребывание
- Множественные интерфейсы и имена методов
- 2.1 Интерфейс SCSI
- 2.2 Интерфейсы IDE, EIDE и АТА
- 7.2 Интерфейс WMI
- 7.5 Программные интерфейсы приложений для адаптеров шины
- Не допускайте того, чтобы поток пользовательского интерфейса блокировался на длительное время
- Доступ к существующим рабочим областям для документов
- Абстрактные базы как двоичные интерфейсы
- Интерфейсы накопителей на жестких магнитных дисках