Do you remember the game called Wordle? The game that was trendy not long ago.
And sure, if you are a programmer, you have seen a lot of versions of this game with different languages and technologies. Now I'm going to show you, how to make this game in the language Haskell, loved by a few, hated by others and ignored by many.
Before you begin, it is necessary that install stack to install some packages.
This means that when entering the file name we will receive an IO String and to “unwrap” the IO monad we will use the Haskell do-notation, that way we get the text with the file content.
Besides, to get a list with all words with the same format, we use the next code:
You can imagine the process to build animals like a pipe that going from the bottom to the top. So animalsText first pass by pack that transform a String to a Text, toLower transform all text to lowercase, lines split the lines and map T.words to each line split in words and finally join all in a list.
In Haskell for use of random numbers (pseudo-randoms), we will use the package random. The next step is to choose a random word of the list. For this, we must make a seed:
The one I named g, later generate a random number, selected_index in the range 0 to the length of animals and getting the word in that index using (!!) function.
In Haskell the operators also are functions.
We already have a random word chosen from a file, now we have to program the logic of the game, for this I created a play function.
importData.Text(Text,pack,strip,toLower,unpack,)importqualifiedData.TextasTimportqualifiedData.Text.IOasTIOimportText.Printf(printf)play::Text->IO[Text]playselected_word=goattempts[]wherego::Int->[Text]->IO[Text]go0xs=returnxsgonxs=doleti=1+lengthxsputStrLn$"Please enter your animal "++showi++"/"++showattempts++": "attemptstr<-getLineletattempt=toLower.strip$packattemptstrlet(wordle,correct)=getWordleattemptselected_wordprintf"Rustle (ES) %d/%d\n\n"iattemptsTIO.putStrLnwordleifcorrectthendoputStrLn"Congratulation!"printf"Rustle (ES) %d/%d\n\n"iattemptsreturn(wordle:xs)elsedogo(n-1)(wordle:xs)
Let's go by parts, play :: Text -> IO [Text] receive the select word and return all games. In the definition of play, I created an auxiliary function called go, that receive the attempts and an empty list. This function iterate the games, i.e., ask the user a word, show the result and while as long as it does not run out of plays or win, the game continue in the recursion.
The function return is not the same that the statement return of others languages mainly imperatives. In Haskell the function are composition of function, since what follows the equals is what defines the function. return wrap the value in a Monad, in this case IO Monad.
Other function important is getWordle, which is defined as:
The function (<>) is a operator to concat two Semigroups, in this case, two Text, for example "foo" <> "bar" = "foobar".
This receives two Text types, attempt and correct, i.e., the attempt of user and the correct word. Haskell has the Let syntax, here we're going to define result.
The strategic that I thought was map the attempt and the correct word together, with some function that check if is success, misplace or fail. The function zipWith does that, apply zip to two lists and call a function with each pair values. In resume is a map and zip composed.
The go function, receive the two values and if are equals then marked as Success, if the character is in the correct word then is a Misplace else is Fail.
If the attempt word is more shore than the correct then the result in screen was going to be more short too, to solve this rest contain the rest of result, but only if correct is more long than attempt. Lastly, isCorrect ask if attempt and correct are equals.
Also, I defined some others things like:
{-# LANGUAGE LambdaCase #-}dataState=Fail|Success|Misplacecshow::State->Charcshow=\caseFail->'⬜'Success->'🟩'Misplace->'🟨'attempts::Intattempts=6
I made a data type named State and defined cshow that return the character according to a State. And attempts that return the attempt amount of game.
Later to finish the game the program show the games, for this:
Is necessary install stack a package manager of Haskell.
stack run
Explication
Do you remember the game called Wordle? The game that was trendy not long ago.
And sure, if you are a programmer, you have seen a lot of versions of this game with different languages and technologies. Now I'm going to show you, how to make this game in the language Haskell, loved by a few, hated by others and ignored by many.
Before you begin, it is necessary that install stack to install some packages.
The game read a list of words with animals.
main::IO()
main =dolet filename ="animals.txt"
animalsText <-readFile filename
...