Chapter 3. C-Quence – A Memory Game

We will be crafting an app that is a little more entertaining by using everything that we covered in Chapter 1, Exploring the New Platform, adding code which uses basic Swift features that most developers will find familiar and will address some of the topics that face the developer in creating software for a platform that presents some unique challenges.

C-Quence will be a game that challenges players' ability to memorize a sequence of colors generated by the app.

It is a game to be played in short bursts rather than prolonged activity, as one of the first things that becomes clear when using a physical device is that the watch is unsuited to tasks that take more than a short time to complete, which we will keep in mind as we look at the top-level design of the app.

Bear in mind that, although this is a very modest app in terms of the amount of coding it takes to bring it to completion, we still want to adhere to what some refer to as Best Practice (and others prefer to think of as simply learning from others' mistakes without the schadenfreude).

Here is a brief overview of how we will approach the various steps of development:

  • Plan the flow of the app
  • Set up the Xcode project
  • Build the interface in Interface Builder
  • Create the game logic class
  • Implement the Interface Controller logic
  • Hook up the classes and interface

The code presented in this chapter will reside fully on the watch, needing no support from the iPhone companion app. It will not be a complete and functioning app, that will come in the following chapter, but it will be a robust framework and we will have learned some important principles of software design.

Plan the app

Let's have a look at how the app will be developed.

Mission statement

Let us look at the app's requirements before beginning any work in Xcode.

We will write a game that presents a group of four color-coded buttons which flash in an order generated by the app, which is then to be repeated by the user by tapping the buttons. If the user does this successfully, the sequence length is extended by adding a randomly generated color, and is flashed again (the flash interval needs to be a suitable time, say, in the region of one second). The sequence gets longer and longer, each time requiring the user to repeat it. Eventually the user will fail, and will be presented with his 'score'—the length of the last correctly guessed sequence, and a prompt to start the next game.

So that's our game, time to get building that interface, right?

Well, no, not quite yet. To make the best use of our coding time, and to produce the best code possible, we will try to formalize our game requirements into a form that will help us maintain a clear picture of what we are aiming to achieve. Our mission statement (a term to be taken with a pinch of salt, perhaps, but it does sum it up rather nicely) is already the first step in this process. Next we want to take a blow-by-blow look at how the user progresses through the app.

User story

It's not just film directors and producers that get to play with storyboards; long before Apple commandeered the term for their IB interface layouts, software engineers came together to run through the so-called user stories and sketch the storyboards that emerged from these sessions.

As tempting as it is to start work on a smart looking bunch of buttons and labels that we can see on our simulators and devices (and garner a few oohs and ahs from friends and colleagues), it really is essential to get some kind of handle on what the software will be doing when it comes up against its biggest challenge—the user. Doing this will substantially improve the quality of code that we write and the speed with which we write it. It is also likely to reduce the amount of code we produce and as any experienced developer will tell you, less code means fewer mistakes, easier code maintenance, and greater efficiency.

lessCode == betterCode //evaluates to true

As the first attempt, let's just run through what the user will experience when using the app, without (yet) attempting to extract any formal specifications.

But this is a game and games don't have users, they have players, so our user story becomes a player story:

The player will launch the app and be presented with a screen prompting her to begin play. This suggests a button (no prizes for working that one out), possibly labelled 'Play'. Whatever we label it, we shall refer to it as the Play button. She will have no choice than to tap the Play button (or leave the app, but let's be optimistic here) and so we can move onto the next step. The app will show the four colored buttons and flash a sequence of colors, which is generated on the fly by adding a random color to that sequence (the game starts with an empty sequence, so extending the sequence needs to take place before the first round). At this point, we do not want the player to be able to actively engage with the app and so we disable user interaction on the buttons.

Now that we are ready to accept the player's attempt to repeat the sequence, we need to enable user interaction.

The player's guess is evaluated. If the player's guess is correct, but she has not yet guessed the complete sequence, we simply wait for the next guess. If the player's guess is correct and she has guessed the whole sequence, user interaction is disabled once more, the sequence is extended by a random color, and flashed on the screen. If the guess is wrong, the game is over, and we present the player with both her score and the Play button with which she has the opportunity to play the next round. Also, we need to reset the sequence back to empty in preparation for the next game.

Now we can arrange that user story into pseudocode, a rough description of what we need the app to do:

Present Play button

  • User hits Play

Play sequence

  • Extend sequence by one color
  • Disable user interaction
  • Flash colors in sequence

Get player input

  • Enable user interaction
  • Store user input
  • Acknowledge user input with color flash

If player guesses correctly and guess is incomplete

  • Get player input (as above)

Otherwise (i.e. user guesses correctly and guess is complete)

  • Play sequence (as above)

If user guesses wrong

  • Show results
  • Reset sequence
  • Present Play button (as above)

We might want to sketch out such pseudocode in a more visual manner to produce a flow-chart that will provide a map for us to follow when designing the app:

User story

Now we're getting somewhere! Already we can get a pretty good idea of the the way in which the flow of the program suggests much of the code that we will be writing and this will be a valuable aid to ensuring that what we write is as clear and concise as we can get it, and that we only have to write it once.

We are now ready to think about how we will structure our app.

App requirements

We will divide our app into three parts according to the program design principles espoused by Apple for writing iOS apps, the so called Model-View-Controller pattern.

  • The Model, in this case, will be the actual game logic of generating the sequence, evaluating the player's guesses and deciding when the game is over.
  • The View is simply the screen with which the player engages, which we will create in Interface Builder; it includes all of the UI elements we will need to interact with the player.
  • The Controller will facilitate communication between the two by providing methods to present information to the player, gather player input, create timers, and set properties of the view to reflect the state of the app.

    Note

    This separation of concerns is the bedrock of object orientated programming. It provides a pattern for designing robust apps and producing code that is both re-usable and easy to maintain. An expansive explanation of MVC is beyond the scope of this book, but the reader is encouraged to gain as much familiarity with the concept as possible.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.131.38.14