Today I’ve been writing a hangman game. I imagine just about everybody is familiar with this game. It’s something I played with other children in school. Someone thinks of a word and then draws spaces on the board, and the others get to guess letters. Players guess letters until they can guess the whole word or phrase. Typically, though, for each letter you guess wrong someone draws a morbid little man hanging from a noose. When the man-doodle is fully formed, the game is lost.
My version of the game does not include this hanging man doodle (yet), but the rest of the principles are there. I’ve already published the app even though I’m still aware of some work that needs to be done. Consider it an alpha version. It’s published here: http://widgetwonk.azurewebsites.net/Vue/VueHangman.
This tiny game is surprisingly complex under the hood. When you play hangman, one person knows the word and everyone else has to guess. I decided early on that in my game the person who knows the word would not be your computer but the server. What that means is that when you begin my game, the server chooses a phrase for you at random from a long list of common English phrases. (More on that list later.) It will tell you the length of the phrase right away. Then, with additional queries, you can ask the server if particular letters appear in the phrase, one by one. If yes, it will respond with an array revealing the positions of the letters you asked for.
If will also confirm or deny if you try to guess the complete phrase all at once.
Strictly speaking, it was not necessary to do things this way. I could have written a self-contained game that works offline. But I was going for techniques and mechanisms that better mimic other, more general situations. The general idea here is that you have access to an oracle, and it can tell you yes or no, but it will not give you answers any more helpful than that. And I wanted that unhelpful oracle mechanism to be encapsulated separately from the client side.
(The hackers among you might have already noticed the similarity to password cracking.)
I used the Vue library at the outset for no particular reason. I’m not sure yet why I might choose any library other than Vue except that other people out there in the world like React and Angular so much so that I need to know them too. I like Vue.
Thus I had established that I was using Vue and that I needed to do some http requests. Nowadays I could have used the native fetch API along with a polyfill, but I decided to use Axios just for the sake of being familiar with it. That said, though, axios offered me nothing to learn, which is perhaps the highest praise I can think of to give a piece of software. It works exactly as I anticipated. I don’t know why I haven’t been using axios for years. I guess I was just content to roll my own handlers for ajax stuff.
Hangman is also the first widget I’ve made of any size to use Vuex. My opinion of Vuex at this point is that it suffers from not being Redux. Redux is cleaner. Redux does a better job of persuading you to write code that doesn’t cause bugs. Understanding how Vuex works in a deep sense means understanding the sometimes complicated nature of Vue’s reactivity. I try as hard as I can not to need to learn that mess. An immutable state object solves the problem created by applying a “watch” to something in a shallow way or a deep way. If any change to state means creating a whole new object from whole cloth, then we are changing the reference the variable points to. Thus, shallow watch and deep watch are the same thing.
I used Vuex because I’ve heard it mentioned so often in the same breath as Vue. I need to be familiar with it. But if the time comes when I’m working on a team to build a project from the ground up, I will argue for Redux. I don’t want to use Vuex again. I will, but it’s not great.
The main complexity of the app was in implementing the logic. I put all of the business logic in the state actions which in turn call state mutations. The rest was flourish. I wanted letters to highlight themselves briefly when they appear. That wasn’t hard, but it’s something I would not have bothered to do a month ago Now I think it’s almost necessary. And I need more things like that. After seeing my parents play with this app, I see that I need some kind of non-intrusive feedback to tell you when you guess a letter wrong. Right now my app just adds that letter to your list of guesses and otherwise doesn’t nothing. It’s not enough feedback.
Soon then, tomorrow probably, I will add some of these very basic improvements to the app. And then maybe some unit testing later.