Сибирский федеральный университет
Опубликован: 01.09.2010 | Доступ: свободный | Студентов: 3999 / 417 | Оценка: 4.08 / 3.78 | Длительность: 11:06:00
Лекция 9:

Сценарии Javascript

Создание пользовательских объектов

Функции могут служить конструкторами пользовательских объектов. В этом случае ключевое слово this является ссылкой на вновь создаваемый объект.

//конструктор объекта Окружность
  function Circle(x, y, r) {
    this.x = x; //x-координата центра
    this.y = y; //y-координата центра
    this.r = r; //радиус окружности
  }

  //создание объектов
  var circle1 = new Circle(1, 1, 2);
  var circle2 = new Circle(3, 3, 1);

Свойство prototype функции-конструктора позволяет добавлять свойства и методы как к пользовательским, так и встроенным объектам.

function getLength() {
      //this является ссылкой на объект, 
      //в контексте которого осуществляется вызов
      return 2 * Math.PI * this.r; //длина окружности
    }

    //подключаем функцию к конструктору
    //обратите внимание на отсутствие скобок 
    //без скобок присваивается объект-функция
    //со скобками – результат выполнения функции
    Circle.prototype.length = getLength;

    //Добавим еще один метод
    Circle.prototype.area = function() {
      return Math.PI * this.r * this.r; //площадь круга
    }

    document.write("circle1 имеет радиус " + circle1.r +
      ", длину " + circle1.length() +
      " и площадь " + circle1.area());

Использование функции-конструктора позволяют создавать любое число объектов. Если требуется всего один объект, можно воспользоваться альтернативным синтаксисом.

var uniqueObj = {
      prop1: 10, //определяем числовое свойство
      prop2: 'red', //определяем строковое свойство
      method1: function() { return 'Hello'; } //определяем метод
    };
Внешние объекты

Internet Explorer и другие браузеры открывают доступ к собственной объектной модели через программный интерфейс приложения (Application Programming Interface, API), так что свойства, методы и события объектов браузера становятся доступны для Javascript.

Пример: карточная игра Blackjack

В качестве примера разработаем карточную игру, известную под названием Blackjack, которая будет работать в веб-браузере.

Правила игры

Игра ведется колодой карт из 52 листов, от двойки до туза в каждой из четырех мастей. Каждая карта имеет свою цену, в очках. (От двойки до десятки в соответствии со значением, картинки – 10, туз 11 или 1, в зависимости от набранных очков)

В игре участвуют два игрока: собственно игрок и крупье. Цель игры - набрать больше очков, чем противник, но не более 21 (за исключением двух тузов).

Игрок (человек) делает ставку в пределах своего баланса и берет карты по одной, пока не сочтет количество очков достаточным, после чего передает ход крупье.

Крупье (компьютер) действует автоматически.

Разработка объектной модели

Колода состоит из карт. Каждая карта характеризуется мастью, значением и числом очков. Кроме того, уместно привязать к карте ее картинку. Фактически, если перенумеровать все карты в колоде от 0 до 51, то все свойства карты можно рассчитать из ее порядкового номера.

//конструктор карты
    function Card(n) {
      //вспомогательные массивы
      var suits = ['треф', 'бубен', 'червей', 'пик'];
      var names = ['2', '3', '4', '5', '6', '7', '8', '9', '10', 'Валет', 'Дама', 'Король', 'Туз'];
      var values = [2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 11];

      //рассчитываем свойства карты по ее номеру
      this.suit = suits[parseInt(n / 13)]; //масть
      this.name = names[n % 13]; //название
      this.value = values[n % 13]; //очки

      //прикладываем картинку к карте - объект Image Веб браузера
      this.img = new Image();
      //рассчитываем имя файла и инициализируем загрузку файла,
      //полагая, что изображения хранятся в папке deck
      //и поименованы от 0.gif для двойки треф
      //до 51.gif для туза пик
      this.img.src = 'deck/' + n + '.gif';
      //задаем дополнительные атрибуты изображения
      this.img.alt = this.toString();
      this.img.className = 'Card';
    }
    // переопределяем функцию toString
    Card.prototype.toString = function() {
      return this.name + ' ' + this.suit;
    }

