The document describes the evolution of a number guessing game from a procedural program to one using object-oriented principles. It starts with the original program written in a BASIC-like language, then converts it to JavaScript. It discusses improving the code by adding whitespace, renaming variables for clarity, and refactoring the program into discrete functions. It later introduces testing the game logic separately from the user interface. Finally, it presents the game design using higher-order functions for flexibility and composability over a static structure.
2. Aslam Khan
mail at aslam.khan@factor10.com
blog at http://aslamkhan.net
tweet at @aslamkhn
skype at aslmkhn
3. One of the first games that I wrote
10 I = INT(10 * RND(1))
20 PRINT “GUESS MY NUMBER:”
30 INPUT J
40 IF INT(J) != I THEN GOTO 20
50 PRINT “YOU GOT IT!”
60 PRINT “PLAY AGAIN (Y/N)?”
70 INPUT Y
80 IF Y == ‘Y’ THEN GOTO 10
90 PRINT “THANKS FOR PLAYING”
4. It looks The JS version
better with whitespace
do {
var i = Math.floor(Math.random()*11);
do {
var j = prompt(“Guess my number”);
} while (i != j);
alert(“You got it!);
y = confirm(“Play again?”);
} while (y);
alert(“Thanks for playing”);
5. It reads better with whitespace
do {
var i = Math.floor(Math.random()*11);
do {
var j = prompt(“Guess my number”);
} while (i != j);
alert(“You got it!);
y = confirm(“Play again?”);
} while (y);
alert(“Thanks for playing”);
6. What else can we do about it?
do {
var i = Math.floor(Math.random()*11);
do {
var j = prompt(“Guess my number”);
} while (i != j);
alert(“You got it!);
y = confirm(“Play again?”);
} while (y);
alert(“Thanks for playing”);
7. It reads better with nicer names
do {
var mystery_number = Math.floor(Math.random()*11);
do {
var guessed_number = prompt(“Guess my number”);
} while (guessed_number != mystery_number);
alert(“You got it!);
var play_again = confirm(“Play again?”);
} while (play_again);
alert(“Thanks for playing”);
8. Can we do better than renaming?
do {
var mystery_number = Math.floor(Math.random()*11);
do {
var guessed_number = prompt(“Guess my number”);
} while (guessed_number != mystery_number);
alert(“You got it!);
var play_again = confirm(“Play again?”);
} while (play_again);
alert(“Thanks for playing”);
9. Make the intention clearer
do {
keep_guessing_until_matched( mystery_number() );
} while (play_again());
say_thanks();
10. It’s still not good enough
do {
keep_guessing_until_matched( mystery_number() );
} while (play_again());
say_thanks();
Why?
11. Because it is still this design
10 I = INT(10 * RND(1))
20 PRINT “GUESS MY NUMBER:”
30 INPUT J
40 IF INT(J) != I THEN GOTO 20 And it is not a
50 PRINT “YOU GOT IT!” very good
60 PRINT “PLAY AGAIN (Y/N)?” design either
70 INPUT Y
80 IF Y == ‘Y’ THEN GOTO 10
90 PRINT “THANKS FOR PLAYING”
12. How do I add a new feature?
10 I = INT(10 * RND(1))
20 PRINT “GUESS MY NUMBER:”
30 INPUT J
40 IF INT(J) != I THEN GOTO 20 And it is not a
50 PRINT “YOU GOT IT!” very good
60 PRINT “PLAY AGAIN (Y/N)?” design either
70 INPUT Y
80 IF Y == ‘Y’ THEN GOTO 10
90 PRINT “THANKS FOR PLAYING”
13. How do I test it?
10 I = INT(10 * RND(1))
20 PRINT “GUESS MY NUMBER:”
30 INPUT J
40 IF INT(J) != I THEN GOTO 20 And it is not a
50 PRINT “YOU GOT IT!” very good
60 PRINT “PLAY AGAIN (Y/N)?” design either
70 INPUT Y
80 IF Y == ‘Y’ THEN GOTO 10
90 PRINT “THANKS FOR PLAYING”
14. Let’s just focus on the game itself
TestCase("Game Tests", {
"test new game should let us play": function() {
var play = new_game();
assertFunction(play);
},
"test play should let us check for a win": function() {
var play = new_game();
var win = play(5);
assertFunction(win);
},
"test winning play": function() {
var play = new_game();
var guess = play['mystery_number'];
var win = play(guess);
assertTrue(win());
}
});
15. The game as Higher Order Functions
var play = new_game();
var win = play(guess);
The rest is user interface stuff
17. Every powerful language has this
Primitive expressions
Means of combination
Means of abstraction
(this parallels the basics of human understanding too, btw)
18. We use these languages to
express and organise our thoughts
do {
keep_guessing( mystery_number() );
} while (play_again());
say_thanks();
OR
var play = new_game();
var win = play(guess);
19. We use these languages to
express and organise our thoughts
do {
Build monolithic
keep_guessing( mystery_number() );
} while (play_again());
static structures
say_thanks();
OR
var play = new_game();
var win = play(guess);
Build composable
dynamic structures
20. JS let’s you build both.
What do you want to build?
factor10.com :: @aslamkhn :: aslamkhan.net