Добавить весь код маджонга
This commit is contained in:
480
код/2019-09-10.js
Normal file
480
код/2019-09-10.js
Normal file
@@ -0,0 +1,480 @@
|
||||
var ресурсы = [
|
||||
[БАЗА + "модели/фишка/2019-09-08.osgt", "mod"],
|
||||
[БАЗА + "текстуры/заглушка.png", "tex.stub"],
|
||||
[БАЗА + "шейдеры/освещение-изображение.vert", "ver"],
|
||||
[БАЗА + "шейдеры/освещение-изображение.frag", "fra"],
|
||||
[БАЗА + "раскладки/X_shaped.layout", "lay"],
|
||||
|
||||
[БАЗА + "классы/Раскладка/2019-08-16.js", "Layout"],
|
||||
[БАЗА + "классы/Фишка/2019-09-07.js", "Tile"],
|
||||
[БАЗА + "темыФишек/заглушка/2019-09-08.js", "theme.stub"],
|
||||
];
|
||||
|
||||
мж.начали = new Уведомитель();
|
||||
мж.начать = function()
|
||||
{
|
||||
муром.камера.позиция = [0, -70, 0];
|
||||
муром.камера.вращение = [90, 0, 0];
|
||||
мж.сцена = муром.узлы.создатьСферу("sce", 0);
|
||||
мж.сцена.вращение = [60, 0, 0];
|
||||
var мир = муром.узлы.узел("mir");
|
||||
мир.добавитьДитя(мж.сцена);
|
||||
|
||||
мж.начали.уведомить();
|
||||
};
|
||||
|
||||
мж.задатьНейтральныйМатериал = function()
|
||||
{
|
||||
var мат = муром.материалы.создатьМатериал("N");
|
||||
var изо = муром.ресурсы.ресурс("tex.stub");
|
||||
мат.задатьТекстуру("image", изо);
|
||||
var вер = муром.ресурсы.ресурс("ver").содержимое;
|
||||
var фра = муром.ресурсы.ресурс("fra").содержимое;
|
||||
мат.задатьШейдеры(вер, фра);
|
||||
мж.сцена.задатьМатериал(мат);
|
||||
};
|
||||
|
||||
мж.разобратьРаскладку = function()
|
||||
{
|
||||
eval(муром.ресурсы.ресурс("Layout").содержимое);
|
||||
|
||||
var содержимое = муром.ресурсы.ресурс("lay").содержимое;
|
||||
мж.раскладка = new Раскладка();
|
||||
мж.раскладка.разобрать(содержимое);
|
||||
};
|
||||
|
||||
мж.фишки = [];
|
||||
мж.создатьФишки = function()
|
||||
{
|
||||
eval(муром.ресурсы.ресурс("Tile").содержимое);
|
||||
|
||||
for (var номер in мж.раскладка.позиции)
|
||||
{
|
||||
var ф = new Фишка();
|
||||
ф.позиция = мж.раскладка.позиции[номер];
|
||||
мж.фишки.push(ф);
|
||||
}
|
||||
};
|
||||
|
||||
мж.размерФишки = {
|
||||
"ширина": 2.0,
|
||||
"высота": 3.0,
|
||||
"глубина": 1.0,
|
||||
};
|
||||
мж.создатьУзлыФишек = function()
|
||||
{
|
||||
const шагФишки = 2.0;
|
||||
const коэффициенты = {
|
||||
"x": мж.размерФишки.ширина / шагФишки,
|
||||
"y": -мж.размерФишки.высота / шагФишки,
|
||||
"z": мж.размерФишки.глубина,
|
||||
};
|
||||
var мод = муром.ресурсы.ресурс("mod");
|
||||
|
||||
for (var номер in мж.фишки)
|
||||
{
|
||||
var имя = номер.toString();
|
||||
var узел = муром.узлы.создатьУзел(имя, мод);
|
||||
мж.сцена.добавитьДитя(узел);
|
||||
|
||||
var ф = мж.фишки[номер];
|
||||
var п = ф.позиция;
|
||||
узел.позиция = [
|
||||
п[2] * коэффициенты.x,
|
||||
п[1] * коэффициенты.y,
|
||||
п[0] * коэффициенты.z,
|
||||
];
|
||||
ф.узел = узел;
|
||||
}
|
||||
};
|
||||
|
||||
мж.центрироватьСцену = function()
|
||||
{
|
||||
var границы = {
|
||||
"лево": 1000,
|
||||
"право": -1000,
|
||||
"верх": -1000,
|
||||
"низ": 1000,
|
||||
};
|
||||
for (var номер in мж.фишки)
|
||||
{
|
||||
const ф = мж.фишки[номер];
|
||||
const x = ф.узел.позиция[0];
|
||||
const y = ф.узел.позиция[1];
|
||||
if (x < границы.лево)
|
||||
{
|
||||
границы.лево = x;
|
||||
}
|
||||
if (x > границы.право)
|
||||
{
|
||||
границы.право = x;
|
||||
}
|
||||
if (y < границы.низ)
|
||||
{
|
||||
границы.низ = y;
|
||||
}
|
||||
if (y > границы.верх)
|
||||
{
|
||||
границы.верх = y;
|
||||
}
|
||||
}
|
||||
|
||||
const ширина = границы.право - границы.лево + мж.размерФишки.ширина;
|
||||
const высота = границы.верх - границы.низ + мж.размерФишки.высота;
|
||||
мж.сцена.позиция = [-ширина / 2.0, 0, высота / 2.0];
|
||||
};
|
||||
|
||||
// http://www.rubl.com/rules/mahjong-solitaire-rules.html
|
||||
мж.задатьФишкамГруппыПоследовательно = function()
|
||||
{
|
||||
var группы = [];
|
||||
// Генерируем группы.
|
||||
const группВсего = 42;
|
||||
const группПо4Дубля = 34;
|
||||
for (var г = 0; г < группВсего; ++г)
|
||||
{
|
||||
const четыреДубля = (г < группПо4Дубля);
|
||||
const колвоДублей = четыреДубля ? 4 : 1;
|
||||
for (var д = 0; д < колвоДублей; ++д)
|
||||
{
|
||||
группы.push(г);
|
||||
}
|
||||
}
|
||||
// Задаём.
|
||||
for (var номер in мж.фишки)
|
||||
{
|
||||
var ф = мж.фишки[номер];
|
||||
ф.группа = Number(группы[номер]);
|
||||
}
|
||||
};
|
||||
|
||||
мж.применитьТемуФишек = function()
|
||||
{
|
||||
eval(муром.ресурсы.ресурс("theme.stub").contents);
|
||||
const R = RR();
|
||||
|
||||
// Создать текстуры.
|
||||
var обозначения = [];
|
||||
var текстуры = [];
|
||||
for (var номер in R)
|
||||
{
|
||||
var обозначение = R[номер][0];
|
||||
обозначения.push(обозначение);
|
||||
var имя = "tile.tex/" + обозначение;
|
||||
var содержимое = R[номер][1];
|
||||
var текстура = муром.ресурсы.создатьРесурс(имя, содержимое);
|
||||
текстуры.push(текстура);
|
||||
}
|
||||
|
||||
// Создать материалы.
|
||||
var нейтраль = [];
|
||||
var выбор = [];
|
||||
var вер = муром.ресурсы.ресурс("ver").содержимое;
|
||||
var фра = муром.ресурсы.ресурс("fra").содержимое;
|
||||
// Нейтраль.
|
||||
for (var номер = 0; номер < 42; ++номер)
|
||||
{
|
||||
var имя = "tile.mat/" + обозначения[номер];
|
||||
var изо = текстуры[номер];
|
||||
var мат = муром.материалы.создатьМатериал(имя);
|
||||
мат.задатьТекстуру("image", изо);
|
||||
мат.задатьШейдеры(вер, фра);
|
||||
нейтраль.push(мат);
|
||||
}
|
||||
// Выбор.
|
||||
for (var номер = 42; номер < 83; ++номер)
|
||||
{
|
||||
var имя = "tile.mat/" + обозначения[номер];
|
||||
var изо = текстуры[номер];
|
||||
var мат = муром.материалы.создатьМатериал(имя);
|
||||
мат.задатьТекстуру("image", изо);
|
||||
мат.задатьШейдеры(вер, фра);
|
||||
выбор.push(мат);
|
||||
}
|
||||
|
||||
// Применить тему.
|
||||
for (var номер in мж.фишки)
|
||||
{
|
||||
var ф = мж.фишки[номер];
|
||||
ф.нейтраль = нейтраль[ф.группа];
|
||||
ф.выбор = выбор[ф.группа];
|
||||
|
||||
ф.показатьНейтраль();
|
||||
}
|
||||
};
|
||||
|
||||
мж.маскаВыбора = 0x2;
|
||||
мж.сделатьФишкиВыбираемыми = function()
|
||||
{
|
||||
for (var номер in мж.фишки)
|
||||
{
|
||||
var ф = мж.фишки[номер];
|
||||
ф.узел.задатьМаску(мж.маскаВыбора);
|
||||
}
|
||||
}
|
||||
|
||||
мж.индексПозиции = function(п)
|
||||
{
|
||||
return п[0] * 1000000 + п[1] * 1000 + п[2];
|
||||
};
|
||||
|
||||
мж.индексПозиций = {};
|
||||
мж.проиндексироватьПозиции = function()
|
||||
{
|
||||
for (var номер in мж.фишки)
|
||||
{
|
||||
var ф = мж.фишки[номер];
|
||||
var и = мж.индексПозиции(ф.позиция);
|
||||
мж.индексПозиций[и] = true;
|
||||
}
|
||||
};
|
||||
|
||||
мж.естьСоседи = function(позиция, смещениеПоля, смещениеСтолбца)
|
||||
{
|
||||
for (var смещениеРяда = -1; смещениеРяда <= 1; ++смещениеРяда)
|
||||
{
|
||||
var сосед = [
|
||||
Number(позиция[0]) + смещениеПоля,
|
||||
Number(позиция[1]) + смещениеРяда,
|
||||
Number(позиция[2]) + смещениеСтолбца,
|
||||
];
|
||||
var и = мж.индексПозиции(сосед);
|
||||
if (и in мж.индексПозиций)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Соседей нет.
|
||||
return false;
|
||||
};
|
||||
|
||||
мж.можноВыбратьФишку = function(ф)
|
||||
{
|
||||
// Проверяем наличие фишек с левой и правой сторон одновременно.
|
||||
var слева = this.естьСоседи(ф.позиция, 0, -2);
|
||||
var справа = this.естьСоседи(ф.позиция, 0, 2);
|
||||
if (слева && справа)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Проверяем наличие фишек непосредственно сверху.
|
||||
for (var смещение = -1; смещение <= 1; ++смещение)
|
||||
{
|
||||
if (this.естьСоседи(ф.позиция, 1, смещение))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Фишка не заблокирована.
|
||||
return true;
|
||||
};
|
||||
|
||||
мж.номерВыбраннойФишки = null;
|
||||
мж.выбраннаяФишка = null;
|
||||
мж.выбранаФишка = new Уведомитель();
|
||||
мж.выбратьФишку = function()
|
||||
{
|
||||
// Определить щелчок.
|
||||
if (муром.мышь.нажатыеКнопки.length == 1)
|
||||
{
|
||||
var узел =
|
||||
муром.камера.узелВПозиции(
|
||||
муром.мышь.позиция,
|
||||
мж.маскаВыбора
|
||||
);
|
||||
if (узел)
|
||||
{
|
||||
var номер = Number(узел.имя);
|
||||
var ф = мж.фишки[номер];
|
||||
if (мж.можноВыбратьФишку(ф))
|
||||
{
|
||||
мж.номерВыбраннойФишки = номер;
|
||||
мж.выбраннаяФишка = ф;
|
||||
мж.выбранаФишка.уведомить();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
мж.отладитьВыборФишки = function()
|
||||
{
|
||||
мж.выбранаФишка.подписать(function(){
|
||||
console.log(
|
||||
"Выбор. Номер: '" +
|
||||
мж.номерВыбраннойФишки +
|
||||
"' Группа: '" +
|
||||
мж.выбраннаяФишка.группа +
|
||||
"'"
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
мж.показатьВыбраннуюФишку = function()
|
||||
{
|
||||
мж.выбраннаяФишка.показатьВыбор();
|
||||
};
|
||||
|
||||
мж.выбранныеФишки = [];
|
||||
мж.фишкиРазличаются = new Уведомитель();
|
||||
мж.фишкиСовпадают = new Уведомитель();
|
||||
мж.фишкиСравнили = new Уведомитель();
|
||||
мж.сравнитьВыбранныеФишки = function()
|
||||
{
|
||||
// Собираем.
|
||||
мж.выбранныеФишки.push(мж.выбраннаяФишка);
|
||||
// Удостоверяемся в наличии пары фишек.
|
||||
if (мж.выбранныеФишки.length != 2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var ф1 = мж.выбранныеФишки[0];
|
||||
var ф2 = мж.выбранныеФишки[1];
|
||||
// Убираем дубликат при двойном выборе одной фишки.
|
||||
if (ф1.имя == ф2.имя)
|
||||
{
|
||||
мж.выбранныеФишки.shift();
|
||||
return;
|
||||
}
|
||||
// Сравниваем.
|
||||
if (ф1.группа == ф2.группа)
|
||||
{
|
||||
мж.фишкиСовпадают.уведомить();
|
||||
}
|
||||
else
|
||||
{
|
||||
мж.фишкиРазличаются.уведомить();
|
||||
}
|
||||
мж.фишкиСравнили.уведомить();
|
||||
};
|
||||
|
||||
мж.отладитьСравнениеФишек = function()
|
||||
{
|
||||
мж.фишкиСовпадают.подписать(function(){
|
||||
console.log("Фишки совпадают");
|
||||
});
|
||||
мж.фишкиРазличаются.подписать(function(){
|
||||
console.log("Фишки различаются");
|
||||
});
|
||||
};
|
||||
|
||||
мж.скрытьСовпадающиеФишки = function()
|
||||
{
|
||||
мж.выбранныеФишки[0].скрыть();
|
||||
мж.выбранныеФишки[1].скрыть();
|
||||
};
|
||||
|
||||
мж.убратьСовпадающиеФишки = function()
|
||||
{
|
||||
var ф1 = мж.выбранныеФишки[0];
|
||||
var ф2 = мж.выбранныеФишки[1];
|
||||
var и1 = мж.индексПозиции(ф1.позиция);
|
||||
var и2 = мж.индексПозиции(ф2.позиция);
|
||||
delete мж.индексПозиций[и1];
|
||||
delete мж.индексПозиций[и2];
|
||||
};
|
||||
|
||||
мж.очиститьОтображениеВыбора = function()
|
||||
{
|
||||
мж.выбранныеФишки[0].показатьНейтраль();
|
||||
мж.выбранныеФишки[1].показатьНейтраль();
|
||||
};
|
||||
|
||||
мж.очиститьВыбор = function()
|
||||
{
|
||||
мж.номерВыбраннойФишки = 0;
|
||||
мж.выбраннаяФишка = null;
|
||||
мж.выбранныеФишки = [];
|
||||
};
|
||||
|
||||
мж.оставшиесяФишки = [];
|
||||
мж.задатьОставшиесяФишки = function()
|
||||
{
|
||||
мж.оставшиесяФишки = мж.фишки.slice();
|
||||
};
|
||||
|
||||
мж.обновилиОставшиесяФишки = new Уведомитель();
|
||||
мж.обновитьОставшиесяФишки = function()
|
||||
{
|
||||
var и1 = мж.оставшиесяФишки.indexOf(мж.выбранныеФишки[0]);
|
||||
мж.оставшиесяФишки.splice(и1, 1);
|
||||
var и2 = мж.оставшиесяФишки.indexOf(мж.выбранныеФишки[1]);
|
||||
мж.оставшиесяФишки.splice(и2, 1);
|
||||
|
||||
мж.обновилиОставшиесяФишки.уведомить();
|
||||
};
|
||||
|
||||
мж.доступныеДляВыбораФишки = function()
|
||||
{
|
||||
var фишки = [];
|
||||
for (var номер in мж.оставшиесяФишки)
|
||||
{
|
||||
var ф = мж.оставшиесяФишки[номер];
|
||||
if (мж.можноВыбратьФишку(ф))
|
||||
{
|
||||
фишки.push(ф);
|
||||
}
|
||||
}
|
||||
|
||||
return фишки;
|
||||
};
|
||||
|
||||
мж.естьХод = function()
|
||||
{
|
||||
var фишки = мж.доступныеДляВыбораФишки();
|
||||
for (var н1 in фишки)
|
||||
{
|
||||
for (var н2 in фишки)
|
||||
{
|
||||
var ф1 = фишки[н1];
|
||||
var ф2 = фишки[н2];
|
||||
if (
|
||||
(ф1.имя != ф2.имя) &&
|
||||
(ф1.группа == ф2.группа)
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
мж.победа = new Уведомитель();
|
||||
мж.поражение = new Уведомитель();
|
||||
мж.проверитьЗавершение = function()
|
||||
{
|
||||
var кончилисьФишки = (мж.оставшиесяФишки.length == 0);
|
||||
if (кончилисьФишки)
|
||||
{
|
||||
мж.победа.уведомить();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!мж.естьХод())
|
||||
{
|
||||
мж.поражение.уведомить();
|
||||
}
|
||||
};
|
||||
|
||||
мж.отладитьЗавершение = function()
|
||||
{
|
||||
мж.победа.подписать(function(){
|
||||
console.log("Игра завершена. ПОБЕДА!");
|
||||
});
|
||||
мж.поражение.подписать(function(){
|
||||
console.log("Игра завершена. ПОРАЖЕНИЕ :(");
|
||||
});
|
||||
};
|
||||
|
||||
мж.задатьОтображениеЗавершения = function()
|
||||
{
|
||||
мж.победа.подписать(function(){
|
||||
муром.камера.цветОчистки = [0.2, 0.5, 0.2];
|
||||
});
|
||||
мж.поражение.подписать(function(){
|
||||
муром.камера.цветОчистки = [0.5, 0.2, 0.2];
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user