2013-02-07

Value of an Ace

I made a Blackjack game to test myself on the JavaScript I have learned so far. (Link to it at the bottom of this post.) The greatest challenge I faced in getting the game to work was the variable value of an Ace. As you will know if you're familiar with the game of Blackjack, the objective is to get the player's hand as close as possible to a value of 21, without going over (which is an automatic loss). The player starts with two cards, and can continually ask for more cards until the player fears "busting" (going over 21), then the player may stop and pray that the dealer will do a worse job.

Aces behave in a special way in this game, as they are generally valued at 11, but their value changes if the player accidentally goes over 21. If the player is holding an Ace and goes over 21, the Ace will drop from a value of 11 to just 1. This value changes as the player draws new cards, and every Ace drawn will behave this way independently. So I needed to handle the scoring of a hand in a way that would allow the value of an Ace to be evaluated anew every time a new card was drawn.

When I started building the scoring function I ran into some problems. The first problem was timing. Because Aces change their value based on the non-Ace cards in the player's hand, I couldn't evaluate the player's hand in the order it was dealt.

Take the following example, in which the player is dealt (and the player hand is populated with) 5, 4, Ace, and 8, in that order. If I evaluate the cards in order, I would come to the Ace at a time when the cumulative value of the hand is still only 9 (first 5, then add the next card, 4). Since the 8 hasn't been added yet, the Ace seems like a great addition to the hand at this point, because even if I'm checking for bust (going over 21), 9 + Ace (11) would be 20, which is very close to 21. But then, when the 8 is added, the player would bust - I would want to evaluate the Ace as a 1, but it would be too late, the Ace was already evaluated!

One solution that came to mind early on was to reiterate through the hand any time a bust was detected, and check for Aces. I could subtract 10 from the total value of the hand for each Ace (if any) until the value of the hand came back to under 22 (leaving any remaining Ace valued at 11). But this struck me as a rather inelegant and scrappy solution. I wanted to evaluate the Aces on the fly so I wouldn't have to feel like I was "going back" and removing value that had already been added to the hand.

I got around this by adding the value of each non-Ace to the value of the hand and leaving out the values of any Aces, but counting the number of Aces. Only after the non-Ace value of the hand was evaluated, I began to evaluate and add in the value of each Ace. This is where things became complicated algorithmically. I needed to put together an algorithm to check not just whether an Ace would bust the hand, but whether an Ace would bust the hand in light of the fact that there is a variable quantity of Aces left to evaluate!

Here's what I came up with, I'll explain it below.

The good part is the for loop at line 24, where Ace values are evaluated. The for loop iterates through all the Aces. For each Ace, I check whether the hand would bust if the Ace was valued at 11, and all remaining Aces were valued at 1. If the hand would bust, the Ace is evaluated to 1; otherwise, it gets an 11 and the loop continues.

