просто притворяется, что там стена – если вы зададите мир без окружающих стен, существа не смогут сойти с края.
Мы создали экземпляр мирового объекта. Теперь, когда все необходимые методы готовы, у нас должно получиться заставить его двигаться.
>for (var i = 0; i < 5; i++) {
> world.turn();
> console.log(world.toString());
>}
>// → … пять ходов
Просто выводить пять копий карты – не очень удобный способ наблюдения за миром. Поэтому в песочнице для книги (или в файлах для скачивания) есть волшебная функция >animateWorld
, которая показывает мир как анимацию на экране, делая по три шага в секунду, пока вы не нажмёте стоп.
>animateWorld(world);
>// → … заработало!
Реализация >animateWorld
пока останется тайной, но после прочтения следующих глав книги, обсуждающих интеграцию JavaScript в браузеры, она уже не будет выглядеть так загадочно.
Одна из интересных ситуаций, происходящих в мире, случается, когда два существа отскакивают друг от друга. Можете придумать другую интересную форму взаимодействий?
Я придумал существо, двигающееся по стенке. Оно держит свою левую руку (лапу, щупальце, что угодно) на стене и двигается вдоль неё. Это, как оказалось, не так-то просто запрограммировать.
Нам нужно будет вычислять, используя направления в пространстве. Так как направления заданы набором строк, нам надо задать свою операцию >dirPlus
для подсчёта относительных направлений. >dirPlus("n", 1)
означает поворот по часовой на 45 градусов на север, что приводит к >“ne”
. >dirPlus("s", -2)
означает поворот против часовой с юга, то есть на восток.
>var directionNames = Object.keys(directions);
>function dirPlus(dir, n) {
> var index = directionNames.indexOf(dir);
> return directionNames[(index + n + 8) % 8];
>}
>function WallFollower() {
> this.dir = "s";
>}
>WallFollower.prototype.act = function(view) {
> var start = this.dir;
> if (view.look(dirPlus(this.dir, -3)) != " ")
> start = this.dir = dirPlus(this.dir, -2);
> while (view.look(this.dir) != " ") {
> this.dir = dirPlus(this.dir, 1);
> if (this.dir == start) break;
> }
> return {type: "move", direction: this.dir};
>};
Метод >act
только сканирует окружение существа, начиная с левой стороны и дальше по часовой, пока не находит пустую клетку. Затем он двигается в направлении этой клетки.
Усложняет ситуацию то, что существо может оказаться вдали от стен на пустом пространстве — либо обходя другое существо, либо изначально оказавшись там. Если мы оставим описанный алгоритм, несчастное существо будет каждый ход поворачивать налево, и бегать по кругу.