StackHack – A game prototyping project: part 1 – paper prototyping

Recently I undertook a game prototyping project to design and create a game with the working title of StackHack. I wanted to create a simple Christmas-themed game, as I’m trying to make it something of an annual tradition that each year I create a Christmas game for family and friends. Here’s last year’s effort.

The design process began with a paper prototype:

FullSizeRender 21

A paper prototype is a very quick way of exploring game ideas. You start with a simple background drawn on a sheet of paper and draw and cut out other bits of paper to represent the characters and dynamic elements in the game. You can then play with the elements to explore different game concepts, adding, removing or tweaking elements to strengthen initial ideas. Paper prototypes are much quicker to produce than digital prototypes, so you can quickly explore ideas and discard those that don’t work before moving on to the digital prototyping stage.

My idea for this game is that it would be set in Santa’s workshop – in the warehouse where Christmas presents are stacked ready for Santa to collect and deliver them. Unfortunately something has gone horribly wrong and the automatic present stacking machine (represented by the circular cannon at the top of the image) is just throwing out presents at random. The player, as head elf (represented by the stick man), must collect the presents (represented by the coloured cross-hatched cubes), and stack them in a pattern shown by the holographic guides (represented by the squares with dotted lines).

FullSizeRender 19

To achieve this the player can either push or carry the blocks to the guides.

FullSizeRender 18

When the player reaches the guides, they drop the present on the guide and it locks into place. As you can see from the image above, the player can stand on presents – they also have a jumping ability.

FullSizeRender 20

When the stack is complete the player has won the level and can move on to the next, slightly harder level.

FullSizeRender 22

Of course the game will soon become tiresome if that was all there was to it, so later levels had to introduce some additional elements. The most obvious of these is the addition of platforms. This complicates life for the player in two ways. Firstly, presents that they might need will sometimes come to rest on platforms, and secondly, the guides might be on a platform. To reach these the player will have to use presents to create additional platforms or steps to allow them to access higher areas.

The next addition is that some guides will not just accept any present, they will only accept presents of a matching colour. The colours are not easy to see in this image but the top position in the guide pattern will only accept a green present.

The image above shows one of the advantages of paper prototyping in highlighting potential issues. Although this image is not to scale, you can see that there is insufficient room between the lower platform and the ground for the player to pass beneath it. This would mean that any presents that slid underneath that platform would be inaccessible. This doesn’t mean that the platform idea won’t work, it just means that I have to take care in the level design to have platforms that are high enough for the player to pass under, or low enough to prevent presents from sliding beneath them.

In the next part I’ll describe the transition from the paper prototype to the first digital prototype.

Posted in Games, HTML5, Prototyping | Tagged , , , | 3 Comments

Review of Berklee College of Music’s Introduction to Music Production

Introduction to Music Production is a MOOC offered by Berklee College of Music through the Coursera online learning platform. If you want to know more about how these courses work, you might like to look at my earlier posts: A year of MOOCs and Review of Berklee College of Music’s Developing Your Musicianship.

This course veers more towards the technical side of music than the musical. If you want to work as a studio engineer or producer, or you are simply looking to have more control over how you produce your own music, then this is the right course for you. The course is six weeks long and covers a broad range of production topics:

  • The nature of Sound
  • Signal Flow
  • Digital Audio Workstations (DAW)
  • Mixers
  • Dynamic Effects
  • Filter and Delay Effects
  • Synthesis

The key term in the title of this course is introduction. Any one of these topics would merit an entire course of its own, and in a six week course there is only so much detail you can go into. So don’t expect to come away from this being an expert in any of these topics. That being said, the course instructor, Loudon Stearns, does an excellent job in the course videos of conveying the key points clearly and concisely. So you will come away with a sound overview of the end-to-end production process and some idea of where to begin with each part of that process.

Perhaps because the course does attempt to cover such a lot of ground in a short space of time, this is quite an intensive undertaking, especially for students who are fitting it around other commitments. I would say that Coursera’s estimate of six to eight hours of work a week is a little on the low side. Which is not to say that the effort won’t be rewarding.

At the end of each week, students are asked to demonstrate their understanding in two ways. First you will take a series of multiple-choice quizzes on the topics introduced that week. Secondly, and this is the time consuming bit, you are required to create your own teaching materials that cover one aspect of what you have learned that week. These materials are then peer reviewed by at least three other students. You will then also have to peer review the work of three other students.

As an example of what’s involved in this part of the course, here are the teaching materials I created:

This hopefully gives you some idea of the workload. That being said, creating your own teaching materials is an ideal way to cement your understanding of the course topics.

At the end of the course there is also a final exam. Unlike the weekly tests, this one is much longer, covers all the topics taught throughout the course and is timed.

If you manage to pass the course and you have signed up for certification (signature track), you’ll be awarded a nice looking certificate like this one.

The best way to use this course is to give yourself a quick overview of the music production process and then use it as a springboard to further investigate topics of particular interest to you. If you approach it in that way, and you are prepared to put the hours in, you will get a lot out of it.

Posted in Education, MOOCs, Music, Production | Tagged , , , | Leave a comment

Review of Berklee College of Music’s Developing Your Musicianship

Berklee College of Music is the largest and perhaps the most well-known contemporary music college in the world. For potential students unable to live and study in the Boston, MA area it also runs an extensive on-line programme.  However, both of those options are expensive, and for many students, especially those who need to remain in full-time work to support themselves and their families, the cost and time investment required by these courses puts them out of reach.

An alternative and cheaper way to access Berklee’s teaching materials is to sign up to one of their MOOCs made available through the Coursera platform. Developing Your Musicianship is one of these courses. The course is aimed at aspiring, new or experienced musicians who have had little formal musical training, or whose theory is a little rusty. It currently runs a couple of times a year over a six week period (check out the course home page to see upcoming dates). You can take it as a stand-alone course, or as part of the Modern Musician specialisation, which also includes courses on music production and songwriting, and requires the completion of a capstone project.

If you are not particularly bothered about certification, you can access the course materials for free. If you want a certificate, either for the individual course or for the specialisation, you will have to join the Signature Track, which requires you to pay a small fee. At the time I took the course, the fee for the specialisation was US$176. If you don’t want to take all the courses, you can pay a fee for just the courses you are interested in, which is less.

When you sign up for signature track you need to verify your identity. You do this by taking a picture with a webcam and typing a short phrase so the system can record your typing pattern. Each time you submit a piece of work, or take a test you will be required to take another picture and type another phrase to confirm your identity. This is to ensure the work you submit is your own and has not been completed for you by someone else.

If the mention of music theory sent you running for cover and you are imagining this is a very dry and dusty course, think again. Probably the best aspect of this course is the charismatic instructor, George W. Russell Jr. At the start of the course he emphasises that the most important thing is to have fun – and it is fun.

Each week you are guided through a progression of important topics: Major Scales, Major and Minor Triads, the Minor Pentatonic Scale, Major and Dominant Seventh Chords and Song Form.

George Russell’s emphasis is on practical demonstrations of these topics in the course videos, rather than lots of dry theory. You’ll get the most out of it, and have the most fun, if you have access to a keyboard of some sort so you can follow along. An important aspect of the course is an introduction to ear training, and although the course can only touch on the basics of this key skill, hopefully it will give you enough of a taste of it to make you want to explore it further once the course ends. I certainly found that was the case for me.

At the end of each week you demonstrate your understanding of the material by completing a short online quiz. Some of the quiz questions are straightforward multiple choice, but the most interesting are those that use audio and test your ear training. For example, you might be played two notes in succession and have to identify the interval, or you might be played a chord and have to identify the chord type.

There are also peer-reviewed assignments, which involve projects such as finding recorded examples of a blues progression, or finding recorded example of songs in a certain key, or examples of different intervals. Once you have submitted your assignments, they will be peer reviewed by at least three other people on the course. You will also have to review three assignments from other students. The peer review mechanism is completely anonymous to avoid any unconscious bias. Obviously this mechanism is not as good as having work reviewed by course staff, but fundamentally this is how Berklee is able to deliver the course material at such a low cost.

The course culminates in a final project in which you apply the theory you have learned to record a simple improvisation on the minor pentatonic scale over a 12-bar blues progression. Here’s my humble example: https://soundcloud.com/laurence-scotford/lscotford-assign6/s-WXLX6.

If you signed up for the signature track you’ll also receive a certificate. Here’s what that looks like: https://www.coursera.org/signature/certificate/Q6HG2BGLKJ.

If you’re a musician who is looking to get a more theoretical basis to your music, I’d recommend this as a great starting point.

Posted in Education, MOOCs, Music, Theory | Tagged , , , , | 1 Comment

A year of MOOCs

I’ve managed few posts in the past few months and that’s because, among other things, I’ve been busy exploring the world of Massive Open Online Courses or MOOCs for short.

If you don’t know what a MOOC is there’s a useful description here: http://en.m.wikipedia.org/wiki/Massive_open_online_course.

