>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
, в случае если существо забилось в угол без свободного пространства вокруг – например, окружено другими существами.
Теперь можно приступать к мировому объекту >World
. Конструктор принимает план (массив строк, представляющих сетку мира) и объект >legend
. Это объект, сообщающий, что означает каждый из символов карты. В нём есть конструктор для каждого символа – кроме пробела, который ссылается на >null
(представляющий пустое пространство).
>function elementFromChar(legend, ch) {
> if (ch == " ")
> return null;
> var element = new legend[ch]();
> element.originChar = ch;
> return element;
>}
>function World(map, legend) {
> var grid = new Grid(map[0].length, map.length);
> this.grid = grid;
> this.legend = legend;
> map.forEach(function(line, y) {
> for (var x = 0; x < line.length; x++)
> grid.set(new Vector(x, y),
> elementFromChar(legend, line[x]));
> });
>}
В >elementFromChar
мы сначала создаём экземпляр нужного типа, находя конструктор символа и применяя к нему >new
. Потом добавляем свойство >originChar
, чтобы было просто выяснить, из какого символа элемент был создан изначально.
Нам понадобится это свойство >originChar
при изготовлении мирового метода >toString
. Метод строит карту в виде строки из текущего состояния мира, проходя двумерным циклом по клеткам сетки.
>function charFromElement(element) {
> if (element == null)
> return " ";
> else
> return element.originChar;
>}
>World.prototype.toString = function() {
> var output = "";
> for (var y = 0; y < this.grid.height; y++) {
> for (var x = 0; x < this.grid.width; x++) {
> var element = this.grid.get(new Vector(x, y));