So I got to thinking, how would I do something like this in the browser:
import System.IO
main :: IO ()
= do
main putStrLn "let's play Hangman by creating a word to guess:"
<- getSpecialLine
secretWord putStrLn "Now try to guess it. Yeah I know you know it!"
play secretWord
-- 1. Use getCh to build our string
getSpecialLine :: IO String
= do
getSpecialLine <- getSpecialChar
c if c == '\n' then do
putChar c
return []
else
do putChar '-'
<- getSpecialLine
cs return (c:cs)
getSpecialChar :: IO Char
= do
getSpecialChar False
hSetEcho stdin <- getChar
c True
hSetEcho stdin return c
play :: String -> IO ()
= putStrLn "A games loop begins"
play word
What AI had to say about it:
<!DOCTYPE html>
<html>
<head>
<title>Hangman Game</title>
<style>
font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; }
body { .hidden-input { position: absolute; left: -9999px; }
.dashes { letter-spacing: 5px; font-size: 24px; margin: 10px 0; }
</style>
</head>
<body>
<div id="game">
<div id="message"></div>
<input type="text" id="hiddenInput" class="hidden-input" maxlength="1">
<div id="dashes" class="dashes"></div>
</div>
<script>
let secretWord = '';
let currentDashes = '';
async function getSpecialChar() {
return new Promise((resolve) => {
const input = document.getElementById('hiddenInput');
.value = '';
input.focus();
input
const handler = (e) => {
if (e.key.length === 1) {
.preventDefault();
e.removeEventListener('keydown', handler);
inputresolve(e.key);
};
}
.addEventListener('keydown', handler);
input;
})
}
async function getSpecialLine() {
let word = '';
= '';
currentDashes document.getElementById('dashes').textContent = currentDashes;
updateMessage('Type the secret word (press Enter when done):');
while (true) {
const char = await getSpecialChar();
if (char === 'Enter') {
updateMessage('');
document.getElementById('dashes').textContent = '';
break;
else if (char.length === 1) {
} += char;
word += '-';
currentDashes document.getElementById('dashes').textContent = currentDashes;
}
}
return word;
}
function updateMessage(text) {
document.getElementById('message').textContent = text;
}
function play(word) {
updateMessage("A games loop begins! The secret word was: " + word);
// Game logic would go here
}
async function main() {
updateMessage("let's play Hangman by creating a word to guess:");
= await getSpecialLine();
secretWord
updateMessage("Now try to guess it. Yeah I know you know it!");
play(secretWord);
}
// Start the game
main();
</script>
</body>
</html>
Conclusion
Like the Haskell code, the JavaScript code is relatively straighforward. We are not mutating any variables in our code.
The next step will be to introduce some kind of state, basically game state. I will keep it simple, and put it in a game loop which recursively passes the updated game state, namely the word back to itself.
= do
main "images"
staticDirectory "css"
staticDirectory "js" staticDirectory