> return dest;
> }
>};
Сначала мы просто просим существо действовать, передавая ему объект >view
, который знает про мир и текущее положение существа в мире (мы скоро зададим >View
). Метод >act
возвращает какое-либо действие.
Если тип действия не >“move”
, оно игнорируется. Если >“move”
, и если у него есть свойство >direction
, ссылающееся на допустимое направление, и если клетка в этом направлении пустует (>null
), мы назначаем клетке, где только что было существо, >null
, и сохраняем существо в клетке назначения.
Заметьте, что >letAct
заботится об игнорировании неправильных входных данных. Он не предполагает по умолчанию, что направление допустимо, или, что свойство типа имеет смысл. Такого рода защитное программирование в некоторых ситуациях имеет смысл. В основном это делается для проверки входных данных, приходящих от источников, которые вы не контролируете (ввод пользователя или чтение файла), но оно также полезно для изолирования подсистем друг от друга. В нашем случае его цель – учесть, что существа могут быть запрограммированы неаккуратно. Им не надо проверять, имеют ли их намерения смысл. Они просто запрашивают возможность действия, а мир сам решает, разрешать ли его.
Эти два метода не принадлежат к внешнему интерфейсу мирового объекта. Они являются деталями внутренней реализации. Некоторые языки предусматривают способы объявлять определённые методы и свойства «приватными», и выдавать ошибку при попытке их использования снаружи объекта. JavaScript не предусматривает такого, так что вам придётся полагаться на другие способы сообщить о том, что является частью интерфейса объекта. Иногда помогает использование схемы именования свойств для различения внутренних и внешних, например, с особыми приставками к именам внутренних, типа подчёркивания (>_
). Это облегчит выявление случайного использования свойств, не являющихся частью интерфейса.
А пропущенная часть, тип >View
, выглядит следующим образом:
>function View(world, vector) {
> this.world = world;
> this.vector = vector;
>}
>View.prototype.look = function(dir) {
> var target = this.vector.plus(directions[dir]);
> if (this.world.grid.isInside(target))
> return charFromElement(this.world.grid.get(target));
> else
> return "#";
>};
>View.prototype.findAll = function(ch) {
> var found = [];
> for (var dir in directions)
> if (this.look(dir) == ch)
> found.push(dir);
> return found;
>};
>View.prototype.find = function(ch) {
> var found = this.findAll(ch);
> if (found.length == 0) return null;
> return randomElement(found);
>};
Метод >look
вычисляет координаты, на которые мы пытаемся посмотреть. Если они находятся внутри сетки, то получает символ, соответствующий элементу, находящемуся там. Для координат снаружи сетки