Выразительный JavaScript (Хавербеке) - страница 70

>            "#                          #",

>            "#          #####           #",

>            "##         #   #    ##     #",

>            "###           ##     #     #",

>            "#           ###      #     #",

>            "#   ####                   #",

>            "#   ##       o             #",

>            "# o  #         o       ### #",

>            "#    #                     #",

>            "############################"];

Символ “>#” обозначает стены и камни, “>o” – существо. Пробелы – пустое пространство.

План можно использовать для создания объекта мира. Он следит за размером и содержимым мира. У него есть метод >toString, который преобразовывает мир в выводимую строчку (такую, как план, на котором он основан), чтобы мы могли наблюдать за происходящим внутри него. У объекта мир есть метод >turn (ход), позволяющий всем существам сделать один ход и обновляющий состояние мира в соответствии с их действиями.

Изображаем пространство

У сетки, моделирующей мир, заданы ширина и высота. Клетки определяются координатами x и y. Мы используем простой тип >Vector (из упражнений к предыдущей главе) для представления этих пар координат.

>function Vector(x, y) {

>  this.x = x;

>  this.y = y;

>}

>Vector.prototype.plus = function(other) {

>  return new Vector(this.x + other.x, this.y + other.y);

>};

Потом нам нужен тип объекта, моделирующий саму сетку. Сетка – часть мира, но мы делаем из неё отдельный объект (который будет свойством мирового объекта), чтобы не усложнять мировой объект. Мир должен загружать себя вещами, относящимися к миру, а сетка – вещами, относящимися к сетке.

Для хранения сетки значений у нас есть несколько вариантов. Можно использовать массив из массивов-строк, и использовать двухступенчатый доступ к свойствам:

>var grid = [["top left",    "top middle",    "top right"],

>            ["bottom left", "bottom middle", "bottom right"]];

>console.log(grid[1][2]);

>// → bottom right

Или мы можем взять один массив, размера width × height, и решить, что элемент (x, y) находится в позиции x + (y × width).

>var grid = ["top left",    "top middle",    "top right",

>            "bottom left", "bottom middle", "bottom right"];

>console.log(grid[2 + (1 * 3)]);

>// → bottom right

Поскольку доступ будет завёрнут в методах объекта сетки, внешнему коду всё равно, какой подход будет выбран. Я выбрал второй, потому что с ним проще создавать массив. При вызове конструктора >Array с одним числом в качестве аргумента он создаёт новый пустой массив заданной длины.

Следующий код объявляет объект >Grid (сетка) с основными методами: