Skip to content

Instantly share code, notes, and snippets.

@santhoshanand
Created December 16, 2024 04:37
Show Gist options
  • Select an option

  • Save santhoshanand/c1ca06ceca50c45bc7115697f3ab5fab to your computer and use it in GitHub Desktop.

Select an option

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
<!-- 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