Created
December 16, 2024 04:37
-
-
Save santhoshanand/c1ca06ceca50c45bc7115697f3ab5fab to your computer and use it in GitHub Desktop.
simple Cryptogram puzzle in Tamil . It is in the basic version please go through the code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!-- Cryptogram Interactive Tamil Puzzle with Keyboard | |
| https://gist.github.com/allenbh/7128566 | |
| Solve the puzzle by replacing letters to reveal the hidden message. | |
| Use the keyboard and mouse to move the cursor. | |
| Type a letter to make a guess and advance the cursor. | |
| Correct mistakes by typing over them or with backspace and delete. | |
| --> | |
| <style> | |
| .puzzle { font-family: monospace; font-size: 2em } | |
| .guess { font-style: normal; font-weight: bold; color: darkslateblue} | |
| .solved { color: darkgreen} | |
| .error { color: red } | |
| .cursor { background-color: lightgray } | |
| .curchr { text-decoration: underline } | |
| </style> | |
| <style> | |
| #tamil-keyboard { | |
| margin-top: 20px; | |
| text-align: center; | |
| } | |
| .keyboard { | |
| display: flex; | |
| flex-wrap: wrap; | |
| justify-content: center; | |
| gap: 10px; | |
| } | |
| .key { | |
| font-size: 1.5em; | |
| padding: 10px 15px; | |
| background-color: #f0f0f0; | |
| border: 1px solid #ccc; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| user-select: none; | |
| } | |
| .key:hover { | |
| background-color: #d9d9d9; | |
| } | |
| </style> | |
| <body> | |
| <h1>Cryptogram - குறியீட்டு விளையாட்டு</h1> | |
| <p>Solve the puzzle by replacing letters to reveal the hidden message.</p> | |
| <p>Use the keyboard and mouse to move the cursor. | |
| Type a letter to enter a guess and advance the cursor. | |
| Correct mistakes by typing over them or with backspace and delete.</p> | |
| <p>சுட்டியை நகர்த்துவதற்கு விசைப்பலகை மற்றும் சுட்டியைப் பயன்படுத்தவும். ஒரு கடிதத்தை உள்ளிட்டுக் குறியீட்டை முன்வைக்கவும். தவறுகளைச் சரிசெய்ய நீங்கள் அதை மீண்டும் எழுதலாம் அல்லது backspace ஐப் பயன்படுத்தலாம் மற்றும் நீக்கலாம்.</p> | |
| <p id="puzzle"></p> | |
| <p>Use this keypad for easy (title has the key)</p> | |
| <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script> | |
| <script> | |
| // Tamil Cryptogram with Virtual Tamil Keyboard Integration | |
| var tamilAlphabet = "அஆஇஈஉஊஎஏஐஒஓஔாி◌ீுூெேைொோௌகஙசஜஞடணதநனபமயரறலளழவஶஷஸஹஃ◌்"; | |
| var encodeCypher = {}; | |
| var decodeCypher = {}; | |
| var textClear = ""; | |
| var textAlpha = ""; | |
| var textKey = ""; | |
| var textHidden = ""; | |
| var textSolved = ""; | |
| function setPuzzle(text) { | |
| textClear = text; | |
| textAlpha = makeAlpha(textClear); | |
| textKey = makeKey(textAlpha.length); | |
| encodeCypher = makeCypher(textAlpha, textKey); | |
| decodeCypher = makeCypher(textKey, textKey.toLowerCase()); | |
| textHidden = translate(textClear, encodeCypher, true); | |
| textSolved = translate(textHidden, decodeCypher, true); | |
| } | |
| function makeCypher(from, to) { | |
| var cypher = {}; | |
| for (var i = 0; i < from.length; ++i) { | |
| cypher[from.charAt(i)] = to.charAt(i); | |
| } | |
| return cypher; | |
| } | |
| function translate(text, cypher, preserve) { | |
| var arry = text.split(""); | |
| for (var i = 0; i < arry.length; ++i) { | |
| var arryval = arry[i]; | |
| if (cypher.hasOwnProperty(arryval)) { | |
| var cypherval = cypher[arryval]; | |
| if (!preserve) { | |
| arry[i] = cypherval; | |
| } else { | |
| arry[i] = arryval === arry[i] ? cypherval : cypherval.toLowerCase(); | |
| } | |
| } | |
| } | |
| return arry.join(""); | |
| } | |
| function makeAlpha(text) { | |
| var arry = text | |
| .replace(/[^-]/g, "") // Keep only Tamil characters | |
| .split(""); | |
| arry.sort(); | |
| var uniqueChars = [...new Set(arry)]; // Remove duplicates | |
| return uniqueChars.join(""); | |
| } | |
| function scramble(alpha) { | |
| var arry = alpha.split(""); | |
| for (var i = arry.length; 0 < i; --i) { | |
| var j = Math.floor(i * Math.random()); | |
| [arry[i - 1], arry[j]] = [arry[j], arry[i - 1]]; | |
| } | |
| return arry.join(""); | |
| } | |
| function makeKey(length) { | |
| return scramble(tamilAlphabet).substr(0, length); | |
| } | |
| // Cursor and puzzle interaction logic | |
| var cursorPos = 0; | |
| var cursorBlink = true; | |
| var cursorTimer = null; | |
| function cursorUpdate(pos) { | |
| if (cursorTimer != null) { | |
| clearInterval(cursorTimer); | |
| } | |
| while (pos < 0) { | |
| pos += textHidden.length; | |
| } | |
| while (textHidden.length <= pos) { | |
| pos -= textHidden.length; | |
| } | |
| cursorPos = pos; | |
| cursorBlink = true; | |
| update(); | |
| cursorCallback(); | |
| cursorTimer = setInterval(cursorCallback, 800); | |
| } | |
| function setGuess(cypherVal, clearVal) { | |
| cypherVal = cypherVal.toUpperCase(); | |
| clearVal = clearVal.toUpperCase(); | |
| if (decodeCypher.hasOwnProperty(cypherVal)) { | |
| decodeCypher[cypherVal] = clearVal; | |
| textSolved = translate(textHidden, decodeCypher, true); | |
| update(); // Refresh the puzzle | |
| } | |
| } | |
| function update() { | |
| var elems = document.querySelectorAll("#puzzle span"); | |
| elems.forEach((el, i) => { | |
| el.textContent = textSolved.charAt(i); | |
| el.className = getClass(i); | |
| }); | |
| } | |
| function getClass(i) { | |
| var hiddenVal = textHidden.charAt(i).toUpperCase(); | |
| if (!decodeCypher.hasOwnProperty(hiddenVal)) { | |
| return ""; | |
| } else { | |
| var decodeVal = decodeCypher[hiddenVal]; | |
| return decodeVal === decodeVal.toUpperCase() ? "guess" : "error"; | |
| } | |
| } | |
| function cursorCallback() { | |
| var elems = document.querySelectorAll("#puzzle span"); | |
| elems.forEach((el, i) => { | |
| el.classList.toggle("cursor", i === cursorPos && cursorBlink); | |
| }); | |
| cursorBlink = !cursorBlink; | |
| } | |
| // Create Tamil virtual keyboard | |
| document.body.insertAdjacentHTML( | |
| "beforeend", | |
| `<div id="tamil-keyboard" style="display: flex; flex-wrap: wrap;"> | |
| ${tamilAlphabet | |
| .split("") | |
| .map( | |
| (char) => | |
| `<button class="key" style="margin: 2px; padding: 10px;">${char}</button>` | |
| ) | |
| .join("")} | |
| </div>` | |
| ); | |
| document.getElementById("tamil-keyboard").addEventListener("click", function (event) { | |
| if (event.target.classList.contains("key")) { | |
| var tamilChar = event.target.textContent; | |
| setGuess(textHidden.charAt(cursorPos), tamilChar); // Set the guess for the current character | |
| cursorUpdate(cursorPos + 1); // Move the cursor forward | |
| } | |
| }); | |
| </script> | |
| <script> | |
| var puzzleOptions = [ | |
| "தமிழ் குறியீட்டு விளையாட்டு" | |
| ]; | |
| setPuzzle(puzzleOptions[Math.floor(Math.random()*puzzleOptions.length)]); | |
| document.body.innerHTML.replace( | |
| /<p id="puzzle"><\/p>/, | |
| `<div id="puzzle" style="font-family: monospace; font-size: 1.5em;">${textHidden | |
| .split("") | |
| .map(() => `<span>_</span>`) | |
| .join("")}</div>` | |
| ); | |
| var cursorPos = 0; | |
| var cursorBlink = true; | |
| var cursorTimer = null; | |
| var puzzle = d3.selectAll("#puzzle"); | |
| puzzle.classed("puzzle", true); | |
| var data = puzzle.selectAll("*").data(d3.range(textSolved.length)); | |
| data.enter().append("span"); | |
| data.exit().remove(); | |
| data.order(); | |
| function setGuessAtCursor(val) { | |
| setGuess(textHidden.charAt(cursorPos), val); | |
| update(); | |
| } | |
| function clearGuessAtCursor() { | |
| clearGuess(textHidden.charAt(cursorPos)); | |
| update(); | |
| } | |
| // Handle key events | |
| function updateKey(key) { | |
| switch (key) { | |
| case 37: // left arrow | |
| cursorUpdate(cursorPos - 1); | |
| return true; | |
| case 32: // space | |
| case 39: // right arrow | |
| cursorUpdate(cursorPos + 1); | |
| return true; | |
| case 36: // home | |
| cursorUpdate(0); | |
| return true; | |
| case 35: // end | |
| cursorUpdate(-1); | |
| return true; | |
| case 8: // backspace | |
| cursorUpdate(cursorPos - 1); | |
| clearGuessAtCursor(); | |
| return true; | |
| case 46: // delete | |
| clearGuessAtCursor(); | |
| return true; | |
| } | |
| // Tamil character handling and ASCII | |
| if ((key >= 0x0B80 && key <= 0x0BFF) || (key >= 0x20 && key <= 0x7E)) { | |
| var val = String.fromCharCode(key); | |
| setGuessAtCursor(val); | |
| cursorUpdate(cursorPos + 1); | |
| return true; | |
| } | |
| return false; | |
| } | |
| function keyDownCallback() { | |
| if(updateKey(d3.event.keyCode || d3.event.which)) | |
| d3.event.preventDefault(); | |
| } | |
| d3.selectAll("body").on("keydown", keyDownCallback); | |
| cursorUpdate(0); | |
| update(); | |
| </script> | |
| </body> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment