Javascript: игра 24
Написал за часок с утра и похмелья эту игру, отбывая одно субботнее мероприятие. В принципе, она известна как "24", хотя в "Вики" не нашёл (в английской какой-то вариант с факториалами имеется).
Мы обойдёмся без факториалов, разрешив только 4 арифметических действия и круглые скобки. Компьютер задумывает 4 натуральных числа, а вы расставляете знаки и круглые скобки так, чтобы в результате решения примера получилось значение 24. Пример приведён при входе в игру.
Мне лично кажется, что это интереснее "пятнашек" да и всяких степеней двойки тоже.
В IE8 работать точно не будет, забыл я его особенности :)
Да, и я не знаю, что там делают по нажатию Enter все браузеры. Жалеем стариков, пользуемся мышкой :) Если добавить свистелок-перделок, двигалок, лупоглазок, из этой моей часовой работы можно сделать модную шнягу. А я лично хочу в горизонтальное положение, ту ж ночь не спал, обнаружив подозрительное щёлканье на стойке с "винтами" и сливая гигабайты в "секретное" хранилище :( У меня нет бабла на Raid 5 и кластера нет дома :(
В работе и исходник - ниже.
<script> var cnt=0; var numbers; var help = '<font size="2">'+"\n"+ 'Введите выражение с этими числами, результатом которого будет <font color="red">24</font>'+"\n"+ '<br>Разрешены только операции *, /, +, - и круглые скобки ()'+"\n"+ '<br>Числа можно менять местами как угодно, например:'+"\n"+ '<br>Числа <font color="red">1 8 4 1</font>'+"\n"+ '<br>Решение <font color="red">(8-1-1)*4</font>'+"\n"+ '</font>'; function eval24(numbers, input) { //оценка и проверка правильности решения var invalidChars = /[^\d\+\*\/\s-\(\)]/; var validNums = function(str) { var mnums = numbers.slice(); mnums.sort(); return str.replace(/[^\d\s]/g, " ") .trim() .split(/\s+/) .map(function(n) { return parseInt(n, 10); }) .sort() .every(function(v, i) { return v === mnums[i]; }); }; var validEval = function(input) { try { return eval(input); } catch (e) { return {error: e.toString()}; } }; if (input.trim() === "") return "Нужно что-нибудь ввести :)"; if (input.match(invalidChars)) return "Найдены недопустимые символы во вводе; разрешены только + - * / ( ) и числа"; if (!validNums(input)) return "Не использованы нужные числа, попробуйте ещё раз"; var calc = validEval(input); if (typeof(calc) !== 'number') return "Не удалось вычислить выражение, попробуйте ещё раз"; if (calc !== 24) return "Неверный ответ: " + String(isInteger(calc)?calc:(''+calc).substring(0,8)+'...') + "; попробуйте ещё раз"; game24(); return input + " = 24! Поздравляю! Ваш счёт: "+(++cnt); }; function game24 () { //основная функция let bads = [ //нет решения, по возрастанию цифр 1111,1112,1113,1114,1115,1116,1117,1119, 1122,1123,1124,1125,1133,1159,1167,1177,1178,1179,1189,1199, 1222,1223,1299,1346,1355,1456,1499,1555,1557,1558,1577,1667,1668,1677,1678,1777,1778,1899,1999, 2222,2226,2279,2299,2334,2555,2556,2599,2677,2777,2779,2799,2999, 3358,3377,3388,3467,3488,3555,3577, 4459,4466,4467,4477,4499,4779,4999, 5557,5558,5569,5579,5777,5778,5799,5899,5999, 6667,6677,6678,6699,6777,6778,6779,6788,6999, 7777,7778,7779,7788,7789,7799,7888,7899,7999, 8888,8889,8899,8999, 9999 ]; do { numbers = [1, 2, 3, 4].map(function() { return Math.floor(Math.random() * 8 + 1); }); let arr = numbers.slice(); arr.sort ( function(a,b) { return a - b; }); let val = parseInt(arr.join('')); if (bads.includes(val)) continue; else break; } while (1); //Удалить нерешаемые! document.form24.text24.value = ''; document.getElementById('res24').innerHTML = help; document.getElementById('data24').innerHTML = numbers.join(' '); } function isInteger(num) { //хитрая проверка на целое число return (num ^ 0) === num; } window.addEventListener ('load', function (e) { game24(); }); </script> <noscript><div align="center">Извините, для работы приложения нужен включённый Javascript</div></noscript> <table align="center" width="600" cellpadding="0" cellspacing="4" border="0"> <tr> <td align="center" valign="middle"> <form name="form24" method="post" onsubmit="return false;"> Ваши числа: <span id="data24"></span></font></p> <input type="text" name="text24" size="20" maxlength="18" value="" /> <input type="button" name="action1" value="Выполнить" onclick="document.getElementById('res24').innerHTML = eval24(numbers, document.form24.text24.value);return false;" /> </form> </td> </tr> <tr> <td align="center" valign="top"> <div id = "res24"></div> </td> </tr> </table>
Не предложенные числа использовать по правилам нельзя, а также использовать не все числа из предложенных.
Я решил, что сделать разумные правила фильтрации невозможных комбинаций цифр было бы сложнее, чем просто перечислить недопустимые сочетания в массиве (см. массив bads
в исходнике, нет никакой уверенности, что там все возможные недопустимые значения). Если найдёте недопустимую комбинацию цифр, которую скрипт предлагает решить - напишите в комментарий!
P.S. Вроде бы, скорректировал список недопустимых решений в листинге, спасибо внимательному анонимному читателю, написавшему на почту :)
23.04.2016, 20:54 [7232 просмотра]