How To Create Computer Games
How To Create Computer Games
CHRISTOPHER LAMPTON
HOW TO
CREATE
COMPUTER
GAMES
A Computer-Awareness
First Book
Franklin Watts
New York 1London 1Toronto
Sydney 11986
Library of Congress Cataloging in Publication Data
Lampton, Christopher.
How to create computer games.
(A Computer-awareness first book)
Includes index.
Summary: Provides instructions for creating
computer games using BASIC.
1. BASIC (Computer program language)-Juvenile
literature. 2. Computer games-Juvenile literature.
[1. Computer games. 2. BASIC (Computer program
language) 3. Programming languages (Computers)
4. Programming (Computers)] I. Title. II. Series.
QA76.73.B3L3535 1986 794.8'2 85-26635
ISBN 0-531-10120-7
Chapter One
The Ghost in the Machine 1
Chapter Two
A Fishing Expedition 13
Chapter Three
Playing the Game 25
Chapter Four
Something Completely Different 53
Chapter Five
Checkers 63
Chapter Six
All the World's a Game 81
Index 83
HOW TO CREATE COMPUTER GAMES
CHAPTER ONE
THE GHOST
IN THE
MACHINE
[2]
already know a few things about computer programming. For
instance, you should know how to write computer programs
using the programming language called BASIC. If you don't know
anything about BASIC, or if you don't even know what a pro-
gramming language is, then this book will probably be too tough
for you. We suggest that you read at least one introductory book
on BASIC programming before you continue.
The program examples in this book are intended to run on any
computer equipped to understand BASIC-that is, a computer
that is running a BASIC interpreter, the program that translates
BASIC instructions into an electronic form that the computer
understands. Of course, this means that we've left out features
such as graphics (pictures) that you might expect to find in a game
program, because the way in which graphics are programmed
varies widely from one computer to another. However, we'll
make suggestions as to how you can add these features, if you
wish.
[3]
information is stored. There are several types of variables, but we
will concentrate on numeric variables-variables that store num-
bers. We will use these numbers to represent all sorts of things-
playing cards, positions on a game board, even, well, numbers.
We store a number using a numeric variable like this:
A = 178
LET A = 178
If you are using one of these versions of BASIC, you will need to
make this change to all assignment statements in this book.)
Once we've assigned a value to a variable, we can retrieve that
value just by using the variable's name. For instance, if we write
the instruction:
PRINT A
[4]
abIes. For instance, there is a special kind of data structure found
in most programming languages called the array. An array is a list
of variables that can be used to hold a list of data items. In BASIC,
an array variable looks like an ordinary variable, except that the
name of the variable is followed by one or more numbers in pa-
rentheses, like this:
A(1)
8G(14)
Y6(10,1)
All of these are names that can be used for array variables. Before
you can use an array variable in a BASIC program, however, you
must dimension the array using a DIM statement, like this:
DIM A(10)
This tells the BASIC interpreter that you are establishing an array
called A and that this array will have ten elements.
What is an element? Well, when you create an array like the
one above you are not just creating a single variable; you are
creating ten different variables. Here are their names:
A(1) A(6)
A(2) A(7)
A(3) A(8)
A(4) A(9)
A(5) A(10)
[5]
of the array we are dealing with. For instance, the element A(6)
has a subscript of 6, so we know it is element 6 of the array.
Since the array above is a numeric array-that is, an array
made up of numeric variables-we can use each element to store
a number. We can assign a value to an element of an array just like
we assign a value to a regular variable, like this:
A(2) = 45
PRINT A(2)
B = A(2)
c= A(2) - 15
and so forth.
"Wait a minute!" you exclaim. If we can do exactly the same
things with an array element as we can with an ordinary variable,
what's the point of using an array?
Good question. The answer is that an array can be used to put
information in order. If we have a list of numbers and we need to
keep that list organized, we can store that list in an array. Further-
more, it is easier to use an array of ten elements to store data than
it is to use ten separate variables, with different names. Why?
Because we can use a second variable to represent the subscript of
the array, like this:
[6]
A(B)
A(2)
A(7)
INPUT A
INPUT A(7)
[7)
values to ten non-array variables, we would need to write ten
separate input statements, like this:
10 INPUT A
20 INPUT B
30 INPUT C
40 INPUT D
50 INPUT E
60 INPUT F
70 INPUT G
80 INPUT H
90 INPUT I
100 INPUT J
You don't need to type and RUN this program, but if you did, it
would prompt you to type ten numbers, pressing RETURN (or
ENTER) after each. Each number would be assigned to a separate
variable, from A through J-though you could change these to
any variable names that you might prefer.
This program would be much simpler if we used array vari-
ables, rather than ordinary variables. We would dimension the
array in the first line of the program, like this:
10 DIM L(10)
20 FOR X=1 TO 10
30 INPUT L(X)
[8]
40 NEXT X
10 DIM L(10)
20 FOR X=1 TO 10
30 INPUT L(X)
40 NEXT X
Do you see how this program works? The FOR-NEXT loop will be
executed ten times. Each time, the variable X will be equal to a
different number, from 1 to 10. Therefore, the variable L(X) in line
30 will be equal to a different element of array L each time the
loop executes. The first time, it will be L(l), because X will be
equal to 1. The second time, it will be L(2), and so on. Each time,
the user will be prompted, with a question mark, to type a num-
ber, and that number will be assigned to an element of the array.
(If you don't already know how a FOR-NEXT loop works, you
might find this example confusing. Once again, you should read
an introductory book on BASIC if you find these program exam-
ples too difficult.)
In short, this program does exactly what the earlier program
did, but it does it with four instructions instead of ten. And if we
suddenly decided that we wanted to input 100 numbers instead of
10, we would need to make only one small change to the pro-
gram, like this: .
10 DIM L(100)
20 FOR X=1 TO 100
30 INPUT L(X)
40 NEXT X
Now the program will input 100 numbers. To change the earlier
version so that it would input 100 numbers, we would need to add
[9]
ninety new instructions and ninety new variable names. See how
much easier the job becomes when we use an array?
Why would you want to put a list of numbers in an array?
There are almost as many reasons as there are computer pro-
grams. Maybe you are writing a program to keep track of the bat-
ting averages of your favorite players. Or maybe your program
contains the grade averages of all the students in a class, in order
of their names in the class roll book.
The arrays that we've been showing you are called one-dimen-
sional arrays. This is a fancy way of saying that each element of
the array has one subscript after it. Most versions of BASIC, how-
ever, allow us to create arrays that have more than one subscript
after each element, like this:
DK(2,9)
BG(1,9,13)
Z(89,3,1,2)
[10]
DIM AB(14,7)
This DIM statement creates an array called AB, with two dimen-
sions. There are fourteen possible subscripts in the first dimension
and seven possible subscripts in the second. (Actually, there are
fifteen and eight possible subscripts in each dimension, but we are
still ignoring the 0 subscript.)
Here are a few possible elements in this array:
AB(1,5)
AB(14,1)
AB(9,2)
How many elements are there in this array? Well, at a guess, you
might think that there would be twenty-one elements, because 21
is the sum of 14 and 7. But if you guessed this, you would be
wrong. Actually, there are ninety-eight elements in this array,
because 98 is 14 times 7! And that is why multidimensional arrays
eat computer memory-they have a lot of elements in them!
We use one-dimensional arrays to hold lists of data items,
such as numbers. Why would we use multidimensional arrays?
Once again, there are lots of reasons. In this book, we will show
you several ways in which both one- and two-dimensional arrays
can be used in game programs. Once you have finished reading
this book, you will probably have a better understanding of how
these data structures can be used in other kinds of programs.
[11]
CHAPTER TWO
A FISHING
EXPEDITION
[13]
There are several card games that match this description. One
of these is Go Fish.
You've probably played this game before, though perhaps not
recently. In case you haven't played it, or have forgotten the rules,
we'll describe it here briefly.
Go Fish, like most card garnes, is played with a deck of fifty-
two cards. We'll assume you know what a deck of cards looks like.
For our purposes, the most important thing about a deck is that
each card has a suit and a denomination. The suit for each card is
either hearts, diamonds, clubs, or spades. The denomination is
either ace, two through ten, jack, queen, or king.
The game of Go Fish is played by two to six players. In this
book, we will restrict ourselves to two players.
When the game begins, one of the two players is chosen to be
the dealer. (In our computerized version, the computer will
always deal.) The dealer shuffles the deck and hands seven cards
to each player. These cards become the players' hands.
The players then alternate turns, usually beginning with the
player who did not deal the cards. The player whose turn it is asks
the other player for all of the cards of a certain denomination that
he or she holds. For instance, one player may say to the other,
"Give me all of your nines." If the other has cards of this denom-
ination, he or she must give all of these cards to the player who
requests them. Before a player can ask for cards of a certain de-
nomination, however, that player must have at least one card of
that denomination in hand. For instance, the player who asks for
"nines" must have at least one nine in hand already.
If the other player does not have any cards of that denomina-
tion in hand, he or she says "Go fish!" The player asking for the
cards must then draw a card from the top of the deck and add it to
the cards in his or her hand.
If the player gets the denomination of card asked for-either
from the other player or from the deck-that player gets an extra
turn and can continue asking for cards until he or she fails to
receive the requested denomination.
[14]
When a player has four cards of the same denomination in
hand, that player is said to have a book and must discard those
cards-that is, put them aside. The game continues until one
player runs out of cards. The winner is the player who has dis-
carded the most books. If both players create the same number of
books, the game is a tie.
[15]
This isn't quite as hard as it sounds. Honest!
In our game of Go Fish, we will represent the deck of fifty-two
cards as a two-dimensional array called DK (deck). This array will
be created at the beginning of the game, like this:
20 DIM DK(4,13)
(Don't type this line or any of the rest of the program yet. At the
end of Chapter Three, we'll give you the complete program. You
can type it, and play with it, then.)
This line tells the computer that the first subscript can be any
of four possible numbers and that the second subscript can be any
of thirteen possible numbers. Do these numbers sound familiar?
We are going to use the first subscript to represent the four possi-
ble suits:
1 = hearts
2 = clubs
3 = diamonds
4 = spades
1 = ace
2-10 = two through ten
11 = jack
12 = queen
13 = king
DK(2,13)
[16)
this would represent the king of clubs, because the 2 in the first
position represents clubs and the 13 in the second position repre-
sents the king.
We could also write:
OK(SU,OE)
o= in the deck
1 = in the player's hand
2 = in the computer's hand
3 = in a discarded book
OK(3,8) = 1
[17]
have to "move" the card anywhere; rather, we use array OK to
keep track of it, in a way that the computer can understand.
This data structure, the array OK, is the key to our entire
game. Everything we do in the actual program will be based on
the fact that OK represents a deck of cards, that the first subscript
of OK is the suit, that the second subscript of OK is the denomi-
nation, and that the value of an element represents the where-
abouts of that card.
Now let's begin writing the program. Once again, you don't need
to type the program until we show you the complete listing at the
end of this chapter, but you should follow along as we build the
program line by line and routine by routine. (A routine is a set of
program instructions that accomplish a single task or related
group of tasks. A subroutine is a special kind of routine that is
called, or activated, by the GOSUB instruction.)
We've already written line 20, which DIMs the array OK. Line
10 should clear the video display of your computer, but the
instruction for this will vary from one version of BASIC to anoth-
er. For instance, if you are using a Radio Shack, IBM, or Timex-
Sinclair computer, you should use the instruction:
10 CLS
If you are using an Apple computer, you should use the instruc-
tion:
10 HOME
10 PRINT CHR$(147)
10 PRINT CHR$(125)
[18]
If you are not using one of the above computers and don't know
what instruction will clear the video display, just leave this line
out. It isn't really necessary; it just makes things look neater. The
rest of the program will be pretty much the same no matter which
computer you are using.
Next, we need to create a variable that will tell us how many
cards are currently in the deck, so that we will know when we run
out of cards. In Go Fish, we should never run out of cards in the
deck; by the time we reach the bottom of the deck one of the
players has to run out of cards, ending the game. Nonetheless, we
will check for this event in case something goes wrong with our
program. We create the variable like this:
30 ND=52
[20]
message reading "THE DECK IS EMPTY!" If this happens, check
your program to make sure it is correctly typed.
Line 2020 uses the RND function to choose a random suit,
which it stores in variable SU, and a random denomination,
which it stores in variable DE. How does the RND (random) func-
tion work? Unfortunately, it works differently in the various ver-
sions of BASIC, so you may have to make some changes here.
In most versions of BASIC, RND(O) will be equal to a random
fraction that is larger than 0 and smaller than 1. This may be dif-
ficult to understand, but you can simply think of the RND func-
tion as a way of coming up with an unpredictable number
between 0 and 1, but not including 1. The first time we use
RND(O) in the above subroutine, we write:
SU=INT(RND(O)*4+ 1)
[21]
ten in Radio Shack BASIC, Atari BASIC, and Commodore BASIC.
Consult your computer's manual for details, if necessary.
The next instruction in line 2020 is:
DE= INT(RND(0)*13+ 1)
This works pretty much like the last instruction, setting DE equal
to a random number in the range 1 to 13. Since the denomination
of a card can be any number from 1 (ace) to 13 (king), this sets DE
equal to a random denomination of card. We have now produced
both a random suit and a random denomination, as though we
had drawn a random card from a shuffled deck.
However, we must make sure that this card has not already
been drawn from the deck. Line 2030 reads:
DK(SU,DE)=CP
[22]
records the whereabouts of card DK(SU,DE), so that we will know
whether it is in the player's hand or the computer's.
The next instruction reads:
ND=ND-1
The loop that starts on line 100 repeats seven times. Each time it
calls the card-dealing subroutine twice, once with CP equal to 1
and once with CP equal to 2, dealing one card to the human
player and one card to the computer, for a total of seven cards in
each hand.
All of this dealing and shuffling takes time, and the player
may wonder what the computer is up to. To calm the player's
(23}
fears that the computer might have abandoned him or her, we'll
print a message on the video display, like this:
40 PRINT "DEALING"
Notice that this message goes way back in line 40, so it will be
printed before the dealing starts.
After the dealing, we must take care of some important busi-
ness. We must establish the number of cards in the player's hand
and the number of cards in the computer's hand, because these
numbers will keep changing throughout the game and we must
keep track of them. We will use the variable PN ("player's num-
ber") to store the number of cards in the player's hand and the
variable CN ("computer's number") to store the number of cards
in the computer's hand. At the beginning of the game, both hands
have seven cards in them, so we will set both variables equal to 7,
like this:
All of the basic elements of the game are now in place. Sharp-
en your Go Fish skills-it's time to play!
[24)
CHAPTER THREE
PLAYING
THE GAME
[25]
is holding and the number of books that the player has dis-
carded.
Printing out the number of books that have been discarded is
easy. This number, you will remember, is contained in variable PB
("player's books"), so we can print it out like this:
Notice that we don't leave any blank spaces around the number of
books. This is because most versions of BASIC will automatically
place blank spaces before and after a number. If you are using a
version of BASIC that does not do this, such as Applesoft or Atari
BASIC, you will need to add some spaces inside the quotes, until
this sentence looks right on your video display.
Printing out the number of cards that the player is holding is
also easy. This number is contained in the variable PN ("player's
number"), and can be printed out like this:
But wait! Naming the cards is trickier than numbering them. First,
we will need a special notation for the cards-that is, a way of
naming them on the video display. Because there is a limited
amount of space on the video display for printing the card names,
this notation should be short. We will use only one or two char-
acters to represent the denomination:
A= ace 8= eight
2 = two 9= nine
3 = three 10= ten
4 = four J= jack
[26]
5 = five Q= queen
6 = six K= king
7 = seven
Ht = hearts
Cl = clubs
Di = diamonds
Sp = spades
J-CI
5-Sp
A-Ht
and so forth.
Now we need a subroutine that will take a suit number from 1
to 4 and a denomination number from 1 to 13 and print the card
name on the video display using this notation. Here is such a sub-
routine:
[27]
3030 IF DE=11 THEN PRINT "J"; : GOTO 3060: REM JACK
3040 IF DE=12 THEN PRINT "0"; : GOTO 3060 : REM OUEEN
3050 IF DE=13 THEN PRINT "K"; : GOTO 3060 : REM KING
3060 PRINT "-"; : REM PRINT A HYPHEN IN THE MIDDLE
3070 IF SU=1 THEN PRINT "Ht"; : RETURN: REM HEARTS
3080 IF SU=2 THEN PRINT "CI"; : RETURN: REM CLUBS
3090 IF SU=3 THEN PRINT "Di"; : RETURN: REM DIAMONDS
3100 IF SU=4 THEN PRINT "Sp"; : RETURN: REM SPADES
(If you are using Timex-Sinclair BASIC, you will need to change
the letters" ASC" to "CODE.") You don't need to understand
[28]
how this line works. Just take our word for it that it does. Unfor-
tunately, it won't work properly if the card is "10," which is why
we have deliberately singled out "10" for special treatment on
line 3010.
Now that we have a subroutine that prints out the name of the
card, we can call this subroutine to print out the cards in the
human player's hand. We determine which cards are in the
player's hand by looking through the entire deck, and checking to
see which elements of array DK are equal to 0, like this:
The two FOR-NEXT loops run through all the denominations and
suits. Every time it finds one that is in the player's hand-that is,
if DK(SU,DE) is equal to 1-it calls the subroutine at line 3000 to
print the name of that card on the video display. It then prints two
blank spaces, to separate the names. The PRINT statement on line
250 simply prints a carriage return at the end of the list of
cards.
Before we proceed with the game, we should check to be sure
that there are no books of cards in the player's hand. Although the
game has not really begun, it is possible that the player has been
dealt four cards of the same denomination. Not very likely, but
possible. Of course, we will also need to check again for a book
later, after the player has drawn cards from the computer's hand
or the deck. And we will need to check the computer's hand for
books too, when it is the computer's turn to play. Therefore, we
should create a subroutine that will check for books, since we will
be doing it often. Here is such a subroutine:
[29]
4000 FOR DE=1 TO 13 : REM CHECK ALL 13 DENOMINATIONS
4010 NC=O : REM SET NUMBER OF CARDS IN DENOMINATION TO
o
4020 FOR SU=1 TO 4: REM CHECK ALL 4 SUITS
4030 IF DK(SU,DE)=CP THEN NC=NC+1 : REM COUNT NUMBER
OF CARDS OF THIS DENOMINATION IN CURRENT PLAYER'S
HAND
4040 IF NC=4 THEN 4090 : REM IF IT'S A BOOK OF FOUR, SKIP
AHEAD
4050 NEXT SU
4060 NEXT DE
4070 DE=O : REM NO BOOK WAS FOUND
4080 RETURN
4090 FOR SU=1 TO 4: REM ELSE, IF FOUND, THEN DISCARD IT
4100 DK(SU,DE)=3 : REM 3 = DISCARDED BOOK
4110 NEXT SU
4120 RETURN
[30]
search is terminated and the computer jumps ahead to line 4090.
(There can never be more than one book in hand at a time, so
there is no need to search further.)
If no book is found, DE is set equal to 0 and the subroutine
RETURNs to the main program. If a book is found, the loop begin-
ning on line 4090 sets all cards of that denomination-
DK(SU,DE)-equal to 3, indicating that they have been discarded
from the hand. The variable DE now contains the number of the
denomination for which we found a book.
We first call this subroutine immediately after we print out the
contents of the human player's hand, like this:
[31]
5060 IF DE=7 THEN PRINT "SEVENS" : RETURN
5070 IF DE=8 THEN PRINT "EIGHTS" : RETURN
5080 IF DE=9 THEN PRINT "NINES" : RETURN
5090 IF DE=10 THEN PRINT "TENS" : RETURN
5100 IF DE=11 THEN PRINT "JACKS" : RETURN
5110 IF DE=12THEN PRINT "QUEENS": RETURN
5120 PRINT "KINGS" : RETURN
This is a long but simple subroutine. It does nothing but check the
value of DE and print an appropriate name for the denomination.
Line 5120 assumes that the denomination must be KINGS, if the
computer has gotten that far.
The result of calling this subroutine is that line 280, above,
will print out something like this:
[32]
This tells us that the player has one more book and four less cards.
It is impossible for the game to be over after a single book has
been discarded, but this routine will be executed many more times
in the course of the game, and so we must check to see if the
player has run out of cards, thus ending the game. If so, the com-
puter prints "YOU ARE OUT OF CARDS!," then jumps to line
950. The routine beginning at line 950 will announce that the
game is over, then decide who has won and congratulate the win-
ner. We will show you this routine shortly.
Now the player must ask the computer for all of its cards of a
certain denomination. Of course, the player can't speak to the
computer directly-unless the computer is equipped with voice-
recognition equipment. Instead, the program asks the player
which denomination he or she desires, like this:
[33]
6020 IF DK(SU,DE)=CP THEN FL=1 : REM IF CARD FOUND, FLAG
IT
6030 NEXT SU
6040 RETURN
[34]
These four lines do a lot. They check through all four suits looking
for cards of the requested denomination. The number of cards is
counted in variable NC. When a card is found, it is moved from
the computer's hand (2) to the player's hand (1).
At the end of the loop, NC is equal to the number of cards that
were moved. If NC is still equal to zero, then the computer was
holding no cards of that denomination. Effectively, the computer
has told the player to "Go Fish!"-and so we skip ahead to the Go
Fish routine, like this:
This could cause the computer to run out of cards, in which case
the game is over. We check for that like this:
The routine beginning on 950, you'll recall, will announce the end
of the game and check to see who won.
If the game isn't over, we continue. First, we have to announce
how many cards were transferred:
[35]
tained in DE. If the denomination was 7 and the number of cards
transferred (NC) was 3, this would print:
A glance at line 170 will tell you that this will cause the player's
hand to be printed out again and another search to be conducted
for books. (A search for new books should be conducted every
time the player puts new cards in his or her hand.)
What if the player was unsuccessful in requesting cards? The
computer will have jumped ahead to line 440, as in the instruction
in line 390. This is where the computer tells the player to "Go
Fish!":
[36]
The rest of line 450 sets CP equal to 1 and calls the subroutine
at line 2000 to deal a random card to the human player. The
instruction PN = PN + 1 notes that the number of cards in the
player's hand has increased by one.
The next line prints out the name of the card that was
drawn:
460 PRINT "YOU HAVE DRAWN THE "; : GOSUB 3000 : PRINT"."
The subroutine at line 3000 prints the actual name of the card, in
our special notation. The statement PRINT"." prints a period (.) at
the end of the sentence.
According to the rules, if the card that the player draws from
the deck is of the same denomination that he or she just requested
from the other player, then the player gets another turn. Thus, we
check to see if the denomination of the card that was drawn (DE)
is equal to the denomination of the card that was asked for
(PD):
If so, we loop back to the beginning of the main loop, on line 170,
and the player's turn is repeated. And now you know why we
saved the value of the requested card in variable PD.
If we don't loop back, we still must check to see if the player
has any books in his or her hand, now that a new card has been
added. This part of the program proceeds much as before:
480 CP=1 : GOSUB 4000 : REM LOOK FOR BOOKS IN CP'S HAND
490 IF DE=O THEN 530 : REM IF NO BOOKS, SKIP AHEAD
500 PRINT "YOU HAVE A BOOK OF "; : GOSUB 5000 : REM ELSE
ANNOUNCE IT
510 PRINT "YOU DISCARD THIS BOOK"
520 PB=PB+1 : PN=PN-4: IF PN=O THEN PRINT "YOU ARE OUT
[37]
OF CARDS!"; : GOTO 950 : REM IF PLAYER OUT OF CARDS, END
GAME
When it was the human player's turn, we printed out the con-
tents of the hand. However, it would be cheating to let the human
player see the contents of the computer's hand. Nonetheless, you
might want to look at the computer's hand occasionally, to check
if the program is working correctly, so we will include instructions
to print it out. But we will put these instructions in REM state-
ments, so that the computer will think they are remarks and
ignore them. If you want the computer to execute these state-
ments and show you the computer's hand, remove the word REM
at the beginning of each line:
[38]
620 CP=2 : GOSUB 4000 : REM LOOK FOR BOOKS IN CP'S HAND
630 IF DE=O THEN 670 : REM IF NO BOOKS, SKIP AHEAD
640 PRINT "THE COMPUTER HAS A BOOK OF "; : GOSUB 5000 :
REM ELSE ANNOUNCE IT
650 PRINT "IT DISCARDS THIS BOOK"
660CB=CB+1 : CN=CN-4: IFCN=OTHEN PRINT "THECOMPUT-
ER IS"; : GOTO 950
670DE=INT(RND(0)*13+1)
[39]
This sets DE equal to a random denomination betwen 1 and 13.
(Remember, if you needed to change the RND(O) function in the
subroutine at line 2000 to fit your version of BASIC, you will need
to make a similar change here.) If this denomination has already
been discarded, then the computer should choose a different
denomination. This is easy enough to check:
[40]
cards. However, it would be nice to pause the program and give
the player a chance to rest a minute:
This will pause the program until the RETURN (or ENTER) key is
pressed. (If the key on your computer is called ENTER rather than
RETURN, you can change this program line accordingly.)
Next, we must search the human player's hand for cards of
this denomination:
[41]
810 PRINT "YOU GIVE THE COMPUTER";NC; : GOSUB 5000
We then announce that the computer has drawn a card, but not
what card it has drawn. (That would be cheating!)
Notice that we skip ahead to line 890 if the computer does not get
the denomination it requests-that is, if PD does not equal DE. If
it does get the denomination it requests, it gets another turn, just
as the human player did-but it must show what card it drew, to
prove it got the requested denomination:
870 PRINT "THE COMPUTER HAS DRAWN THE "; : GOSUB 3000 :
PRINT "."
880 PRINT "IT GETS AN EXTRA TURN!" : GOTO 530
[42]
The subroutine at line 3000 prints out the name of the denomina-
tion. Of course, these lines are skipped if the computer does not
get the denomination it asked for.
We must now search the computer's hand a second time for
books and announce any books we find:
The PRINT statement merely adds a blank line on the video dis-
play, to make it more readable.
We have made several references to a routine on line 950,
which ends the game and congratulates the winner. Here it is:
[43]
We politely ask the player if he or she wants to play again:
[44]
Nobody with a decent command of the English language says
1/1 books"-but the computer doesn't know any better. You can
add instructions telling the computer to change the word "books"
to "book" when the number of books (in variable NB) is 1.
In the same way, the computer will say things like:
Add instructions to tell the computer that "1 aces" should be "1
ace."
Another area you might want to improve is in the strategy by
which the computer chooses the denomination it requests of the
human player. As explained earlier, this choice is made random-
ly-but it doesn't have to be. While you play the game, notice the
way in which you make your own choices about which cards to
ask for.
Do you notice which denomination the computer keeps ask-
ing you for (and therefore must have in its hand)-then wait until
you draw a card of that denomination so that you can get those
cards from the computer? Do you ever ask the computer for a card
that you know it cannot possibly have? Are there certain circum-
stances under which you must ask the computer for a card you
know it does not have? Once you have figured out a strategy, see
if you can program that strategy into the computer.
As you play the game, of course, you will see other areas
where it could use improvement. Make all the improvements you
want. As written, this game is really a skeleton, waiting for you to
flesh it out, to add the extra features that programmers call "bells
and whistles."
And when you have put the program together exactly as you
want it, try it out in your friends. But don't be surprised if they
have a few suggestions of their own!
[45]
10 REM ( Add an instruction on this line to clear the video display of your
computer. See Chapter Two for details.)
20 DIM DK(4,13)
30 ND=52
40 PRINT "DEALING"
50 FOR SU=1 TO 4
60 FOR DE=1 TO 13 I
70 DK(SU,DE)=O
80 NEXT DE
90 NEXT SU
100 FOR 1=1 TO 7
110 GOSUB 2000: DK(SU,DE)=1
120 GOSUB 2000 : DK(SU,DE)=2
130 NEXT I
150 PN=7 : CN=7
160 PB=O : CB=O
170 PRINT "YOU HAVE DISCARDED";PB;"BOOKS"
180 PRINT "YOU HAVE";PN;"CARDS"
190 PRINT "THEY ARE: ";
200 FOR DE=1 TO 13
210 FOR SU=1TO 4
220 IF DK(SU,DE)=1 THEN GOSUB 3000 : PRINT" ";
230 NEXT SU
240 NEXT DE
250 PRINT
260 CP=1 : GOSUB 4000: REM LOOK FOR BOOKS
270 IF DE=O THEN 310
280 PRINT "YOU HAVE A BOOK OF "; : GOSUB 5000
290 PRINT "YOU DISCARD THIS BOOK"
300 PB=PB+1 : PN=PN-4 : IF PN=O THEN PRINT "YOU ARE OUT
OF CARDS!" : GOTO 950
310 PRINT "WHICH DENOMINATION WOULD YOU LIKE (1-13)?"
320 INPUT DE
330 CP=1 : GOSUB 6000
340 IF FL=O THEN PRINT "YOU DON'T HAVE ANY IN YOUR HAND!":
[46]
GOTO 310
350 NC=O
360 FOR SU=1 TO 4
370 IF DK(SU,DE)=2 THEN NC=NC+1 : DK(SU,DE)=1
380 NEXT SU
390 IF NC=O THEN 440
400 PN=PN+NC : CN=CN-NC
410 IF CN=O THEN PRINT "THE COMPUTER IS OUT OF CARDS!" :
GOTO 950
420 PRINT "THE COMPUTER GIVES YOU";NC; : GOSUB 5000
430 GOTO 170
440 PRINT "THE COMPUTER SAYS: 'GO FISH!' "
450 PD=DE: CP=1 : GOSUB 2000: DK(SU,DE)=1 : PN=PN+1
460 PRINT "YOU HAVE DRAWN THE "; : GOSUB 3000 : PRINT" "
470 IF DE=PD THEN PRINT "CONGRATULATIONS! YOU GET AN
EXTRA TURN!": GOTO 170
480 CP=1 : GOSUB 4000: REM LOOK FOR BOOKS
490 IF DE=O THEN 530
500 PRINT "YOU HAVE A BOOK OF"; : GOSUB 5000
510 PRINT "YOU DISCARD THIS BOOK"
520 PB=PB+1 : PN=PN-4: IF PN=O THEN PRINT "YOU ARE OUT
OF CARDS!"; : GOTO 950
530 PRINT: PRINT "THE COMPUTER HAS DIS-
CARDED" ;CB; "BOOKS"
540 PRINT "IT HAS";CN;"CARDS"
550 REM PRINT "THEY ARE: ";
560 REM FOR DE=1 TO 13
570 REM FOR SU=1 TO 4
580 REM IF DK(SU,DE)=2 THEN GOSUB 2000 : PRINT" ";
590 REM NEXT SU
600 REM NEXT DE
610 REM PRINT
620 CP=2 : GOSUB 4000
630 IF DE=O THEN 670
640 PRINT "THE COMPUTER HAS A BOOK OF "; : GOSUB 5000
[47]
650 PRINT "IT DISCARDS THIS BOOK"
660 CB=CB+1 : CN=CN-4: IF CN=O THEN PRINT "THE COMPUT-
ER IS OUT OF CARDS!"; : GOTO 950
670 DE=INT(RND(0)*13+1)
680 IF DK(1 ,DE)=3 THEN 670
690 CP=2 : GOSUB 6000
700 IF FL=O THEN 670
710 PRINT "THE COMPUTER SAYS:"
720 PRINT "GIVE ME ALL OF YOUR "; : GOSUB 5000
730 PRINT "PRESS <RETURN> TO CONTINUE"
740 INPUT Q
750 NC=O
760 FOR SU=1 TO 4
770 IF DK(SU,DE)=1 THEN NC=NC+1 : DK(SU,DE)=2
780 NEXT SU
790 IF NC=O THEN 840
800 CN=CN+NC : PN=PN-NC
810 PRINT "YOU GIVE THE COMPUTER";NC; : GOSUB 5000
820 IF PN=O THEN PRINT "YOU ARE OUT OF CARDS!" : GOTO
950
830 GOTO 530
840 PRINT "YOU TELL THE COMPUTER: 'GO FISH!' "
850 PD=DE: CP=2: GOSUB 2000: DK(SU,DE)=2 : CN=CN+1
860 PRINT "THE COMPUTER DRAWS FROM THE DECK" : IF
PD<>DE THEN 890
870 PRINT "THE COMPUTER HAS DRAWN THE "; : GOSUB 3000 :
PRINT "."
880 PRINT "IT GETS AN EXTRA TURN!" : GOTO 530
890 CP=2 : GOSUB 4000: REM LOOK FOR BOOKS
900 IF DE=O THEN 940
910 PRINT "THE COMPUTER HAS A BOOK OF "; : GOSUB 5000
920 PRINT "IT DISCARDS THIS BOOK"
930 CB=CB+1 : CN=CN-4: IF CN=O THEN PRINT "THE COMPUT-
ER IS OUT OF CARDS!" : GOTO 950
940 PRINT: GOTO 170
[48]
950 REM CONGRATULATE THE WINNER
960 PRINT "THE GAME IS OVER!"
970 PRINT "YOU HAVE";PB;"BOOKS"
980 PRINT "THE COMPUTER HAS";CB;"BOOKS"
990 IF CB>PB THEN PRINT "THE COMPUTER HAS WON!" : GOTO
1020
1000 IF PB>CB THEN PRINT "YOU HAVE WON!" : GOTO 1020
1010 PRINT "THE GAME IS A TIE!"
1020 PRINT "PLAY AGAIN? (1 =YES, 2=NO)"
1030 INPUT Q
1040 IF Q=1 THEN 30
1050 IF Q=2 THEN END
1060 GOTO 1020
1989 REM
1990 REM *** DEAL A CARD
1991 REM ***
1992 REM *** SUBROUTINE TO DEAL ONE CARD
1993 REM *** FROM A DECK OF 52 CARDS, IN
1994 REM *** ARRAY DK(SUIT, DENOMINATION)
1995 REM ***
1996 REM
2000 IF ND>O THEN: GOTO 2020
2010 PRINT "THE DECK IS EMPTY!" : END
2020 SU=INT(RND(0)*4+1) : DE=INT(RND(0)*13+1)
2030 IF DK(SU,DE)<>O THEN 2020
2040 DK(SU,DE)=CP : ND=ND-1
2050 RETURN
2989 REM
2990 REM *** NAME THE CARD
2991 REM ***
2992 REM *** A SUBROUTINE TO WRITE THE NAME
2993 REM *** OF A CARD ON THE VIDEO DISPLAY
2994 REM *** IN ABBREVIATED NOTATION, WHERE
2995 REM *** SU IS THE SUIT AND DE IS THE
2996 REM *** DENOMINATION OF THE CARD
[49]
2997 REM ***
2998 REM
3000 IF DE>1 AND DE<10 THEN PRINT [CHR$(DE+ASC("O"))]; :
GOTO 3060
3010 IF DE=10 THEN PRINT "10"; : GOTO 3060
3020 IF DE=1 THEN PRINT "A"; : GOTO 3060
3030 IF DE = 11 THE PRINT "J"; : GOTO 3060
3040 IF DE= 12 THEN PRINT "0"; : GOTO 3060
3050 IF DE=13 THEN PRINT "K"; : GOTO 3060
3060 PRINT"-";
3070 IF SU=1 THEN PRINT "Ht"; : RETURN
3080 IF SU=2 THEN PRINT "CI"; : RETURN
3090 IF SU=3 THEN PRINT "Di"; : RETURN
3100 IF SU=4 THEN PRINT "Sp"; : RETURN
3989 REM
3990 REM *** CHECK FOR A BOOK
3991 REM ***
3992 REM *** A SUBROUTINE TO CHECK THE DECK
3993 REM *** TO SEE IF THE CURRENT PLAYER (CP)
3994 REM *** HAS FOUR CARDS OF THE SAME
3995 REM *** DENOMINATION (DE)-A "BOOK," IN
3996 REM *** THE PARLANCE OF THE GAME. RETURNS
3997 REM *** THE DENOMINATION (OR 0) IN DE
3998 REM ***
3999 REM
4000 FOR DE=1 TO 13
4010 NC=O
4020 FOR SU=1 TO 4
4030 IF DK(SU,DE)=CP THEN NC=NC+1
4040 IF NC=4 THEN 4090
4050 NEXT SU
4060 NEXT DE
4070 DE=O
4080 RETURN
[50]
4090 FOR SU=1 TO 4
4100 DK(SU,DE)=3
4110 NEXT SU
4120 RETURN
4989 REM
4990 REM *** NAME THE DENOMINATION
4991 REM ***
4992 REM *** A SUBROUTINE TO PRINT THE
4993 REM *** NAME OF DENOMINATION DE TO
4994 REM *** THE VIDEO DISPLAY AS A WORD
4995 REM ***
4996 REM
5000 IF DE=1 THEN PRINT "ACES" : RETURN
5010 IF DE=2 THEN PRINT "TWOS" : RETURN
5020 IF DE=3 THEN PRINT "THREES" : RETURN
5030 IF DE=4 THEN PRINT "FOURS" : RETURN
5040 IF DE=5 THEN PRINT "FIVES" : RETURN
5050 IF DE=6 THEN PRINT "SIXES" : RETURN
5060 IF DE=7 THEN PRINT "SEVENS" : RETURN
5070 IF DE=8 THEN PRINT "EIGHTS" : RETURN
5080 IF DE=9 THEN PRINT "NINES" : RETURN
5090 IF DE=10 THEN PRINT "TENS:' : RETURN
5100 IF DE=11 THEN PRINT "JACKS": RETURN
5110 IF DE=12 THEN PRINT "QUEENS": RETURN
5120 PRINT "KINGS" : RETURN
5989 REM
5990 REM *** CHECK HAND FOR DENOMINATION
5991 REM ***
5992 REM *** A SUBROUTINE TO CHECK THE
5993 REM *** HAND OF THE CURRENT PLAYER (CP)
5994 REM *** DENOMINATION DE. THE VARIABLE
5996 REM *** FL IS SET EQUAL TO 1 IF SO,
5997 REM *** AND 0 IF NOT
5998 REM ***
[51]
5999 REM
6000 FL=O
6010 FOR SU=1 TO 4
6020 IF DK(SU,DE)=CP THEN FL=1
6030 NEXT SU
6040 RETURN
[52]
- ;, ,1
CHAPTER FOUR
SOMETHING
COMPLETELY
DIFFERENT
[53]
player directly against the computer. Rather, we are going to write
a program that will let two human players play against each other,
using the computer screen as a playing field instead of a piece of
paper. Of course, if you feel that you are up to the job, you can
rewrite the program so that the game is actually played against
the computer. Good luck!
The tic-tac-toe board will be simulated by a two-dimensional
array called TB, which will be dimensioned like this:
20 DIM TB(3,3)
30 CP=O : NM=O
CP equals the number of the current player, 1 for player one and 2
for player 2. Player 1 will use the X to mark squares and player 2
[54]
will use the O. NM equals the number of markers-both XS and
Os-that have been placed on the board.
At the start of the game, we must set every element of the
array TB to 0, to indicate that no squares have been marked with
either Xs or Os:
[55]
1130 PRINT: REM CARRIAGE RETURN TO NEXT LINE
1140 NEXT ROW
1150 PRINT: REM BLANK LINE AT BOTTOM
1160 RETURN
As you will see, this routine prints out numbers at the head of
each column and at the beginning of each row, so that we can
easily identify the location of each square. The spacing of the
characters is very important here, which may present a problem if
you are using certain versions of BASIC. As we have mentioned
before, some versions of BASIC print extra blank spaces around
numbers and others don't. This subroutine assumes that the
spaces are printed. If you are using Applesoft BASIC or Atari
BASIC or any other version that does not perform this automatic
spacing, the board will look very cramped, and the column num-
bers will be in the wrong positions. You will have to rewrite this
routine so that spaces will be printed between the squares of the
board, and between the column numbers.
We'll call the subroutine like this:
[56]
Of course, this isn't going to happen on the first move, but this
line will be repeated before every move in the game.
Now it is time for a player to put his or her marker on the board.
The current player, 1 or 2, is represented by variable CPo We ini-
tially set CP equal to 0, which is not the number of either player.
So we will now add 1 to that, and make it the first player's
turn:
110 CP=CP+1
The next time this loop executes, this statement will add another 1
to CP, making the current player 2. But the next time, we will
want the current player to be 1 again, so we must make sure that
the value of CP never becomes greater than 2:
First, we will ask the player to choose the row on which his or
her marker is to be placed:
[57]
The PRINT statement in line 180 adds a blank line to keep the
video display neat.
It would also be nice to give the players a way to end a game
in progress-in case it is obvious that nobody is going to win. If
the player types -1 when asked for a ROW, we will stop the
game, like this:
We should make sure that the row and column that the player
asked for fall within the legal bounds-that is, that neither is
greater than 3 or less than 1:
If an illegal column or row has been asked for, we skip back to line
130 and ask again.
Finally, we must mark TB(ROW,COL) as having the current
player's marker on it. First, though, we must check to see that it is
not already occupied by a marker:
[58]
250 IF TB(I,COL)<>CP THEN FL=1 : REM IF MARKER NOT FOUND
ON ANY SQUARE, ASSUME THE WORST
260 NEXT I
270 IF FL=O THEN 370 : REM WE'VE GOT A WINNER
The loop beginning in line 240 takes us through all three squares
on the row where player CP put his or her marker. Variable FL
tells us if any of those squares are not occupied by CP's marker. If
FL equals 1 after the loop, CP did not have a marker on at least
one of the squares-and therefore cannot have three markers in a
horizontal row. If FL is still equal to 0 after the loop, then CP does
have three markers in a row, so we jump to line 370 to offer our
congratula tions!
We can do the same thing for the vertical column on which CP
placed his or her marker:
[59]
plies a number by itself a certain number of times. On some ver-
sions of BASIC, such as Applesoft, this should be replaced by a
circumflex symbol (~) and on others, such as Commodore
BASIC, by a symbol that looks like an upward pointing arrow (1).
If player 1 has placed markers on all squares in the diagonal, then
the result of multiplying the values in all of those squares together
(as we have done above) will be 1 multiplied by itself three times,
or 1. If player 2 has placed markers in all three squares, then the
result of multiplying the values together will be 2 multiplied by
itself three times, or 8. Thus, we can see if any player has occupied
all squares in the diagonal by checking if the result of this multi-
plication is 1 or 8.
Finally, we must loop back, draw the board again, and let the
other player make a move:
[60]
10 REM Add an instruction here to clear the video display of your com-
puter. See Chapter Two for details.
20 DIM TB(3,3)
30 CP=O : NM=O
40 FOR ROW = 1 TO 3
50 FOR COL = 1 TO 3
60 TB(ROW,COL) = 0
70 NEXT COL
80 NEXT ROW
90 GOSUB 1000 : REM ** DRAW TIC-TAC-TOE BOARD **
100 NM=NM+1 : IF NM>9THEN PRINT: PRINT "TIE GAME": GOTO
400
110 CP=CP+1
120 IF CP>2 THEN CP=1
130 PRINT "PLAYER";CP" 'S MOVE"
140 PRINT "ROW";
150 INPUT ROW
155 IF ROW = -1 THEN PRINT "GAME ABORTED" : GOTO 400
160 PRINT "COLUMN";
170 INPUT COL
180 PRINT
190 IF COL<1 OR COL>3 OR ROW<1 OR ROW>3 THEN GOTO
130
200 IF TB(ROW,COL)=O THEN TB(ROW,COL)=CP : GOTO 230
210 PRINT "THAT SQUARE IS TAKEN. TRY AGAIN"
220 GOTO 130
230 FL=O
240 FOR 1=1 TO 3
250 IF TB(I,COL)<>CP THEN FL=1
260 NEXT I
270 IF FL=O THEN 370
280 FL=O
290 FOR 1=1 TO 3
300 IF TB(ROW,I)<>CP THEN FL=1
310 NEXT I
[61]
320 IF FL=O THEN 370
340 IF TB(1,1)*TB(2,2)*TB(3,3)=CP[3 THEN 370
350 IF TB(3,1 )*TB(2,2)*TB(1 ,3) = CP[3 TH EN 370
360 GOTO 90
370 GOSUB 1000: REM ** DRAW TIC-TAC-TOE BOARD **
380 PRINT "CONGRATULATIONS, PLAYER";CP;"-YOU HAVE
WON!"
390 PRINT
400 PRINT "PLAY AGAIN? (1 =YES, 2=NO)"
410 INPUT Q
420 IF Q=1 THEN GOTO 30
430 IF Q=2 THEN END
440 GOTO 400
1000 REM ** DRAW TIC-TAC-TOE BOARD **
1010 PRINT" ";
1020 FOR COL = 1 TO 3
1030 PRINT COL;
1040 NEXT COL
1050 PRINT
1060 FOR ROW = 1 TO 3
1070 PRINT ROW;
1080 FOR COL = 1 TO 3
1090 IF TB(ROW,COL)=O THEN PRINT" - ";
1100 IF TB(ROW,COL)=1 THEN PRINT" X ";
1110 IF TB(ROW,COL)=2 THEN PRINT" 0 ";
1120 NEXT COL
1130 PRINT
1140 NEXT ROW
1150 PRINT
1160 RETURN
[62]
CHAPTER FIVE
CHECKERS
[63]
not be moved onto an occupied square. All movement must be
toward the opposing player's side of the board. When a piece
makes it to the far side of the board, it becomes a "king" and may
then move toward either side of the board (though it must still
move diagonally). A player may jump diagonally over an oppon-
ent's piece, if the square beyond that piece is empty, thereby
"capturing" the piece and removing it from the board. The winner
is the player who captures all of the opposing player's pieces.
We'll call our checkerboard array CB. It can be dimensioned
exactly as we dimensioned the tic-tac-toe board, except that the
rows and columns will be longer, with eight squares apiece
instead of three:
20 DIM CB(8,8)
Once again, the first subscript will indicate the row of a square
and the second subscript will indicate the column. If there is no
piece on a square, the element representing that square will be set
to O. If player 1 has a piece on that square, the element will be
set to 1. If player 2 has a piece on that square, the element will be
set to 2. If player 1 has a king on that square, the element will be
set equal to 3. If player 2 has a king on that square, the element
will be set equal to 4.
The black player always moves first; hence, we'll call this
player "player 1." As usual, the variable CP will hold the number
of the current player. A new feature of this program is that the
variable OP (for "other player" or "opponent") will hold the
number of the opposing player. In the beginning, CP is player 1
and OP is player 2:
30 CP=1 : OP=2
[64]
pieces already on the board, and so we must set the appropriate
elements of the array equal to 1 and 2, to indicate which squares
are occupied by each player's pieces. To ease our task, we will
create a set of DATA statements containing the opening setup of
the board, and place these DATA statements at the very end of
our program, like this:
[65)
pieces by the letters BL, red pieces by the letters RD, black kings
by the letters BK, and red kings by the letters RK. Here's the sub-
routine:
[66]
even, then the square is black. But how do we tell the difference
between an odd and even sum? The simplest way is to divide the
sum by 2, chop off any fractional value with the INT function, and
multiply the result by 2. If the result of these operation is equal to
the original sum, then the sum was even. If it is not equal to the
original sum, then the sum was odd. Line 1080 does all of this to
see if the square is red, printing the red symbol if it is. If it is not
red, and there is no piece on the square, line 1090 assumes it is
black and prints the black symbol. If the square is occupied, lines
1100 through 1130 print the symbol for the piece that is on the
square. Notice that line 1080 does not check to see if the square is
unoccupied before printing the red symbot since red squares can
never be occupied.
We'll call this subroutine to draw the initial picture of the
board, like this:
Finally, it's time for the game to begin. The following instruc-
tions will be executed for every move in the game, until someone
wins. First, we prompt the current player (CP) to make a move:
[67]
2000 PRINT "ROW"; : INPUT ROW
2010 IF ROW<1 OR ROW>8 THEN PRINT "NO SUCH ROW. TRY
AGAIN" : GOTO 2000
2020 PRINT "COLUMN"; : INPUT COL
2030 IF COL<1 OR COL>8 THEN PRINT "NO SUCH COLUMN. TRY
AGAIN" : GOTO 2020
2040 RETURN
[68]
pieces that have made it all the way across the board and gained
the power to move in all directions. Kings have an identifying
number that is 2 greater than the player's usual identifying num-
ber; hence, we also have to check to see if CB(Rl,Cl) is equal to
CP+2. Line 150 does both:
Once again, we call the subroutine at line 2000 to input the row
and column numbers:
[69]
checkers. And what are those rules? Well, the easiest one, in terms
of checking for a legal move, is that the destination square may
not already be occupied by a piece. We can check for that possi-
bility like this:
[70]
Meanwhile, if the requested move passes the first test, we
must also check to see if the piece was moved in the proper direc-
tion-that is, in the direction of our opponent's side of the board.
If we are playing black, this means that we must move from the
low-numbered rows to the high-numbered rows. If we are playing
red, we must move from the high-numbered rows to the low-
numbered rows. We can check to see which direction we have
moved by subtracting the source row (R1) from the destination
row (R2). For black (player 1), the result should be 1. For red
(player 2), the result should be -1. Since we will be performing
this particular check a couple of times (as you will see), we will
first set up a variable called LM ("legal move") that will hold the
proper result for the current player (CP), like this:
[71]
move. If the move is legal, we must jump ahead to the routine that
makes the move, like this:
Now, we must consider those moves that failed the test in lines
230 and 240, because they moved more than one square. As we
said before, the only case in which a player may move more than
one square either horizontally or vertically is when an opponent's
piece is being jumped and captured. In this case, the player's piece
may be moved two squares horizontally and two squares vertical-
ly. Once again, we will use the ABS function to see if CI-C2 and
Rl- R2 are equal to either 2 or - 2:
If the move fails either test, we jump ahead to line 460, which tells
the player that he or she has made an illegal move.
Next, we must check again to see if the player was moving in a
legal direction. As before, we test for the direction by subtracting
Rl from R2. But now the result can be either 2 or - 2, so we must
multiply variable LM by 2:
Even if the move passes these tests, we must still make sure
that one of the opponent's pieces has been jumped and captured.
Therefore, we must check to see what was in the square that the
player has jumped over.
But how do we determine the number of the square that was
jumped? The square will be halfway between the source square
and the destination square. Thus, we can take the difference
between R 1 and R2, and the difference between Cl and C2,
[72]
divide each by 2, and add the results to the row and columns
numbers of the source square. This gives us the number of the
square that was jumped. Then we must check this square to see if
it contains the opponent's number (OP), like this:
And we must remove the piece from the square that was jumped,
by setting that square equal to 0:
These lines set the destination square equal to the number of the
piece on the source square, then set the source square equal to O.
If the current player's piece has reached the opposite side of
the board for the first time on this move, we must make it into a
king. Here we check to see if we have reached the "king row," the
number of which is contained in variable KR:
[73]
Notice that line 350 not only checks to see if the destination
square is on the king row, but also checks to see if the piece on
that square is already a king (that is, if it has a value greater than
2). If we are not on the king row, or if the piece is already a king,
we skip line 360, which announces the conversion of the piece to
a king and increases the piece's value by 2, to indicate its new
status.
As a last order of business before we go on to the next player's
move, we must check to see if we have a winner yet. Obviously,
this won't happen on the first time through this loop, but we will
check for it after every move just to be safe:
370 FL=O
380 FOR ROW=1 TO 8
390 FOR COL=1 TO 8
400 IF CB(ROW,COL)=OP THEN FL=1
410 NEXT COL
420 NEXT ROW
430 IF FL=O THEN 470
[74]
440 IF CP=1 THEN CP=2 : OP=1 : GOTO 100
450 CP=1 : OP=2 : GOTO 100
[75]
Another feature that is mIssmg here is the "forced jump."
Once again, standard checkers rules require that a player make a
jump if it is available, even if the jump will place his or her piece
in an undesirable position. This rule is not included here, but
could be added.
In fact, you could add both of these features with the addition
of a single subroutine. What would this subroutine do? It would
look for jumps that the current player could make. First, it would
scan the board looking for the current player's pieces. Then, when
it found a square containing such a piece, it would scan the
squares attached diagonally to that square, to see if the opposing
player has pieces on those squares. Finally, it would scan the
squares diagonally past the opposing player's pieces to see if they
are empty, which would mean that the opposing player's piece
could be jumped. If a possible jump is found, this information
would be recorded-perhaps by setting a flag variable (such as
the FL variable we use to detect a winning move) equal to a spe-
cial code number.
This subroutine could be called to see if the current player
should be forced to make a jump. If a jump (or more than one
jump) is available, the program would not accept any move that
isn't a jump.
After a jump is made, the subroutine could be called a second
time to see if a multiple jump is possible. If so, the player would
be called on to make the jump-or the program could make the
jump automatically. However, if more than one jump is available,
the player would have to choose which jump to make.
And, of course, you could also add graphics to this program-
and to any of the programs in this book. Since the drawing of the
checkerboard is done entirely by the subroutine at line 1000, you
would need only to replace this subroutine with a subroutine of
your own, which would use your computer's graphics capabilities
to draw a picture of the board. Of course, you would also need to
rewrite all statements that PRINT sentences on the screen, so that
they don't ruin your neatly planned graphics display.
[76]
Here is the complete program:
20 DIM CB(8,8)
30 CP=1 : OP=2
40 FOR ROW=1 TO 8
50 FOR COL=1 TO 8
60 READ A
70 CB(ROW,COL)=A
80 NEXT COL
90 NEXT ROW
100 GOSUB 1000
110 PRINT: PRINT "PLAYER";CP;"- IT'S YOUR MOVE"
120 PRINT "WHICH PIECE DO YOU WISH TO MOVE?"
130 GOSUB 2000
140 R1 =ROW : C1 =COL
150 IF CB(R1,C1)=CP OR CB(R1,C1)=CP+2 THEN 170
160 PRINT "YOU DON'T HAVE A PIECE THERE!" : GOSUB 1000 :
GOTO 120
170 PRINT "WHERE DO YOU WISH TO MOVE THE PIECE?"
180 GOSUB 2000
190 R2=ROW: C2=COL
200 IF CB(R2,C2)<>0 THEN PRINT "THAT SQUARE IS OCCUPIED":
GOSUB 2000 : GOTO 170
210 IF CP=1 THEN LM=1 : KR=8
220 IF CP=2 THEN LM= -1 : KR=1
230 IF ABS(C1-C2)<>1 THEN 270
240 IF ABS(R1-R2)<>1 THEN 270
250 IF (R2-R1 <>LM) AND (CB(R1 ,C1)<3) THEN 460
260 GOTO 330
270 IF ABS(C1-C2)<>2 THEN 460
280 IF ABS(R1-R2)<>2 THEN 460
290 IF (R2-R1 <>LM*2) AND (CB(R1 ,C1)<3) THEN 460
300 IF CB(R1 +(R2-R1)/2,C1 +(C2-C1)f2)<>OP THEN 460
310 PRINT "YOU HAVE CAPTURED A PIECE!"
320 CB(R1 +(R2-R1)/2,C1 +(C2-C1)/2)=0
[77]
330 CB(R2,C2)=CB(R1 ,C1)
340 CB(R1,C1)=0
350 IF (R2<>KR) OR (CB(R2,C2»2) THEN 370
360 PRINT "YOU HAVE GAINED A KING!" :
CB(R2,C2)=CB(R2,C2)+2
370 FL=O
380 FOR ROW=1 TO 8
390 FOR COL=1 TO 8
400 IF CB(ROW,COL)=OP THEN FL=1
410 NEXT COL
420 NEXT ROW
430 IF FL=O THEN 470
440 IF CP=1 THEN CP=2 : OP=1 : GOTO 100
450 CP=1 : OP=2 : GOTO 100
460 PRINT "ILLEGAL MOVE" : GOSUB 1000: GOTO 120
470 GOSUB 1000
480 PRINT "CONGRATULATIONS, PLAYER";CP
490 PRINT "YOU HAVE WON!"
500 PRINT "WOULD YOU LIKE TO PLAY AGAIN?"
510 PRINT "(1 =YES, 2= NO)"
520 INPUT 0
530 IF 0=1 THEN 30
540 IF 0=2 THEN END
550 GOTO 520
1000 PRINT" ";
1010 FOR COL=1 TO 8
1020 PRINT COL;" ";
1030 NEXT
1040 PRINT
1050 FOR ROW=1 TO 8
1060 PRINT ROW;
1070 FOR COL=1 TO 8
1080 IF INT((ROW+COL)/2)*2=(ROW+COL) THEN PRINT" = ="; :
GOTO 1140
1090 IF CB(ROW,COL)=O THEN PRINT" -- "; : GOTO 1140
[78]
1100 IF CB(ROW,COL)=1 THEN PRINT "BL ";: GOTO 1140
1110 IF CB(ROW,COL)=2 THEN PRINT "RD ";: GOTO 1140
1120 IF CB(ROW,COL)=3 THEN PRINT "BK "; : GOTO 1140
1130 IF CB(ROW,COL)=4 THEN PRINT "RK ";
1140 NEXT COL
1150 PRINT
1160 NEXT ROW
1170 RETURN
2000 PRINT "ROW"; : INPUT ROW
2010 IF ROW<1 OR ROW>8 THEN PRINT "NO SUCH ROW. TRY
AGAIN" : GOTO 2000
2020 PRINT "COLUMN"; : INPUT COL
2030 IF COL<1 OR COL>8 THEN PRINT "NO SUCH COLUMN. TRY
AGAIN" : GOTO 2020
2040 RETURN
3000 DATA 0,1,0,1,0,1,0,1
3010 DATA 1,0,1,0,1,0,1,0
3020 DATA 0,1,0,1,0,1,0,1
3030 DATA 0,0,0,0,0,0,0,0
3040 DATA 0,0,0,0,0,0,0,0
3050 DATA 2,0,2,0,2,0,2,0
3060 OAT A 0,2,0,2,0,2,0,2
3070 DATA 2,0,2,0,2,0,2,0
[79]
CHAPTER SIX
ALL
THE WORLD'S
A GAME
[81]
A three-dimensional array could represent a portion of outer
space-or a scaled-down model of the entire universe,-with the
subscripts indicating how far up, down, left, right, or sideways
each element is from some starting point. Elements could be
assigned numbers to indicate whether they represent stars, plan-
ets, or just empty space. Players could move through the universe
simply by changing elements in the array.
Of course, it would take an imaginative programmer to devise
pictures to do justice to such an array. You could fill the video
display with stars and planets and spaceships, to show the player
what kind of universe the array represents. And that's what com-
puter game simulations are all about-converting your imagina-
tion into numbers inside the computer, then converting those
numbers back into something that a person can sit down at the
computer and play with.
In this book, we've given you a starting point for creating sim-
ulations of your own. Now, go ahead and think of new games to
simulate, and write the programs yourself.
Even the sky isn't the limit!
[82]
INDEX
[83]
Checking programs, checkers, in checkers, 64
68-72, 74 in tic-tac-toe, 54, 55; see
Checking programs, tic-tac- also Data structure
toe, 56-60, 68 ENTER command, 7, 8
Commands. See DIM; ENTER;
FOR-NEXT; GOSUB; FOR-NEXT command, 8,9
GOTO; INPUT; LET; in card games, 19-20, 23,
PRINT; READ; REM; RE- 29
TURN; RUN; SOUND in checkers, 65; see also
Commodore computer instruc- Loops
tions, card games, 18, 24, 44 "Forced jump," 76
Commodore computer instruc- Functions. See ABS function;
tions, tic-tac-toe, 60 INT function; RND function
Computer, definition of, 2
Chessboard, 81 Go Fish, 14-52
complete program for, 45-
Data statements. See Data 52
structure GOSUB. See Subroutines and
Data structure, 3, 18 card games; Subroutines and
of card games, 13, 15 checkers; Subroutines and
of checkers, 65; see also tic-tac-toe
Arrays GOTO command in card
Dealing cards, 14, 20-24, 36- games, 20
37,42 Graphics, 3, 44; see also Draw-
Decision making, 39 ing board games
Denominations, 16, 30-42; see
also Numbering cards IBM computer instructions for
DIM command, 5, 11, 18 card games, 18, 44
Dimension, See DIM command Improvements, 44, 75-76
Drawing board games, 55-56, INPUT command, 7, 8
65-67 in card games, 41, 44
in tic-tac-toe, 60
Elements, 6-11, 18 Instruction. See Assignment
defined,5 statement; Routine; Subrou-
in card games, 18, 22, 29 tine; and specific commands
[84]
Instructions for Apple comput- Moving checkers, 67-74; see
er, 8, 21-22, 26, 28, 56, 60 also "Forced jump"
Instructions for Atari comput- Multidimensional arrays, 10,
er, 18, 22, 26, 28, 56 11
Instructions for Commodore
computer, 18, 22, 60 Naming cards, 26-27, 31-32
Instructions for Radio Shack Nested loops, 19-20,30, 65,
computer, 18, 22, 44 74
Instructions for Timex Sinclair Numbering cards, 26-27; see
computer, 18,28 also Denominations
International Business Ma- Numeric variables. See Vari-
chine. See IBM computer in- ables, numeric
structions
INT function in checkers, 67 One-dimensional arrays, 10,
Internal memory, 3, 10 11
Interrupt function. See INT
function in checkers Pascal language, 3
Pause in the program, 41
Kilobytes, 10; see also Internal Pictures, See Graphics
memory PRINT command, 4
in card games, 26, 43
Legality of checkers program, in checkers, 67
68-72, 74 in tic-tac-toe, 58
LET command, 4 Program, Checkers, 77-79
Limitations of computer, 10 Program, Go Fish, 45-51
Loops, 8, 9, 20 Program, Tic-tac-toe, 61-62
in card games, 19-20, 23, Programming, 1, 2, 4-11
29,31, 34, 36, 37, 42,
43 Radio Shack computer instruc-
in checkers, 74, 75 tions, card games, 18, 22, 44
in tic-tac-toe, 57, 59, 60, Random function. See RND
65 function
READ command and checkers,
Maps, 81 65
Memory, See Internal memory REM command, 38
[85]
RETURN command, 7 Three-dimensional arrays, 10,
and card games, 20 82
RND function in card games, Tic-tac-toe, 53-62
21-22, 39 complete program of, 60-
Routine, card game, 18, 33; see 62
also Subroutine Timex-Sinclair computer in-
RUN command, 8 structions, card games, 18,
28
SOUND command, 44 Two-dimensional arrays, 10, 81
Stopping a game, 58 in card games, 16, 17
Storage, computer. See Memo- in tic-tac-toe game, 53, 54,
ry 64
Strategy, card, 39, 45
Subroutines and card games, Variables, definition of, 3
1~ 1~ 20, 23, 27-34, 37- Variables in card games, 19,
38, 40, 43 22, 23, 30-32, 35-36, 39, 41
Subroutines and checkers, 65- Variables in checkers, 64, 68,
68, 75 69, 71, 73, 74
Subroutines and tic-tac-toe, Variables in tic-tac-toe, 54-57,
55-56 59
Subscript, 6-11 Variables, numeric, 4, 6, 8
definition of, 5 Value, 6, 69, 74
[86]
ABOUT THE AUTHOR