|
@@ -0,0 +1,170 @@
|
|
|
+// Задание на черный пояс: Электронная гадалка
|
|
|
+
|
|
|
+// Пользователь вводит 0 или 1. Гадалка пытается угадать, что введет пользователь (естественно перед его вводом),
|
|
|
+// но не показывает пользователю, чтобы пользователь не выбрал противоположный вариант,
|
|
|
+// а выводит предполагаемый вариант в консоль, скрытую от пользователя.
|
|
|
+// Как это работает?
|
|
|
+// Гадалка хранит историю ввода(4 последних числа) пользователя в массиве history.
|
|
|
+// Каждое следующее число добавляется с помощью push в конец массива, при этом первое число из массива(самое старое)
|
|
|
+// удаляется с помощью shift.
|
|
|
+// Гадалка запоминает, что пользователь ввёл в предыдущий раз после такой истории.То есть, если пользователь
|
|
|
+// вводил 0, 1, 0, 1, 0, то логично предположить, что с историей 0, 1, 0, 1 следующим вариантом будет 0.
|
|
|
+// Для хранения используется 4х мерный массив, индексами которого является история:
|
|
|
+// predictArray[history[0]][history[1]][history[2]][history[3]] равно тому, что пользователь ввёл после истории в предыдущий раз.
|
|
|
+// Алгоритм:
|
|
|
+// Изначально predictArray содержит, например, -1, или иные значения, которые отличаются от пользовательского ввода.
|
|
|
+// История пусть состоит из единиц: history = [1, 1, 1, 1];, Т.е.считается что пользователь нажимал 1 четыре ряда подряд.
|
|
|
+// Пока мы не можем предсказать, так как в массиве еще не сохранилось то, что вводил пользователь, мы используем Math.random
|
|
|
+// в качестве предсказания, и записываем ввод пользователя в массив predictArray, добавляя новые значения в history,
|
|
|
+// и сдвигая его.Т.е.если пользователь ввел 0, то:
|
|
|
+// predictArray[1][1][1][1] = 0; //1,1,1,1 - история, 0 - новое значение
|
|
|
+// history = [1, 1, 1, 0] //удаляем старую единицу из истории и добавляем введенный только что 0
|
|
|
+// Для предсказания следующего достаем значение массива predictArray[1, 1, 1, 0], а после ввода опять записываем туда то,
|
|
|
+// что ввёл пользователь(пусть 1):
|
|
|
+// predictArray[1][1][1][0] = 1; //1,1,1,0 - история, 1 - новое значение
|
|
|
+// history = [1, 1, 0, 1] //удаляем старую единицу из истории и добавляем введенный только что 1
|
|
|
+// Таким образом в predictArray накапливаются знания о том, что вводит пользователь после определенной истории чисел.
|
|
|
+
|
|
|
+const task17block = document.createElement('div');
|
|
|
+task17block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px";
|
|
|
+const task17title = document.createElement('h2');
|
|
|
+task17title.innerText = 'Task-17 Digital Vanga';
|
|
|
+const task17comment = document.createElement('p');
|
|
|
+task17comment.innerText = 'Возможно сохранение истории в n-мерный массив';
|
|
|
+const playVangaBtn = document.createElement('button');
|
|
|
+playVangaBtn.innerText = 'Play';
|
|
|
+playVangaBtn.style = 'margin-bottom:17px';
|
|
|
+root.appendChild(task17block);
|
|
|
+task17block.appendChild(task17title);
|
|
|
+task17block.appendChild(task17comment);
|
|
|
+task17block.appendChild(playVangaBtn);
|
|
|
+playVangaBtn.onclick = () => {
|
|
|
+ let history = [];
|
|
|
+ let predictArray = [-1, -1];
|
|
|
+ let VangaNumber = null;
|
|
|
+ let step = null;
|
|
|
+ let userNumber = null;
|
|
|
+ const historyDeep=+prompt('Введите кол-во элементов, записываемых в историю')
|
|
|
+ // const historyDeep = 4;
|
|
|
+
|
|
|
+// Формирование начального многомерного массива predictArray произвольной глубины вложенности
|
|
|
+ function predictArrayFirstFilling(predictArray, historyDeep) {
|
|
|
+ let prePredictArray = [];
|
|
|
+ if (historyDeep ===0) {
|
|
|
+ return predictArray;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ prePredictArray = JSON.parse(JSON.stringify(predictArray));
|
|
|
+ //Деструктуризация и слайс не дали глубокого копирования, потому использовала JSON.parse(JSON.stringify)
|
|
|
+ // prePredictArray = [...predictArray];
|
|
|
+ // prePredictArray = predictArray.slice(0);
|
|
|
+ for (let j = 0; j < 2; j++) {
|
|
|
+ // predictArray[j] = prePredictArray.slice(0);
|
|
|
+ // predictArray[j] = [...prePredictArray];
|
|
|
+ predictArray[j] = JSON.parse(JSON.stringify(prePredictArray));
|
|
|
+ }
|
|
|
+ return predictArrayFirstFilling (predictArray, historyDeep - 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ predictArrayFirstFilling(predictArray, historyDeep-1);
|
|
|
+
|
|
|
+// для постоянной глубины истории =4
|
|
|
+ // for (let i = 0; i < 2; i++) {
|
|
|
+ // predictArray[i] = [];
|
|
|
+ // for (let j = 0; j < 2; j++) {
|
|
|
+ // predictArray[i][j] = [];
|
|
|
+ // for (let k = 0; k < 2; k++) {
|
|
|
+ // predictArray[i][j][k] = [];
|
|
|
+ // for (let l = 0; l < 2; l++) {
|
|
|
+ // predictArray[i][j][k][l] = -1;
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+
|
|
|
+// Формирование 1-го массива history
|
|
|
+ for (step = 0; step < historyDeep; step++) {
|
|
|
+ VangaNumber = (Math.random() > 0.5) ? 1 : 0;
|
|
|
+ console.log(`Гадалка задумала: ${VangaNumber}`);
|
|
|
+ userNumber = prompt('Введите одно из чисел: 0 или 1');
|
|
|
+
|
|
|
+ if (!(userNumber === null)) {
|
|
|
+ if (!(userNumber === "")) {
|
|
|
+ if (userNumber == 1 || userNumber == 0) {
|
|
|
+ history[step] = userNumber;
|
|
|
+ VangaNumber == userNumber ? alert(`Гадалка угадала, что ты загадал ${userNumber} `) : alert('Гадалка не угадала твое число')
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ alert("Ошибка ввода. Нужно ввести число 0 или 1");
|
|
|
+ step--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ alert("Ошибка ввода. Нужно ввести число 0 или 1");
|
|
|
+ step--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else break;
|
|
|
+ }
|
|
|
+ console.log(`history=[${ history }]`);
|
|
|
+ // Формирование 2-го и более массивов history и внесение статистики в predictArray
|
|
|
+ while (!(userNumber === null)) {
|
|
|
+ //Проверка наличия записи в predictArray
|
|
|
+ let predictArrayElement = predictArray;
|
|
|
+ let prePredictArrayElement = [];
|
|
|
+ for (let i = 0; i < historyDeep; i++) {
|
|
|
+ prePredictArrayElement = predictArrayElement;
|
|
|
+ if (i < historyDeep - 1) {
|
|
|
+ predictArrayElement = [...prePredictArrayElement[history[i]]];
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ predictArrayElement = predictArrayElement[history[i]];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ //Выбор гадалки
|
|
|
+ if (predictArrayElement == 0 || predictArrayElement == 1) {
|
|
|
+ VangaNumber = predictArrayElement;
|
|
|
+ console.log(`Гадалка задумала: ${VangaNumber}`);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ VangaNumber = (Math.random() > 0.5) ? 1 : 0;
|
|
|
+ console.log(`Гадалка задумала: ${VangaNumber}`);
|
|
|
+ };
|
|
|
+
|
|
|
+ userNumber = prompt('Введите одно из чисел: 0 или 1')
|
|
|
+ if (!(userNumber === null)) {
|
|
|
+ if (!(userNumber === "")) {
|
|
|
+ if (userNumber == 1 || userNumber == 0) {
|
|
|
+ VangaNumber == userNumber ? alert(`Гадалка угадала, что ты загадал ${userNumber} `) : alert('Гадалка не угадала твое число');
|
|
|
+
|
|
|
+ //Перезапись нужного элемента массива predictArray
|
|
|
+ let predictArrayElement = 'predictArray';
|
|
|
+ for (let i = 0; i < historyDeep; i++) {
|
|
|
+ predictArrayElement +=`[${[history[i]]}]`;
|
|
|
+ }
|
|
|
+ predictArrayElement += `=${userNumber}`;
|
|
|
+ eval(predictArrayElement);
|
|
|
+
|
|
|
+ history.push(userNumber);
|
|
|
+ history.splice(0, 1);
|
|
|
+ console.log(`history=[${history}]`);
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ alert("Ошибка ввода. Нужно ввести число 0 или 1");
|
|
|
+ step--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ alert("Ошибка ввода. Нужно ввести число 0 или 1");
|
|
|
+ step--;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else break;
|
|
|
+ }
|
|
|
+ console.log(`predictArray=`);
|
|
|
+ console.log(predictArray);
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|