In retrospect, and as more experienced developers / mathematicians / Blackjack players will likely have noticed, this excessively elaborate Ace evaluation algorithm is entirely unnecessary! You only ever have to check whether the first Ace would bust the hand. If one Ace is valued at 11, you know all the rest must be valued at 1, because if two Aces evaluated to 11, you would already have busted with 22. Oops! If I continue to iterate this game with future editions, I will fix this inefficiency (because now it's bugging me).

If you want to try out the game, you're of course welcome! Be warned, it's fairly rudimentary as Blackjack games go, I was more concerned with getting JavaScript up and running on a website than with putting together a faithful representation of the game of Blackjack. (No betting, can't double down or split, no automatic win for Blackjack, but the basics are all there, single player versus a dealer.) Also, as a bare-bones first attempt at writing my own JS in the wild, the entire game exists in alert() and confirm() pop-ups, so apologies for all the clicking you'll have to do to play it! At any rate, here it is.

Thanks for reading!
- Steven Kitzes

2013-02-06

State Based Menus

Recently I've been doing a lot of UI (user interface, or menu) work, specifically for console and mobile video games. This hasn't turned out to be nearly as easy as I originally thought it would be. To my relief, others have confided in me that even seasoned veterans of the gaming and mobile app industries find it difficult to engineer UI without things getting pretty kludgy. There are lots of problems to solve along the way, so I thought I'd share some of what I've learned along the way about designing and building game UI.

I want to concentrate on state-based menus. One of the easiest ways to navigate between screens, elements, and submenus of a user interface is using states. If you don't know what that means, my goal today is to try to explain it. I have seen it explained many times in terms that I, as a junior developer, did not understand, so I want to revisit the topic in a way that is as easy as possible to understand for beginners.

So, what is a state? Let's build an analogy using a very simple example. A light in your home has two states. One state, on, represents the light's status when it is (hopefully) powered and glowing. The other state, off, represents the light when it is unpowered and dark. The user can choose from these two states to tell the light how to behave. A simple, state-based interface! Of course, in computer programming terms, even this simple two-state interface can begin to look complicated. Obviously, if the light is off and the user attempts to turn it on, we apply power. If the light is on and the user tries to turn it off, we remove power. But what happens if the user tries to turn the light on when it's already on? What happens if the user tries to turn the light on, but there is no power? We have to account for these possibilities and more.

In the case of a menu system like one you might see in a video game, you might have a "Main Menu" state, a "Load Game" state, an "Options" state, and others. The "state" itself is stored somewhere as a variable. This can be conveniently handled with an enumerated index, which makes it easier for you (and other people working in your project) to read. Using enumeration at the lower level can be a bit intimidating for beginners, but think of it like this: you have a variable, an int called menuState, which is our state variable. Then you have a collection of words that represent constant values that menuState might represent. If your menuState integer matches one of the constant values you defined (an enumerated value), the menu is in a state that it recognizes! Consider the following snippet, defining (enumerating) some constant integer values that represent a menu's states, and setting up a menuState variable.

To connect this to our light bulb analogy, consider the menu system to be the light bulb itself - it can be switched from one state to another. For example, when your program is first loaded and the UI is initialized, the application might take the user to the Main Menu state automatically. But the user can then switch to another state, just as you can switch a light from "off" to "on." Just as you would use a switch to change a light's state from "off" to "on," you can use UI controls to change a menu's state from "Main Menu" to "Options Menu"! For a more concrete example of what I'm talking about, consider this next snippet. Read the comments if the code is a bit confusing right now.

For a more complex example, I'll take the case of a project I was recently assigned. One feature of a game we are making is an image gallery. One of the greatest challenges in building this gallery has been organizing the functions of the menu so that each element is only visible when I want it to be - in other words, when the menu is in the proper state! In organizing the gallery menu into states, the first step was to look at the features and functions the gallery needed to have.

According to the project specifications, the gallery needed to be separated into categories, with a set of buttons to select each category; a grid of selectable image thumbnails filling the rest of the screen; a popup window to display selected images full size; a dialog window for providing extra information to the user; a confirm window for making selections; and an alert pop-up to warn the user when trying to select an item that is not available. If that sounds like a lot of things to manage in one menu, I agree. I felt the same way the first time an assignment like this was handed to me. But using states, breaking these menu elements into manageable chunks was a breeze! I'll talk through my process to make it a little easier to see.

The first step I took was to break each function of the gallery apart into pieces, to be grouped into states based on when the functions would be available. For example, when the category buttons needed to be active, nothing else in the menu could be. The game needed to know that when the category buttons were active, arrow key and button presses would only affect the category buttons themselves. The solution is to tell the gallery menu that it is in the CategoryButtons state!

When the menu is in a given state, input should only effect the part of the menu that corresponds to the current state. For example, when the user presses the down arrow, if the menu is in the CategoryButtons state, the cursor should move down the list of category buttons. The cursor in the thumbnail grid should not move; in fact, it probably shouldn't be visible at all! Then, when the player finally presses a button to confirm a category selection, the state of the menu is changed from CategoryButtons to ThumbnailButtons. Now, the game sees the state change, makes the category button cursor disappear, and makes a cursor appear on the thumbnail grid. Now, control input makes the thumbnail cursor move, instead of the category button cursor! See the following snippet for an example of how this would look in code. Again, I've tried to add a lot of comments to make it clear what I'm doing in the code.

Obviously, there is a lot more to state-based UI development than just managing the states themselves. And of course, states can be used for a plethora of other tasks that I haven't begun to delve into, and there is a lot of other stuff to worry about when you are putting a UI together. States are just the beginning and help to organize your menu and control flow throughout the menu navigation process. But hopefully this will help you understand the fundamental state-based strategy for menu management!

Thanks for reading!
- Steven Kitzes