So over the course of a little over half a year I’ve tried five courses on EdX (https://www.edx.org) and Coursera (https://www.coursera.org).

These were:

I really didn’t know what to expect – or how MOOCs would compare to other forms of education. Are they genuinely useful or are they a soft option?

What I found surprised me and opened my eyes to the possibilities that MOOCs present.

MOOCs appear to take one of two forms. One type, of which Introduction to Computer Science is an example, is self-paced but has a final deadline.

The other type, of which all the others are examples, take place over a specific time-period with weekly deadlines and all participants progressing through the course at the same pace.

Some courses are stand-alone – CS50 is an example.

Others can optionally be linked as a series. These linked courses are called X-Series in EdX and Specializations in Coursera. For example, the Berklee courses are part of the Modern Musician Specialization (https://www.coursera.org/specialization/modernmusician/5) and the Educational Technology and Game Design courses from EdX are part of an Educational Technology X-Series(https://www.edx.org/xseries).

Just as you have the option to take individual courses or a whole series, you also usually have the option of working towards some form of certification or just auditing the course materials. In most cases, auditing courses is completely free, but most organisations charge a small fee for certification. This is still a fraction of what you would pay for the equivalent attendance course, but the trade off is that you don’t have the personal attention of the course staff.

Many courses also use a peer review marking system as the only practical means of grading so many students. This system is not without its challenges – inaccessible project work, poor quality and inconsistent marking being a couple of issues that I encountered. However the course creators do counter this by having each submission reviewed by several peers so that aberrant marking can be averaged out. CS50 though has a clever automated marking system for many of the problem sets, which analyses the output of the computer programmes you write. It can’t evaluate elements of programming style and efficiency as a human marker could, but it’s generally a more successful compromise than peer review marking.

One thing that become quickly apparent is that these courses are in no way a soft option. To complete a course requires a high level of commitment and hard work, especially if you are trying to complete it around other commitments.

Having said that, it’s been a fun and rewarding experience and I’d definitely recommend it to anyone looking for a low-cost way to broaden their education.

In the posts that follow I’ll review each of the courses in more detail:

Posted in Education, MOOCs | Tagged , , , , , , , | 2 Comments

OS X Games from the Ground Up: Hexapawn – BASIC programme

You can see an index of all the posts in this series: go to index.

In the previous post I explained how the Hexapawn game works. In this post I’ll dissect the original BASIC programme we’ll be converting to C.

Here’s the full listing:

The first thing you’ll probably note about this is that, at first sight, it’s almost incomprehensible. This is one of the difficulties with any code that is poorly commented.  So let’s take it piece by piece.

These first three lines are straightforward and will be familiar to you. They simply display the title and attribution as shown below.

Hexapawn title

These next few lines are just comments with further information about the programme.

Here the programmer creates some arrays and other variables that will be used during the programme:

  • B is a two-dimensional array that holds the 19 possible board configurations we looked at in the previous post
  • M holds the moves that are available for each of those configurations
  • S holds the current state of the board
  • P$ is a three character string that holds the characters used to represent the white and black pawns and an empty space on the board
  • W holds the number of wins for the computer player
  • L holds the number of losses for the computer player.

The board (as stored in S and 19 times in B) is represented by an array of 9 values with elements 1 to 3 representing the top row of the board from left to right, 4 to 6 representing the middle row and 7 to 9 representing the bottom row.

Position 1 Position 2 Position 3
Position 4 Position 5 Position 6
Position 7 Position 8 Position 9

The content of the board at each position is represented by one of three numbers:

  • -1: black pawn
  • 0: empty square
  • 1: white pawn

Each move is stored as a two digit number, with the first digit indicating the from position and the second digit indicating the to position. So for the configuration shown below, a code of 25, for example, represents a black pawn advancing from position 2 to position 5. A code of 24 would indicate the black pawn at position 2 capturing the white pawn at position 4.

Position 1
Value -1
Position 2
Value -1
Position 3
Value -1
Position 4
Value 1
Position 5
Value 0
Position 6
Value 0
Position 7
Value 0
Position 8
Value 1
Position 9
Value 1

Hexapawn example config

These three lines are something we’ve not seen in the programmes we’ve looked at so far. In BASIC you can define your own functions, which is what these lines are doing. It’s important not to confuse BASIC’s user-defined functions with C functions. BASIC’s functions simply enable you to construct an expression in which the term in parentheses is substituted by a value that is passed into the function when it is used in another expression. For example, the code:

Would substitute the value 6 wherever X appears in the expression in line 20, so the expression in line 20 would effectively evaluate as:

-3*(6=1)-(6=3)-4*(6=6)-6*(6=4)-7*(6=9)-9*(6=7)+FNS(6)

Note that one function can make use of the value generated by another function. I’m sure this looks like gibberish to you right now. Basically the two functions FNR and FNS are used to convert a position on the board to its equivalent in a mirror image version of the board where the line of symmetry is vertical. So positions 1, 4, and 7 would become positions 3, 6, and 9 and vice versa, while positions 2, 5, and 8 would remain unchanged. Remember from the discussion in the previous post that we need this because we only store half the possible board configurations and we get the other half by creating mirror images of the ones we have stored.

When you look at the expression above remember that BASIC also uses a single = as both an assignment and an equality operator, and it works out which is which from context. So here, an expression in brackets like (6=1) is not trying to assign the value 1 to the value 6, it is checking to see if 6 is equal to 1. Clearly it isn’t, so this part of the expression will generate false. The next thing you need to know is that this dialect of BASIC represents false as 0, but it represents true as -1.

So let’s work through this expression bit by bit. 6 clearly doesn’t equal 1 so in the first past of the expression, -3*(6=1), 6=1 is going to evaluate as false or 0, and -3*0 is 0, so we end up with:

0-(6=3)-4*(6=6)-6*(6=4)-7*(6=9)-9*(6=7)+FNS(6)

Now let’s do 0-(6=3). 6 doesn’t equal 3 either, so that also evaluates to 0 and 0-0 is 0, so we get:

0-4*(6=6)-6*(6=4)-7*(6=9)-9*(6=7)+FNS(6)

In the next part of the expression, 0-4*(6=6), 6 does equal 6, so that gives us true or -1, and 4*-1 equals -4, and 0 – -4 gives us +4 because subtracting a negative number is like adding a positive number. Now we have:

4-6*(6=4)-7*(6=9)-9*(6=7)+FNS(6)

Now let’s calculate 4-6*(6=4). 6 doesn’t equal 4 so we get 6*0, which is 0 and 4-0 is 4:

 4-7*(6=9)-9*(6=7)+FNS(6)

For 4-7*(6=9), 6 doesn’t equal 9 so we get 7*0, which is 0 and 4-0 is 4:

 4-9*(6=7)+FNS(6)

Again 6 doesn’t equal 7 so we get 9*0, which is 0, and 4-0 is 4:

 4+FNS(6)

So at this point we have to evaluate FNS. If we pass the value 6 in, it evaluates as:

-6*(6=2 OR 6=5 OR 6=8)

Clearly 6 doesn’t equal any of those values, so the parenthesised expression will evaluate as false or 0, and -6*0 is 0, which is what will be returned by this function, so back in FNR we get:

4+0

which evaluates as 4. You should now be able to see that FNS returns the board position if that position is 2, 5, or 8 and it returns 0 if not. And FNR returns the mirror image equivalent of each position. So in our example, we passed it position 6 and it returned 4 which is the mirror image position.

Now let’s look at FNM. This is used to extract the second digit from a two digit move code. For example, if the move code was 15, indicating a capture from the top left square to the middle square then FNM would evaluate as:

15-INT(15/10)*10

So if we evaluate the part in parentheses first that gives us:

15-INT(1.5)*10

As you already know, the INT function in BASIC returns an integer by truncating any fractional part of its argument, so that gives us:

15-1*10

Next we multiply 1*10 to give us:

15-10

And finally we perform the subtraction, to give us 5, which is the second digit of the move code.

We’ll see how these functions get used a little later.

This line simply populates the string P$ with the three characters representing a black pawn (X), an empty board position (.) and a white pawn (0). This will be used later when the board is displayed.

These two sections of code read the configuration data into B and the move data into M respectively. We’ve already covered the format of the configuration and move data above.

If you happen to be following along with the original book, please note that the original listing had a couple of errors in the movement data table, which I have corrected in this version.

These two sections of code should be familiar to you. The first section repeatedly asks the player if they want instructions until they enter an answer beginning “Y” or “N”. LEFT$ is a BASIC function that returns a new string with the leftmost n characters of the string passed as an argument, so A$=LEFT$(A$, 1) has the effect of removing all but the first character of the string in A$.

The second section of code simply displays the instructions and then returns to the line following the input routine.

Hexapawn instructions

The variables X and Y store the computer’s move. X holds the index of the current configuration and Y holds the index of the current move within that configuration.

Lines 111 to 113 set the board to its initial configuration, with the black pawns lined up along the top row (or rank, as it’s known in Chess) and the white pawns lined up along the bottom.

Although BASIC doesn’t have functions in the sense that C does, you can define parts of the programme as subroutines that can be run multiple times from different parts of the code. The GOSUB command is used to run the subroutine starting at the given line. So GOSUB 1000 will begin executing code at line 1000 and continues until it encounters a return statement, like the one on line 1080. At this point it returns control to the line immediately following the GOSUB.

The subroutine at line 1000 displays the board. It sets up two nested loops. The first loop, between lines 1010 and 1060, iterates the rows on the board, while the second loop, between 1020 and 1040, iterates the columns.

This gives a coordinate in the form of (I, J). To convert this to an element number in the board array S, necessitates subtracting 1 from I and then multiplying this by 3, to give 0 for the first row, 3 for the second and 6 for the third. It is then simply a case of adding the value of J to this to get the correct index into the array S. This is achieved by this part of the expression: S((I-1)*3+J), which will yield either -1, 0, or 1 depending on the content of that square. The programmer now needs to display the relevant character from P$. To do this he uses the BASIC function MID$. This takes three arguments, the string, the starting position to extract a substring from and the number of characters to extract. So the programmer adds 2 to the value from the array to give the right character position in P$ and then uses this extract 1 character, which is then printed.

Hexapawn initial board

This next section of code gets the player’s move and validates it. Note that the INPUT statement on line 121 wants two values. In BASIC you can request multiple values separated by commas, but when the arguments are entered by the user they must also be separated by commas.

The first check on line 122 is to see if the player has entered integers between 1 and 9. If they enter a non-integer or an integer outside that range then the programme will display an “ILLEGAL CO-ORDINATES” message and the player will be asked for their move again, as shown below:

Hexapawn illegal coordinates

Next there is a series of six checks to make sure the player hasn’t tried to enter an illegal move:

  • Line 150 checks that the player isn’t trying to move to a square containing another white pawn
  • Line 160 checks that, if the player is not moving directly forward, the square they are moving to is occupied by a black pawn
  • Line 170 checks that the player is not trying to move sideways to the right or backwards
  • Line 180 checks that, if the player is moving a pawn directly forwards, the square it is moving to is currently unoccupied
  • Line 185 checks that the player is not moving further forward than they are allowed to
  • Line 186 checks for a special case illegal move that is not covered by the other rules (moving directly from the bottom left of the board to the top right).

If any of these conditions are found to be true, the programme displays an illegal move message and asks the player for a new move:

Hexapawn illegal move

If you think all that code sounds a little convoluted, you’d be right. This is a good example of how you can quickly tie yourself in knots when programming, especially if you sit down to code without thinking things through first. Here the programmer focused on all the things you can’t do when moving in Hexapawn (of which there are many), when a moment’s thought would have shown him that it’s actually far better to focus on what the player can do, like this:

hexapawn illegal move flowchart

If you spend a moment studying this flowchart you can see that this encompasses all the legal and illegal moves with just four decisions rather than six. By not thinking this through, not only did the original programmer tie himself up in knots, he also failed to test for every eventuality. Look at this game in progress:

Hexapawn illegal move demo 1

I am going to attempt to take the black pawn that is immediately to the left of my white pawn in the centre of the board. This should be an illegal move, right?

Hexapawn illegal move demo 2

Oops! Well all of us have, or will, make mistakes like this from time to time – that’s why it’s so important to test, test and test some more.

These three lines of code will be executed if a legal move is entered. Line 190 sets the square being moved from to empty, while line 200 sets the square being moved to as occupied by a white pawn. If the move is a capture, the black pawn that was previously there will, of course, be obliterated by this simple assignment statement.

Line 205 now reprints the board to show the result of the move.

Hexapawn player move

This section of code checks if white has won. Line 210 checks for a win by reaching the far side of the board by checking to see if any of those squares contain a white piece. If this is the case, the code branches to the player win routine at line 820, which we’ll examine a little later.

If not, we drop through to lines 220 to 223 which check to see if white has won by capturing all the back pieces. This works by simply examining all the squares on the board and jumping out of the loop as soon as a black pawn is found. If the end of the loop is reach then there are no black pawns remaining in the game, so control once again passes to the win routine.

Lines 230 to 340 check to see if black has any legal moves. This works by examining each square of the board. Line 240 checks to see if the square contains a black pawn. If it doesn’t the next square is examined. If it does line 250 checks to see if that pawn can move  directly forward (because the square in front of it is empty). If this is the case, there is at least one legal move available so control jumps out of the loop and picks up execution from line 350 which is the code to determine the computer player’s  move. Again, we’ll examine this a little later. Note that because the game ends as soon as a black pawn reaches the far side of the board, we don’t have to be concerned about an out of bounds error here, because we should never encounter a pawn in the final row within this loop. This does mean, of course, that the loop could have been made a little bit more efficient by only checking squares 1 to 6. Incidentally the same is true for the loop at line 220.

Line 260 uses FNR to check if the pawn is in the centre column. If it is, line 320 checks to see if there are available captures in the right or left columns. If it isn’t, meaning its on one of the outside columns, it can only capture pawns in the centre column. Line 270 checks to see if it is on the first row or second row. and then line 280 or 300 is executed to check if there is a possible capture to the centre square or centre bottom square respectively.

Again, if we reach the end of this loop, that means no legal moves were found and white has won, so line 340 goes to the win routine.

If none of the win conditions for white is satisfied then the computer next searches for the current board configuration. The outer loop, between 350 and 510 iterates through the 19 configurations stored in the array B. You’ll recall that we also need to check mirror images of each of the configurations, so the nested loops from 360 to 400 are used to build a temporary mirrored copy of the currently indexed configuration in the array T. Line 380 simply copies the relevant element of B into T, but the order of each row is reversed.

The loop between 410 and 430 now checks to see if the configuration of the actual board matches the currently indexed configuration in B. If this loop ends we have a match, so line 440 sets the variable R to 0, indicating that we are using a non-mirrored configuration so the computer’s move does not have to be mirrored.

If line 420 finds a mismatch, then control is passed to the loop between 460 and 480, which checks for a match with the mirrored configuration in T. If the end of this loop is reached, indicating we have a match, then R is set to 1 on line 490, so the computer knows its move is to be mirrored.

If line 470 finds a mismatch, it passes control to line 510 and the next configuration is checked. Theoretically the code in lines 511 to 530 should never be executed, because a match with at least one of the configurations should have been found by the time the loop ends. But as we saw earlier, there is a fault in the illegal move detection, so it is currently possible for these lines to be executed.

Line 511 might look like it’s missing a statement, but it’s actually a comment, the REM at the beginning of REMEMBER causes the line to be treated as a REM statement. Note that some BASIC interpreters would require you to put a space between REM and EMBER or this line would cause a syntax error.

This section of code is executed when the correct configuration is found. First X is set to the number of the configuration (i.e. the loop index at the point the loop ended). The loop between 550 and 570 now checks to see if there is at least one available move for this configuration. It’s possible that, if you play enough games, all the available moves for a configuration have been eliminated because they all resulted in a lost game. If at least one valid move is found by line 560, then execution is passed to the code that selects a move at line 600. If the loop finishes without a move being found then the computer resigns (it knows it can’t win from this point) and control passes to the player win code at line 820.

Hexapawn resign

If at least one available move has been found, the computer must now select a move from those available. Each configuration has up to four possible moves, so line 600 selects one of the move slots at random. If a move slot is unused (or if the move that used to be there has been deleted) then it will contain 0. Line 601 checks for this and returns to line 600 to pick another move slot if the chosen slot is empty.

Line 610 checks whether the move should be mirrored, because a mirror configuration was found. If the move should be reversed, control is passed to the alternative move routine on line 630. If not, control continues with the normal move routine on line 620. Line 620 displays the move the computer is about to make. Note that the BASIC function STR$ converts a numeric argument to a string. The expression INT(M(X/Y)/10) extracts the first digit from the move code. The second digit is extracted using the FNM function we examined earlier.

Lines 622 and 623 Now make the move by setting the square being moved from as empty and the square being moved to as holding a black pawn. Once again, if the move is a capture, the white pawn that previously occupied the square will be overwritten by the black pawn.

Lines 630 to 633 achieve the same thing for a mirrored configuration. The only difference is that FNR is used to mirror the move (e.g. the move 14 would be changed to 36).

Finally line 1000 calls the subroutine to display the board.

Hexapawn computer move

Now the programme checks for the three ways the computer could win:

  • By getting a pawn to the far side of the board (line 641)
  • By capturing all the white pawns (lines 650 to 680)
  • By blocking all legal moves for white (lines 690 to 810) – in this case a message is displayed on line 800 to prefix the computer’s “I WIN” message

Heaxapawn you can't move

These are functionally similar to the routines to check for a player win (between lines 210 and 340), which were discussed earlier.

Lines 820 to 840 are executed if the player wins a game. Line 830 deletes the last move the computer made that resulted in a lost game. This ensures that move will never be played from that configuration again. Line 840 increments the number of computer losses.

Hexapawn you win

If the computer has won, lines 870 and 880 are executed to display the “I WIN” message and increment the number of computer wins.

In both cases, lines 851 to 860 are then executed to display the number of games won by each player and then return to the code at line 100 that sets up a new game.

Hexapawn computer win

Note that the programmer has provided no way of exiting the game, other than hitting CTRL + C to terminate the programme. This is one of several improvements we will make in our version. The other things we’ll change are:

  • Fixing the error with the illegal move detection code
  • Displaying a better looking board using ASCII graphics
  • Implementing a menu system (which will include an exit function)
  • Providing save and load functionality for the configuration database
  • Creating and maintaining a database of played games, and providing a replay function for these

We’ll get started on this in the next post, in the meantime, here’s a flowchart showing the current functionality of the game:

hexapawn flow chart

Posted in BASIC, Programming Tutorials | Tagged , , | 2 Comments

OS X Games from the Ground Up: Hexapawn

In this next part of the series we’ll be sticking to the C language for one more game and building on the C fundamentals developed during construction of the first two games.

You can see an index of all the posts in this series: go to index.

If you are joining the series at this point, you should have some prior experience with C. In particular you should understand:

  • C variables and data types (including pointers)
  • Decision structures with if… then… else… and switch
  • Loops using while, do …. while and for
  • C functions (including passing arguments to a function and returning values from a function)
  • The main function
  • How to construct simple command line programmes

If you’re not comfortable with those topics then I recommend you have a look at the index and pick an earlier episode to begin with.

As with earlier parts of this series, we’ll be converting a game originally written in BASIC from the classic book Basic Computer Games.

The Hexapawn programme is a little more challenging than the two programmes we looked at previously: Buzzword and Acey Ducey. To begin with, it’s a two player game – and the second player is played by the computer. That means we will be developing some form of artificial intelligence for the first time in this series. Furthermore, while with the previous two games we’ve been content to simply reproduce the functionality of the original version, for this part of the series we will be enhancing the original. I’ll explain the planned enhancements in the next post.

First though, a little history. Hexapawn is a game developed by the mathematician Martin Gardner in a article he wrote for the March 1962 edition of Scientific American. This was reprinted in his book, The Unexpected Hanging and Other Mathematical Diversions. If you can get hold of a copy of the article or book, it’s a worthwhile read, as it explains how you can build a “matchbox computer” (built using a set of match boxes and some coloured beads), which will not only play the game but improve upon its play over time.

The game is played on a 3 x 3 board, using Chess pieces – three white pawns and three black pawns – which are lined up on opposite sides of the board.

Hexapawn initial position

As in Chess, one player plays white and the other black. They take turns making moves and white always moves first. A pawn may advance one square forward (i.e. towards the opposite side of the board to its starting position), provided the square in front of it is empty. For the Chess players among you, note that in Hexapawn, pawns may not advance two squares on their first move.

Hexapawn forward move

If one of the opposing player’s pawns is diagonally opposite one of your pawns, you can optionally move diagonally to capture that pawn. So from the position above, the white pawn in the centre square could be captured by either of the black pawns on the left or right column (known as a file in Chess). Captured pieces are removed from the board and take no further part in the game.

Hexapawn capture

There are three ways to win a game of Hexapawn. Let’s continue this game to see the first of them.

Hexapawn win by reaching opp side

Here white makes a mistake by not capturing the black pawn at the centre of the board, which allows the black pawn to advance to the white’s side of the board, thus winning the game. So the first way to win is by advancing one of your pawns to the opposite side of the board.

Let’s look at a second game, showing the second way to win:

Hexapawn no moves win

White wins this game because it is black’s turn to move next, but there are no legal moves black can make. So the second way to win is to force your opponent into a position where they have no legal moves.

And finally, here’s the third way to win:

Hexapawn win by capture

In this game, black manages to capture all the white pieces, thereby winning the game. So the third and final way of winning is to capture all your opponent’s pieces.

So you can see this is a very simple game and the rules can be learnt quite quickly. What makes this game interesting is that the matchbox computer (or in this case, our simulation of it) knows how to make a legal move from each possible position of the board, but it begins with no strategy. When you first play against it, it will make a lot of poor moves. But it learns from its mistakes, so the more games you play against it, the better it gets. Eventually it gets so good that it’s quite hard to beat.

So how does this work? Well the computer, which always plays black, can recognise 19 possible configurations of the board when it is its turn to play, and between 1 and 4 legal moves it can make for each of those positions. These are all shown here:

Hexapawn configurations

If you study these for a moment you might spot that there appear to be some valid configurations missing. In fact there are 37 possible configurations of the board when it is black’s turn to play. All of the configurations shown above (with the exception of the second one, which is the only symmetrical configuration), have mirror images. These are not included in the matchbox computer, since it is an easy matter to mirror each configuration horizontally to take care of those additional cases.

So how does this the matchbox computer use this information to play and to improve its game? Well let’s consider the second game we looked at earlier – the one which white won – and see how it works.

Hexapawn AI explanation 1

So at the start of the game, it is white’s turn to move and white chooses to move the leftmost pawn forward. The computer now searches its board configurations to find one that matches.

Hexapawn matching configuration

There are three possible legal moves from this position. The computer has no conception at the moment about which of these moves, if any, is preferable, so it simply choses one at random. In this case it choses to advance its middle pawn.

Hexapawn AI explanation 2

White responds by advancing its rightmost pawn, thus blocking black and winning the game. Whenever black loses a game, it removes the losing move from its store of configurations, so the configuration now looks like this:

Hexapawn revised configuration

Now that losing move will never be played when that configuration arises in future games. And each time the computer plays and loses, the database of configurations is refined by removing one more losing move.

So now that you understand the principles of the game, in the next post we’ll look at how the BASIC version works.

Posted in BASIC, Games, Programming Tutorials | Tagged , , , , , | 2 Comments

Not just kids’ stuff!

If you’re interested in all things code, you’ll almost certainly have heard of Scratch. It’s a Flash-based online programming environment in which you can make games and animations. The first version of Scratch was created in 2003 and the first public version of it appeared back in 2007 – it’s now at version 2.0. What makes Scratch different from most other programming environments is that it is entirely visual.

You build programmes by dragging sprites onto a virtual stage and then creating scripts for them by dragging blocks representing different functions and plugging them together (sort of like programming meets LEGO). The obvious advantage of creating scripts visually is the speed with which you can create and the ease of experimentation. A less obvious advantage, but one that makes Scratch ideal for kids learning to programme, is that, because typing is almost non-existent in Scratch, syntax errors are not something you have to worry about. In fact many structural errors are also eliminated because blocks will only fit with other blocks when it makes sense for them to do so.

Although you can create and import your own sprites, backdrops and sounds, Scratch also comes with a library of existing assets. This means you can be up and running with a new game or animation in a matter of minutes. Once a game or animation has been created, it can be shared with other members of the Scratch community. One of the most fun features of Scratch is that, if you find something you like, you can create a copy of it in your own account area and remix it to create something new – kind of like a scratch mix in music (hence the name).

At the time of writing, the Scratch community has more three million registered users, who have between them created almost six million projects. That makes Scratch an enormous success as a channel for self-expression through programming.

Given the ease with which projects can be created in Scratch, it would be too easy to dismiss it as child’s play. And although it is ideal for kids, and the vast majority of Scratch users are below the age of 20, there is also a thriving community of older Scratch users. Many of the projects being created, by young and old alike, are extremely sophisticated.

Having never used Scratch before, I decided to dip my toe in the water and see what could be done. I set myself some parameters for a game I could make. It should be something simple and easy to play, but also something that would have been non-trivial to programme from scratch in Flash using ActionScript (pardon the pun). It should also involve the complexities of a level progression system.

So I created the first levels of a potentially much longer game. Having long been a fan of Pop Cap’s Zuma games I started to think along the lines of a game with a similar mechanic. This led me to thinking that it would be quite fun to retain the rotating frog at the centre of the play field but, instead of it shooting balls, it should shoot out its tongue to catch different coloured bugs.

Gulp!

If you’d like to play the finished game, you can do so at this link:

http://scratch.mit.edu/projects/21625027/

My first task was to make the sprites and backdrops. Scratch has a nice editor with both a bitmap and vector mode. However, I chose to create my sprites and backdrops in Adobe Illustrator and then import the backdrops as PNG files and the sprites as SVG files, so they would be scalable. One minor problem with the SVG files was that, whatever changes I made to the format, they always lost the colour palette, so the sprites would be completely black, like silhouettes, when imported into Scratch. Fortunately, you can still select the individual shapes in the Scratch editor, so it is a fairly simple matter to recolour them there.

The next major hurdle was implementing the tongue mechanism for the frog. Because the tongue could shoot out to any point on the screen, I needed a sprite that could be scaled in only one direction. Unfortunately, although sprites in Scratch can be scaled, the width and height have to be scaled uniformly. The solution was to use Scratch’s pen feature. This allows a sprite to be used as a brush for drawing lines. By creating a single square portion of the tongue and then using this as a brush to repeatedly draw and erase a line between the frog’s body and the tip of the tongue (which is another sprite), I could create the illusion of a solid tongue shooting out to catch the bugs.

Here’s the tongue sprite and the scripts that control it:

Tongue sprite and scripts

Because most scripts in Scratch are attached to the sprite they operate on (some scripts can also be attached to the stage), communication between scripts for different sprites is effected by the use of messages. Messages are broadcast globally to all scripts, but scripts must be programmed to listen for a specific message. You can see two examples of this in the scripts above, one of which listens for the TongueOut message and the other of which listens for the stopDrawing message. Both these messages are broadcast by scripts attached to other objects.

The other tricky aspect was the level progression structure. With most languages, complex data like level data would be stored in structures or objects. With Scratch you have two forms of storage for data – variables and lists. A list in Scratch is like a single dimension untyped array in another language. This means the only real option for level data was to store it in a list. The image below shows the list with the level data for the first couple of levels in the game.

Scratch list with level data

Level data is structured such that, if the levels are numbered from 0, the data for level n can be found at n * 7 + offset, where offset is the position of the particular data you are after for that level. For example, the name of the backdrop for the level is at offset 1, the number of yellow bugs to be caught is at offset 2, the code for the types of bug to be found on the level is at offset 5 and so on. This leads to some quite convoluted expressions to access particular items of data, as can be seen in the fragment of the script below, where the expression Item 7 * current level + 2 of Levels is used to get the number of yellow bugs required to complete the level:

Scratch script showing level access method

So the reality is that it is possible to create some relatively sophisticated game mechanisms in Scratch, but sometimes an oblique approach is required to overcome the very features that make Scratch easy to use. Which is, of course, exactly as it should be, since to supply more powerful mechanisms like structures or multi-dimensional arrays would be to defeat Scratch’s purpose of introducing new people to programming in a fun way.

If you haven’t yet experimented with Scratch, I urge you to do so. It’s a lot of fun and, if you’re new to programming, a great way to build some skills.

Posted in Games, Scratch | Tagged , , | 2 Comments

OS X games from the ground up: solution to challenge project 1

You can see an index of all the posts in this series: go to index.

In the previous post I set you the challenge of writing a C version of the BASIC game Acey Ducey. If you managed to get a working programme, consider that a significant achievement – although the game is simple, the challenge is not.

In this post I’ll walk you through my solution. My solution will almost certainly differ from yours in several respects, especially as I’ll be using this solution to introduce some new concepts to you. However, it’s always the case with programming that there will be many different possible approaches to any problem – provided that your code works and is easy to understand and maintain, then your solution is valid.

Here’s the built programme:Acey Ducey.

Here are the project files for the finished solution:challenge project 1.

Here’s the code in full:

I’ve created four functions, other than main, for this project. You can see the declarations for these functions in lines 18 to 21. Remember that you have to declare all functions you create before you call them. We’ll look at the detail of each of these functions later in this post.

Note that I’ve also taken the parameters out of this version of main. Getting command line arguments in main is optional. It won’t hurt to leave them in, but removing them from the function definition lets other people viewing the code know that they’re not used.

The next thing you should note is that the main function itself does not contain much code.  As you begin to write more complex programmes, you should find this is generally the case. Most of your programme’s functionality will be put into functions and main‘s job will be to do a bit of initialisation and then call one or more of these functions.

I have main displaying the instructions on line 27, as that is done once, when the programme is first entered, initialising some variables on lines 29 and 30, which I’ll explain in a moment, seeding the random number generator on line 33, and then entering a loop, between lines 35 and 44, which plays the game as many times as the player wishes.

Note that the entire game logic is contained in a single function called runGame. When this function is called on line 37, it plays a single game, then returns when the game is over. It’s always a good idea to break your programme up into functions representing logical chunks. It makes it easier to read and maintain.

When a game has finished, we need to ask the player if they want to  play again. Unlike Buzzword, which looks for a single letter ‘y’, Acey Ducey wants the answer to be “yes”. If you implemented your solution to look for a single letter, that’s fine. In my solution, I show you how to do this when you want to scan for a complete word.

In line 29, we create a character array that we will use to store the raw input. In line 30 we create another character array that we will use to store the word that we’ll extract from that input.

In line 41 we use the fgets function, as we did with Buzzword, to get all the player’s input into the rawInput array. In line 42 we use the sscanf function, once again, to extract the bit we want from the player’s input and store it in the inputString array. Note the initial space in the format string and recall that this will get sscanf to ignore any white space that comes before the word. There are two differences from the way we used this function in Buzzword. The first is that I’ve used the conversion specifier %s instead of %c because we are now scanning for a full string rather than a single character. You’ll also note that the name of the variable, inputString, doesn’t have the reference operator, &, in front of it. Why is this?

You’ll remember that, when we pass a character variable as an argument, what actually gets passed is the value in that variable. But sscanf wants the address of the variable, not the value, because it is going to place a value at that address. When we pass an array as an argument, however, we don’t pass all the values in the array – we pass a pointer to the first element of the array. In this case we do want the variable’s value because that’s the address of the array. This is why we don’t use the reference operator, &, when we are using sscanf to read a string. This diagram shows the difference between an argument passed by value, e.g. a char variable, an argument passed by an explicit reference, e.g. a char variable with a reference operator, and an argument passed by implicit reference, e.g. a char array:

reference and value arguments

Note that, once sscanf finds the start of a word, it will only read as far as the first white space character, e.g. a space. So even if the player were to enter something like “yes I’d like to play again”,  after the sscanf function, only “yes” would be stored in inputString.

Now we need to check if the player has entered “yes”. This is done with the while command on line 44. You might have been expecting to see something like while (inputString == “yes”). Recall from earlier in this post that inputString is an array and when we use the name of an array as an argument, it is passed by reference, not value. In other words, we would be trying to compare a pointer to the first element of the array with a string literal. This just doesn’t make sense. Be aware that C will quite happily let you try to do this, but thankfully Xcode will warn you if you do.

Instead we use a new function, strncmp, which, now you’re getting used to C naming conventions, you have probably worked out is short for string compare. The strncmp function is part of the string library, so I’ve imported this on line 12. This function has three parameters. The first two are either pointers to strings or string literals to be compared (although obviously only one would ever be a string literal as there wouldn’t be much point in comparing two string literals). The third parameter is the maximum number of characters to compare. Note there is a related function, strcmp, which doesn’t have this third parameter. I’ve used strncmp and limited the characters to 3, so that a response like “yessir” or “yesssss” would also match.

The result returned by strncmp (or strcmp) is a negative number if string 1 is less than string 2, 0 if the strings are the same and a positive number if string 1 is greater than string 2. How is “greater than” or “less than” calculated in this context? Each character is actually represented by a number. The actual number used depends on the text encoding standard used by the system on which the machine runs. For the sake of this discussion, let’s assume the encoding standard is one called ASCII (American Standard Code for Information Interchange). In ASCII, the letter ‘a’ is represented by the number 97, ‘b’ by the number 98, ‘c’ by 99 and so on. The strncmp function compares the strings one character at a time until it finds a difference. For example, “cat” is less than “dog” because the value of the first character in “cat” is 99, but the value of the first character in “dog” is 100. Note though that “BIG” is actually less than “big” because the value of an upper case ‘B’ is 66, while the value of a lower case ‘b’ is 98.

Because strncmp returns a zero when the strings are equal, and a zero result for a condition is false, note that I have used the logical NOT, !, operator to negate the result returned by strncmp. This means the programme will loop again if the strings are equal and exit if not.

In that discussion we discovered that “BIG” is not the same as ‘big’ as far as strncmp is concerned. The same will go, for “yes”, “Yes” and “YES”, which are all considered to be different strings. Clearly though, the programme should accept all of them. We could do something like this:

But not only is that quite an unwieldy and error-prone statement, it also doesn’t cater for mixed case responses like “YEs” or “YeS”. You can easily work out that there are eight different combinations of upper and lower case letters we’d have to check for. A more elegant solution is to use a function to convert any upper case letters to lower case first, then we only have to check for a single response, “yes”.

This function is declared on line 21 and defined on lines 169 to 174. Here’s what it looks like:

Note that this function has a single parameter, which is the character array to be converted. Because the function modifies the character array directly, it doesn’t return a value, so it’s return type is void.

Inside the function, we loop through all the characters in the string. Previously, when we have used a for loop, you’ve seen loop conditions that look something like i  < numberOfPhrases, meaning that the loop continues while i is less than the value of the variable numberOfPhrases, but here our condition is string[i]. What’s going on here?

Well, recall that, when evaluating a condition, zero is taken as false and a non-zero number is taken as true. In this loop, each time we get to the condition, string[i] gets the value of the character at position i. Let’s assume that our string contains the text “yes”. The first time through the loop i is equal to 0, so we will get the character at position 0, ‘y’, which has the value 121. That’s non-zero so we repeat the loop. Next time through, i is 1, and position 1 has the character ‘e’ with the value 101, so again we repeat the loop. Third time through i is 2, and position 2 has the character ‘s’, which has a value of 115, so once again we go through the loop. On the next iteration i is 3. Wait a moment, you might be saying, there is no character at position 3. But remember, all strings are terminated with the null character, ‘\0’, which happens to have a value of 0. So at this point the loop ends. This is a convenient facet of strings – every character in a string is guaranteed to have a non-zero value, except for the terminating null character at the end of the string. Note though that this only works because the condition is always tested at the top of a for loop, so execution ends as soon as the null character is found. If you tried to do the same with a do … while loop, it wouldn’t work, because the character would already have been processed by the time you checked it.

Within the for loop we make use of another C library function, tolower, which returns the lower case equivalent of the character passed as an argument. So ‘y’ and ‘Y’ would both be returned as ‘y’. If you pass a non-alphabetic character into tolower, e.g. ‘%’, that character will be returned unchanged. The tolower function is part of the ctype library, which is included on line 13.

We call this function on line 43, just before the loop condition is tested, like this:

Note that this function is only called once, so you might be wondering why I bothered to use a function at all. Why not just include the code to convert to lower case directly at this point? Firstly, as I mentioned before, it’s always a good idea to split your programme up into logical pieces, and for each of those pieces to live in its own function. Secondly, converting a string to lower case is something I’m likely to do again in future programmes. If I have that functionality nicely wrapped up in a function, it’s much easier for me to reuse it again in other programmes.

If the player choses not to continue the game, by entering a value other than “yes”, we display a farewell message and end the programme with an error code of 0, indicating success.

So that’s main‘s part in all this taken care of – now let’s look at the function runGame, which is responsible for the main game logic.

I begin by declaring and initialising a couple of variables, a char array called rawInput, which will be used to capture the player’s input when they bet, an int called bet, which will hold the numeric value of the bet and an unsigned int called money, which holds the amount of money remaining to the player.

You might have noticed that we also have a char array called rawInput in the main function, but remember, from the discussion on variable scope in an earlier post, that variables declared within functions are local to those functions. As far as C is concerned, the rawInput in main and the rawInput in runGame are two entirely different variables.

Most of the rest of the function is contained in a while loop from line 60 to 136. This checks that the player still has money remaining and continues picking cards and taking bets while they do have money. Once the player is out of money an ‘out of cash’ message is displayed, on line 137 and the function ends (and returns to main).

Each time through this loop, the first thing to do is show the player how much money they have left.

Next we pick the first card, which is stored in the unsigned integer variable called cardA:

Note that I’ve created another function for picking a card, called pickCard. This is because we need to pick three different cards each time through the game, so it make sense to have this functionality wrapped up in a function.

The pickCard function, which starts on line 142, looks like this:

This code should look very familiar to you by now. We are picking at random from a range of 13 cards, but starting them with a value of 2, so the actual range will be 2 to 14, with 11 representing a Jack, 12 a Queen, 13 a King and 14 an Ace (Aces are high in this game). Now we return to the runGame function:

This next section of code might look a little odd, so let’s look at it in detail. We start by initialising the second card, cardB to be the same as the first card, cardA. What we now want to do is replace the current cardB with randomly picked cards until cardA and cardB are different. This is achieved by the loop between line 69 and line 71. Note that when you have a single statement in a loop like this, (or between the braces in an if or if … else statement), you can optionally omit the braces and do something like this:

In my opinion, that is not very readable code, so I always use braces, even if the braces contain only a single statement. It’s up to you whether you chose to omit braces for single statements, but whatever you decide, be consistent.

Once cardA and cardB are different, we then have to get them into the correct order, so that cardA is the lower of the two. This is achieved with the if statement from lines 74 to 79. If cardB is the lower card, this simply swaps the two cards over. Note that we have to use a third temporary variable here, called tmp, to preserve the value of cardA while we copy cardB to cardA.

The next bit of code converts the card values into card names. Again, I have created a function to do this, because the same thing has to be done for three cards for each bet. Note that I create two arrays to hold the card names in lines 82 and 83 and these are passed to the getCardName function in lines 84 and 85, along with the value of each card. The function is declared on line 20 and defined on lines 148 to 166.

The function takes two parameters  – the first is the numeric value of the card, the second is a pointer to the character array where the name of the card is to be stored. This should have space for at least six characters. Why six, when the longest card name, “Queen” only has five? Remember that all strings are terminated with a null character, ‘\0’, so we need to allow space for that as well.

If the card value is less than 11, i.e. one of the cards from two to ten, the number of the card will also be its name. To get this into our cardName array, on line 151 we use  a variant on the printf function called sprintf. The sprintf function is to the printf function, what the sscanf function is to the scanf function. In other words, instead of sending its output to stdout, like printf does, it sends it to a string. A pointer to the destination string is the first parameter, and then the remaining parameters work in exactly the same way as the parameters in printf. You probably won’t be surprised to learn that sprintf is part of the stdio library.

The switch command that follows else on line 152 is new to you.  Switch can often be used as a more compact alternative to a long chain of if … else if … else statements. What switch does is follow one of several paths depending on the value of the expression in parentheses. In this case the expression we are checking is simply the value of card. The different paths are enclosed within a pair of braces, and each path begins with the keyword case, followed by a value and then a colon. So you can see from lines 153, 156, 159, and 162 that we are checking for the cases where the value of card is  11, 12, 13, and 14, i.e. the values of all the picture cards and the Ace. You may also have a final path called default: (note this doesn’t have the word case in front of it). This path will be selected for any value not already matched by one of the other cases. For this function though, we don’t need the default case.

In each case we call another function that’s new to you, called strcpy. It should take too much effort to work out that this is short for string copy. This function is defined in the string library and takes two parameters, a string pointer and then either another string pointer or a string literal. The function copies the contents of string 2 into string 1. You must always take care with this function that there is sufficient room in string 1 for the string you are trying to copy, if not you could overwrite other important values in memory and cause your programme to stop working. We use this function to copy the relevant card name into the cardName char array.

You’ll notice beneath each of these statements there is another unfamiliar command, break. The break command causes the switch statement to end. It’s needed because, without it, control would fall through to the cases following the current one. In other words, without the break statements, every card would end up being called “Ace” because regardless of which case was initially executed, all the subsequent cases would also be executed. Strictly speaking, the final break statement on line 164 is not needed, because the switch statement ends at this point anyway. However, it’s always a good idea to include it, because you may add more cases at a later date and forget to put the break statement back in. This diagram should help clarify how the switch statement works:

switch command

Now, you might be wondering why this function had a second parameter – an array pointer for the character array where the string is to be stored. Why not simply return a string? Wouldn’t it have been better if our function looked something like this:

And then in runGame, we could get the cardNames like this:

To answer this question, we need to take a more detailed look at how the stack works. You’ll remember from an earlier post that the stack is an area of memory where variables are stored. So let’s consider what happens as we create variables in this programme. The first function to be run is main. In main we declare two variables, rawInput and inputString. After these variables have been declared, the stack looks like this:

stack explanation 1

A little later we call runGame from main and runGame begins declaring its local variables. By the time we are about to call getCardName, the stack looks like this:

stack explanation 2

Note that main‘s variables are still there, because main is still running. Even though we have two char arrays called rawInput in the stack, they are local variables belonging to different functions, so C considers them to be different. Any reference to rawInput in runGame will be taken to be a reference to runGame‘s variable, not main‘s.

You might be able to see now why this part of the memory is called the stack, because variables are stacked in order as they are created.

So now we call our new version of getCardName and it declares its local variable, which is a char array called cardName. The stack now looks like this:

stack explanation 3

So far, so good. At this point getCardName does its job of putting the relevant name into it’s local variable cardName. Then it returns a pointer to cardName. This brings the getCardName function to an end, so C tidies up by removing any local variables owned by getCardName. So now control has returned to the runGame function, which now tries to copy the string pointed to by the returned pointer into cardAName. But guess what, that string was stored in cardName, which has just been deleted by C. So the return value points to a variable that no longer exists:

stack explanation 4

Now, what can cause further complications with this sort of erroneous programming, is that, often C will mark the memory occupied by cardName as being free for reuse, but it won’t actually erase what was there. So sometimes, especially in cases like this where you are using the returned pointer straight away, the data it points to will still be intact, even though, as far as C is concerned, the variable no longer exists. What this means is that the programme could appear to work, but when you run it on a different machine, or a different operating system, or compile it with a different compiler, it can then suddenly fail for no apparent reason. But this will most likely be because, in the different environment, the data has been overwritten.

This is why you should never attempt to return pointers to local variables. Fortunately Xcode will always warn you if you try to do this, but it’s worth understanding why it’s a bad idea. As you will discover in future posts, pointers are a very powerful feature of C. But, as a certain superhero was once told, “with great power comes great responsibility”. That’s certainly true of pointers. They can be dangerous if not used with care. The issue we’ve just been looking at is known as a “dangling pointer” and is one of many ways in which pointers can get you into trouble. We’ll look at some others in later posts.

Compare this to our original version of the getCardName function, where we ask the calling function, i.e. runGame, to provide its own location for the string to be saved. Think of it like taking your own sturdy bags to the shop instead of relying on the flimsy paper bags the shop provides – the paper bag might get your shopping back safe, but it could just as easily break and you’ll lose your groceries. We know our version of sturdy bags, the variables created in runGame, will exist before the getCardName function is called, will exist while the getCardName function is running and will still exist when the getCardName function returns. It’s a much safer strategy. So now we continue with the runGame function:

The next thing we do is display the card names to the player. Now, the only thing I ever use the card names for is to display them to the player like this and each card only ever gets displayed once. So you might be wondering why I didn’t just write a function that displays the appropriate card name when it’s passed the card value, something like this:

While that’s a functionally valid solution, there are two reasons why I chose not to do it that way. The first has to do with reusability. It’s highly likely that I will create more card games in the future. In other card games I create I might not simply want to display the card name. I might, for example, want to combine the name of the card with another string containing the suit. A generalised function that returns the card name as a string is much more likely to be reusable in a future programme than one that displays the card name directly. As you will have already discovered, programming is an intensive and time consuming task. It’s often worth spending a bit more time to make your code reusable today, if it saves you twice as much time not having to reinvent the wheel tomorrow.

The second reason relates to how the different parts of your programme work together. You might think of this programme as having two fundamental parts. One part is the model – this is the data, such as the card values and the bet amount and the logic to deal with that data. The second part is the interface – this is the code to display information to the player and to get the player’s input. Best practice is to separate those two parts as much as you possibly can, and the more complex your programme is, the more important it is to maintain that separation. Obviously they can’t be completely separate – at some point your model needs to talk to your interface and vice versa, but you should try to make those communication points between the two as well-defined and as minimal as possible.

Why bother to do that? Well, at the moment you are creating programmes that run in a command line interface while you develop your skills. At some point in the near future your skills will be sufficient for you to progress to developing programmes that have a graphical user interface. At that point you might think “you know, wouldn’t it be great to have a version of that Acey Ducey programme that used images of the cards rather than just text.” Now if the code for the model and the code for the interface are horribly tangled up you may well just decide to give up and start developing the graphical version of your programme from scratch. But if you’ve been careful to maintain as much separation as possible between the model and the interface, it’s probably not going to be too difficult to unpick the text interface code and replace it with the code for the graphical interface. All being well, you will have very little additional work to do on the model code. This is an important concept in programming and we’ll be coming back to it again in future posts.

Now we’ve displayed the first two cards to the player, it’s time to get the player’s bet. There will be a number of checks we need to make on the player’s input to validate it, so we need a way of knowing when we have valid input. I’m going to track this with a type of variable you’ve not seen yet. It has the type bool, which is short for Boolean. Boolean variables are used in Boolean logic, which was invented by the 19th Century mathematician George Boole. You’ve already seen Boolean logic at work in the conditions we’ve used in if, while and for statements. Expressions in Boolean logic always evaluate as either true or false. You’ve seen that C considers zero to be false and any non-zero value to be true, however, you can also store these values in a bool variable.

Because bool is a late addition to the C language, you need to import the standard bool library, stdbool, if you want to make use of it. I import this on line 15. As well as defining the bool type, this also defines the values true and false. You can see an example of this on line 91 where I declare the bool variable validBet and initialise it to false.

Lines 94 to 111 are a loop that repeats while the bet is not valid – note that because I am testing for a false condition, I use the logical NOT operator, !.

Notice that I am combining the fgets statement that’s familiar to you, with the code we previously used to get a number from a command line argument, using the strtol function. There are three possible outcomes from this function:

  1. The user entered either a non-numeric value or a negative number. We test for this on line 104 and display an error message if this is the case.
  2. The user tried to bet more money then they have available. We test for this on line 106 and display an error message, including a reminder of the available amount, if this is the case.
  3. The user entered a valid bet. If this is the case, we set validBet to true and the loop exits.

Once we have the player’s bet, it will either be zero, indicating they don’t want to bet, or the amount they want to wager. We test for this on line 114, and if the bet is zero, we just display the “chicken” message and return to the top of the loop for the next round.

If the player has chosen to bet, we pick a third card and display its name. This code, between lines 118 and 125, should be familiar to you now, as it is almost very similar to the code for the first two cards. Finally, in lines 128 to 134, we check if the player has won or lost, display an appropriate message and either add or deduct the amount of the bet.

Lines 130 and 133 contain two operators you’ve not seen yet. This line:

is equivalent to this:

Assigning a variable with the value of itself added to another value or variable is something you will do a lot, so over time this operator will save you a fair few keystrokes. It’s also less error prone because you only have to type the destination variable once. As you will have worked out by now:

is equivalent to:

These are known as compound assignment operators. You can also use *=, /= and %= for multiplication, division and modulus operations respectively.

Well that’s been a lot to take in for one post, but hopefully it’s opened your eyes to some of the considerations you need to make when creating games in C. In the next post in this series we’ll begin developing a new game that will introduce you to some more advanced C skills. If you’d like a challenge in the meantime, see if you can use what you’ve learned in this post to make some improvements to your own version of Acey Ducey.

Posted in Games, Programming Tutorials | Tagged , , , , , | Leave a comment

OS X games from the ground up: challenge project 1

You can see an index of all the posts in this series: go to index.

Challenge projects are a bit more involved than the challenges you’ve seen previously, as they involve creating an entire game using the skills you’ve acquired so far. In this first challenge project you will convert the BASIC game, Acey Ducey to a Command Line Tool written in C. If you want the original source code, here it is: aceyducy.bas. It’s all explained in this post however.

Here’s the original BASIC listing in full:

Let’s break this down, bit by bit, starting with lines 10 to 80.

This section shouldn’t present any real challenge to you, it simply displays instructions to the user. You can keep your text left-aligned, so don’t worry about the TAB instructions in lines 10 and 20. Remember that a PRINT instruction on its own, e.g. line 21, simply moves the print position to the next line. Here’s how that looks:

Acey Ducey instructions

Now for lines 1oo and 110.

These lines initialise two variables. N holds the amount of the player’s bet, while Q holds the amount of money the player has available. Remember that c doesn’t have the single letter variable name restriction that BASIC does, so you can give your variables more self-explanatory names.

This short section of code simply displays the amount of money the player has remaining before moving on to the code at 260 (which is the code for displaying the cards). It looks like this:

Acey Ducey dollars remaining

This section picks two cards at random and displays them to the player. Lines 270 and 300 are used to pick the cards and store them in the variables A and B. Notice that the range for the random numbers is 2 to 14, with 2 to 10 being the number cards, 11 for a Jack, 12 for a Queen, 13 for a King and 14 for an Ace (Aces are high in this game).

The code in lines 280 to 290 and 310 to 320 ensures the random number is constrained within the range 2 to 14. You should be able to write your random number generation in such a way that this additional code is unnecessary.

Line 330 checks to see if the first card has the same value or a higher value than the second card. If it does, control is returned to line 270 so two new cards can be chosen.

Lines 350 to 390 go to an appropriate PRINT command based on the value of the card. Cards with a value below 11 are printed as the numbers 2 to 10 in line 400. Lines 420, 440, 460 and 480 display the word “JACK”, “QUEEN”, “KING” or “ACE” respectively. Once the card value has been displayed, control is passed to line 500.

Note that lines 500 to 630 are almost identical to lines 350 to 480 except they use the card in variable B rather than the card in variable A. The limitations of this early dialect of BASIC often forced programmers into using this sort of brute force approach to a problem. You should be able to think of a more elegant and efficient way of doing this. Hint: could a function help here? Here’s what this code displays:

Acey Ducey cards

Line 660 displays a prompt and then gets the amount of the player’s bet into the variable M. Hint: You can do this in a couple of ways. You can use the input technique you have already seen to get the player’s bet, but you will have to use a different conversion specifier. Alternatively, is there a function you used when interpreting command line arguments that might be useful here?

In line 670 the amount of the player’s bet is checked to see if it is anything other than zero. If it is zero, then a suitably derisory response is displayed on line 675. Control is then returned to the code that displays the cards on line 260.

Acey Ducey Chicken

If the player has entered something other than zero, control is passed to line 680, which checks that the player hasn’t tried to bet more money than they have available.

If the player has bet too much they are warned in line 690 and reminded of the amount remaining in line 700. Control is then returned to line 650, where the player is asked to enter a new bet.

Acey Ducey bet too much

Line 730 chooses the third card. This line and the lines that follow it are identical to the routines for the other two cards, except that the card is stored in the variable C. Again, you should be looking for ways you can achieve this more efficiently.

Line 910 checks if the third card is higher than the first card. If it is, it moves on to the next check in 930. If it is isn’t, control is passed to the lose routine on 970.

Line 930 checks if the third card is equal to or higher than the second card. If it is then control is passed to the lose routine on 970.

If the third card is between the first and second cards then line 950 displays a win message. Control is then passed back to line 210, which adds the player’s winnings to their total.

Line 970 is the start of the lose routine. It displays a lose message.  Line 980 then checks that the amount to be deducted is less than the player’s remaining money. If it is then control passes back to line 240, which deducts the loss. If it isn’t then a broke message is shown on line 1010.

Line 1020 prompts the player to indicate if they want to play again. The answer is checked in line 1030, and if the player answered “YES”, control is passed back to line 110, which resets the player’s cash to the starting amount.

If the player answers anything other than “YES”, a farewell message is displayed on line 1040 and the programme ends.

Reading a word rather than a single character from the player’s input is a bit trickier. By all means try and find a solution (and I’ll show you one in the next post), but it’s fine if you just check for ‘y’ instead of ‘YES’.

Acey Ducey end game

The last few lines you haven’t yet seen are these. Line 210 adds the amount of the player’s bet to their total and then control returns to line 120, which prints the remaining amount of money. Correspondingly, line 240 subtracts the amount of the player’s bet from their total before passing control back to line 120.

Here’s a flowchart for Acey Ducey:

Acey Ducey flowchart

While you are working on your solution, you might find it useful to refer to the documentation for the commands and functions you are using.  While you are in Xcode, make sure the Utilities pane (that’s the one on the right) is visible and select the second icon at the top – the one that has two wavy lines. This is the Quick Help inspector. If you then click on a command or function in the main window, you’ll see help for it here:

Xcode quick help

If you need further help, click the OS X Man Pages link. This will open the relevant manual page in a new window.

Good luck with the challenge. An example solution will be explained in the next post.

 

Posted in Games, Programming Tutorials | Tagged , , , , , | Leave a comment

OS X games from the ground up: user input

You can see an index of all the posts in this series: go to index.

If you are starting from this point, or need a fresh set of files, here are the starter files from the end of the previous post: loops.

In the previous post you used two types of loop, a while loop and a for loop, to display the number of phrases requested by the user. I also left you with the challenge of using a do … while loop to achieve the same thing. Here’s my solution:

The changed code is on lines 50 to 55. Your solution may be slightly different to this, but as long as it creates the same output as the previous versions of the loop, that’s fine.

The main thing to watch out for with do … while loops is that the body of the loop will always be executed at least once, regardless of the condition. For example, if, for some reason, numberOfPhrases was 0 when this loop was first reached,  the body of the loop would be executed once, printing a single phrase. Only at that point would the condition be checked and no further iterations of the loop would occur. Contrast this to the while loop, where the condition would have been checked as soon as the loop was reached, and the body of the loop would never have been executed.

The other thing to watch out for with do … while loops is that you remember to put the semicolon after the closing parenthesis for the condition.

OK after all that hard work with command line arguments, we are now going to dispense with them. Instead of the user entering the number of phrases on the command line, we are now going to replicate the behaviour of the original BASIC programme and get the user to press a key at the end of each phrase. If they enter Y they will get another phrase. If they enter anything else the programme will end.

Let’s have a quick look at the BASIC programme to see how this is achieved there.

Lines 110 to 130 should be familiar to you, as you examined them in an earlier post. These are the lines that generate and display a random phrase.

Line 150 has two statements. The first statement, INPUT Y$, displays a question mark, then waits for the user to type in a response and hit enter. The response is then saved in the specified string variable (Y$).

The next statement on this line should look a little familiar to you as it is BASIC’s version of an IF command. The condition is Y$=”Y”, in other words it checks to see if the user has entered the single letter Y. Notice that BASIC uses a single = sign for both assignment and equivalence operations. It can distinguish between the two based on context.

The part of the IF statement following the keyword THEN is equivalent to what’s in the braces in the C if statement. In this case it’s just a single number, 110. In BASIC, when a single number is used in this context, it means continue execution from this line. So, if the condition is true (i.e. the user has entered Y), control will return to the lines that display a random phrase.

Like C, BASIC also has an ELSE command for indicating code that should be run if the condition is not true. The code that follows this is the equivalent of the code that would be placed within the braces following the C else command. The statement to be executed here is GOTO 999. As you might have already guessed, this causes execution to continue from line 999.

The first statement in line 999 displays a final message to the user. In the second statement, END is BASIC’s equivalent of C’s exit function – it cause programme execution to end.

Make the following changes to the programme:

Quite a lot’s changed here. We no longer import the errno library, which used to come immediately after line 11. We’ve also lost the function declaration that used to come just after that. We’ve lost all of the code to get the command line argument and validate it, which used to be between lines 14 and 15. There’s new or changed code from lines 26 to 38. And we’ve lost the function that used to come after line 41.

As we’re no longer going to be reading arguments on the command line you can, if you wish, edit the scheme, select the argument you set up previously and click the button to remove it, then click OK.

Now let’s have a look at what’s happening in the new code. On line 26 we set up a char variable called input. This will be used to hold the character that is entered by the user. We’ve still got the line that displays a random phrase, on line 30 and it’s still within a do … while loop, from line 29 to line 36. Instead of checking a counter, as it did before, this condition checks to see whether input holds the letter ‘y’, which indicates that the user wants to see another phrase. If it doesn’t hold ‘y’, we display a farewell message on line 38 before ending the programme on line 40. This should all be familiar to you. But how do we get the letter the user enters and put it into input?

That’s taken care of by the scanf function in line 33, which is short for scan formatted and is part of the standard input-output library, stdio. If you think scanf looks mighty similar to printf, you’d be right. While printf sends data to the standard output, scanf reads data from the standard input, which in this case is the keyboard. Like printf, scanf takes a format string with conversion specifiers, and then one further parameter to match each conversion specifier. Our string is very simple, it’s just “%c”, which means read a single character into the variable I give you. This is followed by the name of the variable, input.

But what’s that & symbol doing in front of the variable name? When you use a variable name on its own, as you do in a printf command, C interprets this as meaning you want the value of the variable. But scanf doesn’t care what the current value of the variable is, it wants to put a new value there – the one that it reads from the standard input. So instead of using the variable name on its own, we prefix it with the reference operator, &. When C sees a variable name prefixed with &, instead of providing the value of the variable, it provides the variable’s address in memory. The scanf function then stores the value it reads at this address, which is equivalent to setting the variable to that value.

Let’s try it out. I’ve added a temporary printf command on line 34 so you can see what character has been captured by scanf. Before you run the programme, move your mouse over the top edge of debug pane until it turns into a double headed arrow. Now click and drag upwards to enlarge the pane. Now look for this icon at the bottom right of the debug pane:

Xcode Variables View toggle

If it’s blue not grey, click it once. This hides the variables view, which is a part of the debug pane (the left side) that you’ve not explored yet.

We’ve done all this to give a bit more room to the console. This is the right side of the pane where your programme output appears.

Now try building and running the programme. You should see the instructions, your first phrase and then a prompt: ?. The programme has now paused, waiting for you to enter some characters. First though, as we’re running within Xcode, you need to make sure the console has focus. Click once to the right of the ? in the console. You should now see a flashing cursor. If the programme is ever waiting for input and you can’t see a flashing cursor, just click once in the console to give it focus.

Buzzword input 1

OK let’s try a negative response first. Type n and then hit the enter key. You should see the programme display the farewell phrase and then end.

Buzzword input 2

Great! That’s exactly what we were expecting. Try running again, and this time let’s try a positive response. Type y and hit enter. You’ll see something like this:

Buzzword input 3

Woah! What happened there? The programme displayed another phrase as it should, but then, instead of stopping and waiting for your input again, it flaked out and ended. To understand why this was, we need to look a bit closer at what scanf does. When you type, the console in Xcode collects the characters until you press enter. Then it sends all the characters it has gathered, including the enter (which is interpreted as a newline, \n) to standard input or stdin as it’s referred to in c.

At this point your scanf function starts processing it. The scanf function takes characters from stdin and tries to interpret them based on the conversion specifiers we’ve given it. In this case we’ve given it just one conversion specifier, which is %c for a character. The first character it encounters is the y we typed. So scanf dutifully copies the y character into our variable called input and let’s the rest of your programme go about its business. So we display the entered character on line 34, then on line 36 we check to see if it is equal to ‘y’, which it is, and we return to the top of the loop on line 29. In the loop on line 30 we display another random phrase, then on line 32 we display another prompt.

At this point you might expect that the scanf function on line 33 would hang around and wait for you to enter something else. But it doesn’t. Why? Because when it looks at stdin, it finds that stdin is not empty – it still has the \n character we entered last time when we hit the enter key. So it dutifully copies the \n character to our variable, input, and control passes to the next line. This time when we get to our loop condition, input contains \n, which is not equal to ‘y’, so our programme ends.

This is not what we want at all. We want our programme to ignore the \n characters and just process the letters we type. Well there is a solution. Change line 33 so that there is a single space between the opening quote and %c, like this:

What this does is tell scanf, “look, I’m just not interested in any white space that comes before other characters. So if you find any spaces, tabs, newlines or other characters of that ilk, just throw them away. Thanks.”

Build and run your programme again. This time, when you enter y, you’ll get another phrase and the programme will wait for you to enter another character.

Hurrah, so we’ve solved the problem right? Well, we’ve solved a problem. But all is still not well in scanf land. To see what I mean, try running the programme again and enter yes instead of y. You should see something like this:

Buzzword input 4

Do you see what happened here? The first time through, scanf reads the y into input, but leaves the e and the s in stdin. The next time through, scanf sees that stdin isn’t empty and reads the e into input. Because e does not equal ‘y’, the programme ends.

So what can we do about this? Well the fundamental challenge with scanf is that it’s a messy eater – it takes what it wants from stdin and leaves the half-chewed remains on the plate. What we really need is a way to get everything from stdin, so we start with it empty each time. Change your code to this:

The changes are from line 26 to 35.

In line 26 we’ve added another variable, a character array called rawInput, with 80 elements. This is where we will store everything the user types.

Line 34 introduces a new function, fgets, which is part of the stdio library. The fgets function reads a stream of characters from a file stream and stores them in a character array. You haven’t yet been introduced to the concept of a file stream, but for now, all you need to know is that stdin is a type of file stream.

The fgets function takes three parameters. The first is the character array where fgets should store the characters it reads. We’ve given it the name of the array we set up in line 26, rawInput.

The second is the maximum number of characters that fgets should read. It needs to know this, because otherwise it could potentially write more characters than there is space for in the array. Here we’ve used sizeof(rawInput) to get that number. Although sizeof() looks like a function, it’s actually an operator. It returns the size of its operand in bytes. So here it will return 80, which is the size of the character array rawInput. You might be wondering why I didn’t just type 80 – after all we have only to look at line 26 to see that’s what size the array is. The reason for not doing so, is that at a later point I might decided to change the size of this array. If I do that, I have to remember to change the number, not just in the initialiser in line 26, but also here in the fgets function call. This is bad practice, because it’s too easy to forget to change both of them. By using sizeof, I know that the value returned is always going to be correct, no matter how often I change the size of the array in line 26.

The third parameter is the file stream to read from. In our case we want to read from stdin.

This function will now read the characters you type up to and including enter (\n) or the first 80 characters you type, whichever comes sooner. So what would happen to any characters over 80? Well, they’d stay in stdin and be read next time round. Note that this does mean a really determined user could still cause the programme to terminate by typing a very long phrase over 80 characters, but this will be more than enough to look after the users who simply type yes or yep or yeah or yea instead of y. Ok so we’ve now got the characters the user has entered, but how do we determine if the first of these characters is y?

You’ll notice on line 35 that we have something that looks remarkably similar to our scanf function. Whereas scanf reads from stdin, sscanf, which is also part of stdio, reads from a string – that’s what the extra s at the beginning stands for. It takes at least three parameters. The first is the string to be processed. We’ve given it the name of our character array, rawInput here. The remaining parameters are the same as the parameters of scanf – a string literal containing the conversion specifiers, and then, for each conversion specifier, the address of a variable where the output is to be stored.

You might be wondering why I’ve even bothered to use sscanf. Why not just get the first character using rawInput[0]? The answer is white space once again. We can’t guarantee that the user hasn’t put spaces or tabs before typing y. We can use the same trick with sscanf, as we did with scanf – adding a single space before the conversion specifier %c to force sscanf to ignore any white space.

OK try building and running your programme again. You should find that entering y, yes or yellow-bellied son of a gun all result in you getting another phrase for your money.

Since our input routine now works as we need it to, you can now remove line 36, which shows the character entered. Are we done? Almost. There’s just one more nicety we have to take care of.  If you try running your programme and entering Y (an upper case y) – it’ll dump you straight out on your ass. We need it to serve up another phrase regardless of whether the y is upper or lower case. You should be able to make a simple modification to line 37 to take care of this. See if you can work this out for yourself, then click below to see the solution.

Congratulations. You’ve completed your first programme in C. Here are the final files: user input. And here is a built copy of the final programme: Buzzword

You’ve now got enough tools in your belt to be able to write simple command line games. To prove it, in the next post I’ll give you a challenge to do exactly that.

Posted in Games, Programming Tutorials | Tagged , , , , , | 1 Comment