Колода – единичный объект. Создадим его для дальнейшего использования.

var Deck = {
      cards: [], //собственно колода - массив карт, изначально пустой
      num: 0, // внутренний счетчик

      //колоду нужно инициализировать перед первым использованием
      init: function() {
        //заполняем массив
        for (var i = 0; i < 52; i++)
        //все данные карты рассчитываются по ее номеру
          this.cards[i] = new Card(i);
      },

      //тасуем колоду, т.е. сортируем в случайном порядке
      shuffle: function() {
        this.cards.sort(function() {
            return (Math.random() < 0.5 ? 1 : -1);
          }
        );
        this.num = 0; //инициализируем счетчик
      },

      nextCard: function() {
        //возвращает верхнюю карту из колоды
        return this.cards[this.num++];
      }
    };

В игре участвуют двое. Создадим конструктор для них.

function Hand() { } // конструктор игрока необходим, даже пустой

    Hand.prototype = {//свойства и методы игрока
      balance: 1000, //начальная сумма
      currentBet: 0, //текущая ставка
      cards: [], //массив карт у игрока
      //Методы игрока
      init: function() {//сбросить карты
        this.cards = new Array();
      },
      bet: function() {//увеличиваем ставку
        this.balance += this.currentBet;
        if (this.currentBet == 0)
          this.currentBet = 10; //произвольная начальная ставка
        else
          this.currentBet *= 2; //удваиваем ставку

        //ограничим ставку балансом игрока
        if (this.balance >= this.currentBet)
          this.balance -= this.currentBet;
        else {
          this.currentBet = this.balance;
          this.balance = 0
        }
        //возвращаем значение для удобства использования
        return this.currentBet;
      },
      nextCard: function() {//взять следующую карту
        var card = Deck.nextCard(); //следующая карта из колоды
        this.cards.push(card); //добавляем в конец массива
        //возвращаем значение для удобства использования
        return card;
      },
      //подсчитываем очки на руке игрока
      calc: function() {
        var sum = 0; //сумма очков
        var aces = 0; // число тузов
        if (this.cards)//если массив карт не пустой
          for (var i in this.cards) {
          if (this.cards[i].value == 11)
            aces++; //найден туз
          //суммируем очки
          sum += this.cards[i].value;
        }
        //если на руке не более 2 карт, пересчет не нужен
        if (this.cards.length < 3)
          return sum;
        // в случае перебора считаем туза за 1
        while (sum > 21 && aces > 0) {
          sum -= 10;
          aces--;
        }
        return sum;
      },
      //сравнение двух игроков
      compare: function(anotherHand) {
        //результат: 1 - победил первый, 
        //-1 - победил второй, 0 – ровно
        //подсчитываем очки первого игрока
        var a = this.calc();
        if (a > 21 && this.cards.length > 2)//перебор у первого
          return -1;
        //подсчитываем очки второго игрока
        var b = anotherHand.calc();
        if (b > 21 && anotherHand.cards.length > 2)
        // перебор у второго
          return 1;
        if (a == b)//ровно
          return 0;
        if (a == 22 && this.cards.length == 2)
        // у первого игрока Black Jack
          return 1;
        if (b == 22 && anotherHand.cards.length == 2)
        // у второго игрока Black Jack
          return -1;
        if (a > b)//У первого больше
          return 1;
        //остается единственный вариант - у второго больше
        return -1;
      }
    };
Юрий Шах
Юрий Шах

Профессиональный веб-дизайн: Введение в современные веб-технологии
Самостоятельная работа 4

"3. Создание внешней таблицы.

Теперь создайте таблицу с двумя строками. Во второй строке создайте две ячейки - в первую переместите таблицу цифр, а во вторую - таблицу знаков."

Как в ячейку <td> поместить таблицу? Таблица же сама состоит из ячеек. Исходя из задания следует, что <td> может быть родителем для <td>, но это противоречит правилам HTML?
Если не прав - поправьте.
Также прошу разъяснить, как именно выполнить занное условие - поместить в табличную ячейку таблицу цифр, а в другую ячейку - таблицу знаков? 

Елена Сапегова
Елена Сапегова

После прохождения теоретической части пришло письмо об окончании теоретической части курса, будет ли практическая часть?