task-17.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Задание на черный пояс: Электронная гадалка
  2. // Пользователь вводит 0 или 1. Гадалка пытается угадать, что введет пользователь (естественно перед его вводом),
  3. // но не показывает пользователю, чтобы пользователь не выбрал противоположный вариант,
  4. // а выводит предполагаемый вариант в консоль, скрытую от пользователя.
  5. // Как это работает?
  6. // Гадалка хранит историю ввода(4 последних числа) пользователя в массиве history.
  7. // Каждое следующее число добавляется с помощью push в конец массива, при этом первое число из массива(самое старое)
  8. // удаляется с помощью shift.
  9. // Гадалка запоминает, что пользователь ввёл в предыдущий раз после такой истории.То есть, если пользователь
  10. // вводил 0, 1, 0, 1, 0, то логично предположить, что с историей 0, 1, 0, 1 следующим вариантом будет 0.
  11. // Для хранения используется 4х мерный массив, индексами которого является история:
  12. // predictArray[history[0]][history[1]][history[2]][history[3]] равно тому, что пользователь ввёл после истории в предыдущий раз.
  13. // Алгоритм:
  14. // Изначально predictArray содержит, например, -1, или иные значения, которые отличаются от пользовательского ввода.
  15. // История пусть состоит из единиц: history = [1, 1, 1, 1];, Т.е.считается что пользователь нажимал 1 четыре ряда подряд.
  16. // Пока мы не можем предсказать, так как в массиве еще не сохранилось то, что вводил пользователь, мы используем Math.random
  17. // в качестве предсказания, и записываем ввод пользователя в массив predictArray, добавляя новые значения в history,
  18. // и сдвигая его.Т.е.если пользователь ввел 0, то:
  19. // predictArray[1][1][1][1] = 0; //1,1,1,1 - история, 0 - новое значение
  20. // history = [1, 1, 1, 0] //удаляем старую единицу из истории и добавляем введенный только что 0
  21. // Для предсказания следующего достаем значение массива predictArray[1, 1, 1, 0], а после ввода опять записываем туда то,
  22. // что ввёл пользователь(пусть 1):
  23. // predictArray[1][1][1][0] = 1; //1,1,1,0 - история, 1 - новое значение
  24. // history = [1, 1, 0, 1] //удаляем старую единицу из истории и добавляем введенный только что 1
  25. // Таким образом в predictArray накапливаются знания о том, что вводит пользователь после определенной истории чисел.
  26. const task17block = document.createElement('div');
  27. task17block.style = "border: 2px solid green; border-radius:5px; margin-bottom:10px; padding:10px";
  28. const task17title = document.createElement('h2');
  29. task17title.innerText = 'Task-17 Digital Vanga';
  30. const task17comment = document.createElement('p');
  31. task17comment.innerText = 'Возможно сохранение истории в n-мерный массив';
  32. const playVangaBtn = document.createElement('button');
  33. playVangaBtn.innerText = 'Play';
  34. playVangaBtn.style = 'margin-bottom:17px';
  35. root.appendChild(task17block);
  36. task17block.appendChild(task17title);
  37. task17block.appendChild(task17comment);
  38. task17block.appendChild(playVangaBtn);
  39. playVangaBtn.onclick = () => {
  40. let history = [];
  41. let predictArray = [-1, -1];
  42. let VangaNumber = null;
  43. let step = null;
  44. let userNumber = null;
  45. const historyDeep=+prompt('Введите кол-во элементов, записываемых в историю')
  46. // const historyDeep = 4;
  47. // Формирование начального многомерного массива predictArray произвольной глубины вложенности
  48. function predictArrayFirstFilling(predictArray, historyDeep) {
  49. let prePredictArray = [];
  50. if (historyDeep ===0) {
  51. return predictArray;
  52. } else {
  53. prePredictArray = JSON.parse(JSON.stringify(predictArray));
  54. //Деструктуризация и слайс не дали глубокого копирования, потому использовала JSON.parse(JSON.stringify)
  55. // prePredictArray = [...predictArray];
  56. // prePredictArray = predictArray.slice(0);
  57. for (let j = 0; j < 2; j++) {
  58. // predictArray[j] = prePredictArray.slice(0);
  59. // predictArray[j] = [...prePredictArray];
  60. predictArray[j] = JSON.parse(JSON.stringify(prePredictArray));
  61. }
  62. return predictArrayFirstFilling (predictArray, historyDeep - 1);
  63. }
  64. }
  65. predictArrayFirstFilling(predictArray, historyDeep-1);
  66. // для постоянной глубины истории =4
  67. // for (let i = 0; i < 2; i++) {
  68. // predictArray[i] = [];
  69. // for (let j = 0; j < 2; j++) {
  70. // predictArray[i][j] = [];
  71. // for (let k = 0; k < 2; k++) {
  72. // predictArray[i][j][k] = [];
  73. // for (let l = 0; l < 2; l++) {
  74. // predictArray[i][j][k][l] = -1;
  75. // }
  76. // }
  77. // }
  78. // }
  79. // Формирование 1-го массива history
  80. for (step = 0; step < historyDeep; step++) {
  81. VangaNumber = (Math.random() > 0.5) ? 1 : 0;
  82. console.log(`Гадалка задумала: ${VangaNumber}`);
  83. userNumber = prompt('Введите одно из чисел: 0 или 1');
  84. if (!(userNumber === null)) {
  85. if (!(userNumber === "")) {
  86. if (userNumber == 1 || userNumber == 0) {
  87. history[step] = userNumber;
  88. VangaNumber == userNumber ? alert(`Гадалка угадала, что ты загадал ${userNumber} `) : alert('Гадалка не угадала твое число')
  89. }
  90. else {
  91. alert("Ошибка ввода. Нужно ввести число 0 или 1");
  92. step--;
  93. }
  94. }
  95. else {
  96. alert("Ошибка ввода. Нужно ввести число 0 или 1");
  97. step--;
  98. }
  99. }
  100. else break;
  101. }
  102. console.log(`history=[${ history }]`);
  103. // Формирование 2-го и более массивов history и внесение статистики в predictArray
  104. while (!(userNumber === null)) {
  105. //Проверка наличия записи в predictArray
  106. let predictArrayElement = predictArray;
  107. let prePredictArrayElement = [];
  108. for (let i = 0; i < historyDeep; i++) {
  109. prePredictArrayElement = predictArrayElement;
  110. if (i < historyDeep - 1) {
  111. predictArrayElement = [...prePredictArrayElement[history[i]]];
  112. }
  113. else {
  114. predictArrayElement = predictArrayElement[history[i]];
  115. }
  116. }
  117. //Выбор гадалки
  118. if (predictArrayElement == 0 || predictArrayElement == 1) {
  119. VangaNumber = predictArrayElement;
  120. console.log(`Гадалка задумала: ${VangaNumber}`);
  121. }
  122. else {
  123. VangaNumber = (Math.random() > 0.5) ? 1 : 0;
  124. console.log(`Гадалка задумала: ${VangaNumber}`);
  125. };
  126. userNumber = prompt('Введите одно из чисел: 0 или 1')
  127. if (!(userNumber === null)) {
  128. if (!(userNumber === "")) {
  129. if (userNumber == 1 || userNumber == 0) {
  130. VangaNumber == userNumber ? alert(`Гадалка угадала, что ты загадал ${userNumber} `) : alert('Гадалка не угадала твое число');
  131. //Перезапись нужного элемента массива predictArray
  132. let predictArrayElement = 'predictArray';
  133. for (let i = 0; i < historyDeep; i++) {
  134. predictArrayElement +=`[${[history[i]]}]`;
  135. }
  136. predictArrayElement += `=${userNumber}`;
  137. eval(predictArrayElement);
  138. history.push(userNumber);
  139. history.splice(0, 1);
  140. console.log(`history=[${history}]`);
  141. }
  142. else {
  143. alert("Ошибка ввода. Нужно ввести число 0 или 1");
  144. step--;
  145. }
  146. }
  147. else {
  148. alert("Ошибка ввода. Нужно ввести число 0 или 1");
  149. step--;
  150. }
  151. }
  152. else break;
  153. }
  154. console.log(`predictArray=`);
  155. console.log(predictArray);
  156. }