- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
JavaScript. Учебник начального уровня - DarkGoodWIN
Шрифт:
Интервал:
Закладка:
for(var j = 0; j < colCount; j++)
{
var cell = row.insertCell(j);
if (mines[i * rowCount + j] == 1)
cell.innerHTML = '*'
else
cell.innerHTML = '.';
}
}
}
script>
<body onload=«initTable();">
<table id=«tbl» border=«2» width=«80%" height=«80%">
table>
body>
html>
К сожалению в каждой новой главе, кода становится всё больше, при этом нового кода вообще говоря всего ничего. Это вечная дилема — приводить куски кода в каждой новой главе, но тогда могут быть проблемы с пониманием того, что к чему относится, либо постоянно копировать и тогда текст раздувается до каких–то нереальных размеров. Я пока решил придерживаться второго варианта. Дальше посмотрю.
Мы видим уже знакомую страничку со скриптом. Посмотрим скрипт снизу вверх. Внизу у нас уже знакомая по прошлой статье функция initTable(). В чём её отличие от предыдущей реализации. Во–первых, тут мы добавили переменную minesCount, которой сразу же присвоили значение 10. Кроме того, мы объявили переменную mines, которой присвоили результат функции fillMines с числом строк, столбцов и мин в качестве параметров. Подробнее о том, как устроена эта функция я расскажу ниже, скажу лишь что представляет собой её результат. Функция fillMines возвращает массив длины rowCount * colCount, причём для каждому элементу массива, равному единице соответствует мина, а иначе мины нет.
Что же такое массив? Это особый тип переменной, которая сама по себе ничего не хранит, но как бы предоставляет доступ к другим переменным внутри себя. Вариант классического массива — это как бы набор элементов, доступ к которым осуществляется по индексу. Например, Arr — это массив, тогда Arr[0] — это переменная, соответствующая нулевому элементу массива Arr. Ну и так далее.
Каким образом наш массив mines будет соотноситься с нашей таблицей? Да всё очень просто. Для первой строки первого столбца, то есть элемента [0, 0] (будем нумеровать с нуля, в программировании так почти везде) будет соответствовать нулевой элемент массива [0]. Для первой строки второго столбца [0, 1] — первый элемент массива [1]. Для [0, 9] — [9]. Для первой строки закончились столбцы — не беда, теперь возьмём вторую строку первый столбец [1, 0], этой ячейке будет соответствовать десятый элемент массива mines, то есть, в нашей терминологии, [10]. Так будем идти дальше, пока не дойдем до последней (десятой) строки и последнего (десятого) столбца [9, 9], им будет соответствовать элемент [99].
Всё это на самом деле можно записать куда короче: [i, j] соответствует [i * colCount + j]. Можете проверить на листе бумаги.
Хорошо, мы получили наш массив с бомбами. По сути это основное функциональное отличие от того, что мы делали в прошлой статье. Далее мы видим уже знакомый вложенный цикл, мы получаем переменную ячейки, а дальше, вместо того, чтобы положить туда строку «cell» с индексами ячейки в таблице, мы пишем сразу 4 строки.
if (mines[i * rowCount + j] == 1)
cell.innerHTML = '*'
else
cell.innerHTML = '.';
Тут мы снова сталкнёмся с новой конструкцией. Оператор if или условный оператор. Что это такое? Давайте опять попробуем перевести фразу на русский: «если (mines[i * rowCount + j] == 1), то выполнить cell.innerHTML = '*', а иначе выполнить cell.innerHTML = '.'". Другими словами, если выполняется условие после if (в JavaScript обязательно заключено в круглые скобки), выполняется блок (в нашем случае одна строка, так как нет фигурных скобок обрамляющих блок) сразу после оператора if, если же условие не выполняется (не обязательно, блока else может и не быть), выполняется блок сразу после оператора else. Если за блоком, идущем сразу после блока if нет оператора else, последующий код выполняется всегда, независимо от выполнения или невыполнения условия.
Что же значит выполнение условия, давайте внимательней разберём выражение «mines[i * rowCount + j] == 1». «mines[i * rowCount + j]» — это, как вы вероятно уже догадались переменная, которая соответствует текущей ячейке (строка i, столбец j) в нашем массиве бомб. Как вы помните, эта переменная равна 1, если бомба в соответствующей ячейке есть. Именно равенство переменной единице мы и проверяем. Оператор точного сравнения переменных в JavaScript — "==".
Давайте немного потренируемся составлять такие условия. (i > 2) — значение переменной i больше, чем 2. (i != 3) — значение переменной i не равно 3. (i == j) — значение переменной i равно значению переменной j.
Ну и чтобы формально закончить рассмотрение этого кусочка кода. Получается, что если у нас есть бомба в ячейке — мы делаем текст ячейки равным строке '*', если же бомбы нет — строке '.'.
Теперь перейдём к рассмотрению следующей большой функции в нашем скрипте - fillMines.
function fillMines(rowCount, colCount, minesCount)
{
var res = new Array(rowCount * colCount);
var mines = minesCount;
while (mines > 0)
{
var n = intRand(rowCount * colCount‑1);
if (res[n] != 1)
{
res[n] = 1;
mines--;
}
}
return res;
}
Что же происходит тут. Именно эта функция создаёт нам наш массив с бомбами.
Первой же строчкой создаётся пустой массив, длиной rowCount * colCount. В нём ещё ничего нет, далее мы должны будем его заполнить. Кроме того, мы заводим некую вспомогательную переменную mines, которой присваиваем начальное значение minesCount. Вероятно я её не совсем удачно назвал, будем считать, что она называется как–то вроде «количество бомб, которые ещё нужно распределить». Это куда лучше описывает её назначение.
Далее мы сталкиваемся с новым типом цикла. Это цикл while. Как работает этот цикл? Он выполняет свой блок кода (тело) до тех пор, пока выполняется условие в скобках сразу после слова while. То есть в нашем случае цикл будет выполняться пока ещё есть неразмещённые бомбы. Вообще говоря это довольно опасный цикл, так как его легко сделать бесконечным (в том числе и ошибочно). Например в моём случае функция не проверяет (хотя стоило бы), что бомб меньше чем ячеек в таблице, а ведь если это условие не выполняется, мы никогда не сможем разместить все бомбы так, чтобы в каждой ячейке было не больше одной, а значит никогда не выйдем из этого цикла и наша программа зависнет.
Само тело цикла довольно простое, переменной n мы присваиваем результат функции intRand c параметром числа ячеек таблицы — 1 (максимальный индекс в нашем массиве бомб). Эта функция, как она работает будет ниже, возвращает случайное целое число от 0 до значения переданного в качестве параметра включительно.
Далее мы проверяем, есть–ли уже бомба в элементе с индексом n в массиве res. И если её нет, мы её туда добавляем (res[n] = 1) и уменьшаем на единицу количество бомб, которые надо добавить (mines--). Как только все бомбы будут распределены (mines станет равно 0), наш цикл закончится и мы вернём результат (return res). Из незнакомого тут может быть оператор декремента " — ". Он увеличивает значение переменной на единицу, то есть запись mines-- эквивалентна записи mines = mines‑1. И оператор return. Этот оператор возвращает переменную или выражение после себя в качестве результата текущей функции и выходит из неё. То есть если вы вызовете оператор return в середине функции, оставшаяся её часть выполняться уже не будет.
Вообще говоря, предложенный алгоритм имеет ряд изъянов. Как я уже говорил, возможно зацикливание (зависание), кроме того, неизвестно сколько времени потребуется для того, чтобы случайным образом выбрать ячейки для мин. Чисто теоретически, может 1000 раз подряд выпасть число 39, таким образом мы будем выполнять цикл более тысячи раз, а может сразу выпасть 10 разных чисел и мы будем выполнять цикл всего 10 раз. И хотя вероятность описанной мной ситуации ничтожно мала, она всё–таки существует и тем больше, чем большее количество мин нам нужно расставить. Грубо говоря, мой алгоритм, наверняка будет не плохо работать при количестве мин значительно меньшем, чем количество ячеек, но его не стоит применять, когда их почти столько же.
Наконец мы подошли к последней функции, о которой следует рассказать в этой статье. Она совсем небольшая, всего в одну строчку, итак, функция intRand.
function intRand(maxVal)
{
return Math.round((maxVal + 1) * Math.random() — 0.5);
}
Как я уже говорил, она возвращает случайное целое число от 0 до значения параметра maxVal включительно. То есть intRand(2) может вернуть или 0, или 1, или 2, причём каждый вероятность возврата каждого из этих вариантов равна.

