Paintings & Links
CS 160 Green Sheet, Spring 2002
Prof. Rudy Rucker, MH 213, 924-5147, email@example.com
Office Hours: 10:30 - 11:45 T, Th
Class Meets 9:00 - 10:15 AM, TTh in SCI 311.
Midterm: Thursday, March 21.
Final Demo: Wednesday, May 22, 7:15 - 9:30
This course studies how software engineers organize and carry
out large software projects in groups.
Over the semester,
the students will complete substantial software projects in the
form of computer games.
In the first part of the course, we study principles of software
engineering, including the requirements and specification, the software
lifecycle, project management, working in teams, and techniques
for giving effective presentations. We discuss the object oriented
style of software engineering, including analysis, design, best
OO practics, and the use of software patterns. We illustrate the
ideas with discussions of two particular software frameworks the
students will use for their class projects: the Windows MFC framework
for document/view architectures and the Pop framework for computer
In the second part of the course, students will work on projects
in teams generally of three individuals each, the teams picked by
the instructor. The projects will be computer games based on the
Pop framework, with specifications that have been developed by requirements
gathering processes starting early in the semester, and with designs
developed in stages as well. In the final phase, teams work on their
projects in class with the professor moving from team to team to
give advice. The projects will use the C++ language rather than
Java, and the projects will be for the Windows platform.
To use our lab machines you must either (a) register for CS 110L
(you will need to get an add code) or (b) pay a one-time "orange
form" lab fee of $45 to the MathCS department at MH 208.
This gives you accounts on Suns, Windows, and Linux machines, and
gives you a 40 MB disk quota on your /home or J: drive. Pick up
your account ID at the WSQ1 Lab.
The required texts and software for the course are:
Rucker, Software Engineering and Computer Games, Spring,
2002 Edition. (Available in photo-offset at the SJSU Bookstore starting
late January, 2001. Do not get a used Fall, 2001 version
of Software Engineering and Computer Games, as this will
The Book Website www.cs.sjsu.edu/faculty/rucker/videogameprojects.htm
has links for downloading the Pop software we use in this course.
You can also get this software from the K: drive on the SJSU local
Visual Studio, version 6.0. You may rent the installation disks
for $30.00 for four days from the SJSU bookstore and legally install
the software on your machine. Do not try to
use version 5.0 or earlier of Visual C++ in this course.
Get the software installed as soon as possible.
Grades will be based on individual writing and programming assignments
(~60 pts), on a written in-class midterm (50 pts), and on the team
project (~80 pts). For the final exam we will have final
classroom demos of the student projects.
project grades within a team may vary according to the contributions
of the individual students to the project.
Programs are to be submitted in a two-pocket folder holding (1)
a floppy or CD disk or disks with runnable Windows *.EXE file (possibly
WinZipped) with buildable source code and (2) printed documentation.
Source code should build with no warning messages. Specs and documentation
should be attractively formatted and printed out. Assignments are
due at the START OF CLASS on the due dates. Assignments will be
graded down 20% for 1-7 days late. Assignments later than 7 days
will not be accepted. WARNING: Skipping an assignment can lower
your grade by a full point.
The prerequisite for this course is a C- grade or higher in both
the CS 146 course and in the CS100W writing course. If are
registered and do not satisfy the prerequisite, the instructor can
and will drop you from the course at any time. You must
show written proof to me of having satisfied the 146 and 100W prerequisites.
Absolutely no exceptions to this rule will be made.
Cheating policy: Copying on an exam will result in a score of 0
on that exam for both parties.
The Book Website has links for downloading
the Pop software we use in this course. You can also get this
software from K:\rucker\cs160 on the SJSU local network.
Write out your answers to
Exercises 1 and 2 in Chapter One of Rucker's book.
Must be typed, spell-checked, and printed, two to five pages long.
Exercise 1: Beginning to think about your project. In the
following series of questions, I'd like you to begin trying to work
out what you might do. As you go further in this book you'll get
a better idea of what things might be possible, and you can then
come back and revise your answers to these questions. Write down
your answers to these questions. (A) What are two computer programs
you really like? Say what it is that you like about them. These
can be any kind of program at all. (B) What is a "dream"
program would you like to write if you didn't have to worry about
actually getting the code written? Write out some of the great features
you'd like for this program to have. If you have ideas for several
different dream programs put them all down. (C) What are some areas
of programming you think you'd need to learn about to write some
really great programs? Try to be as specific as you can. (D) What
is an easy program you're fairly sure you might be able to do, assuming
that you got a little help along the way? If you have several ideas
put them all down. (E) What are some features you could add to an
easy program to make it more like a great dream program? If you
have several ideas put them all down.
Exercise 2: Dream and reality. Spend a half hour running
the Pop program. Assume that you're going to build your project
by extending this code. Rethink your answers to Exercise 1. Now
write up an idea for a game project you think you might like to
do. Explain what would be the concept of the game, how the user
controls might work, and draw a picture (picture can be hand-drawn)
of how you think your game screen might look.
Assignment 2 .
Develop a systematic test procedure for the Pop executable and
help file. Use it to find bugs or bad features, at least three,
preferably more. Credit for each reproducible bug (or bad feature),
large or small, that you find. (For a bug to be "reproducible,"
you need to give exact instructions for how to make it happen.)
I'd like you to look for these three kinds of problems.
Bugs. For full credit, explain exactly how to reproduce the
bug. Bad documentation. Find are the cases where the Help
file description does not seem to match the behavior of the program.
Also note cases where some program feature is not well-explained.
Bad Features. Features of the program (or framwork) that
you find bad or confusing. Explain what you don't like.
Bugs found in Pop 24_2
Assignment 3. Due Tuesday March 5, 2002. 30 Pts.
Updated Friday, Feb 22, 2002, 4:30 PM.
Change cGameStub into a 2D Space Invaders game as described in
the new guidelines. DON'T use
what's printed in the book.
8 Pts Mechanics) Be sure to put your name on the program
caption bar so I know you wrote the program! To change the caption
bar, see section the textbook.
What to hand in:
A sheet of paper describing the controls of your game and listing
any Special Features you added.
Two disks: one with the executable in the root directory. And a
disk with clean, buildable source code. LABEL the disks with your
NAME and either EXE or SOURCE.
Put disks and paper in a two-pocket folder with your name on it.
14 Pt. Basically Working) Get the program working following
the guidelines.. The critters
should be neither too hard nor too easy to hit, the game itself
should be neithr too hard or too easy. You may need to tweak some
params to get it right.
Up to 8 Pts Additional) Make the game better than my example.
Possibilities: Change the background, Use different kinds of sprites,
Add code to make the game get progressively harder, Change the code
so that the enemies jiggle back and forth like in the traditional
Space Invaders rather than running away from bullets. Add sound.
Have the enemies change appearance when you hit them before disappearing,
maybe have them shatter or show an explosion bitmap for a few seconds.
Don't forget to put your name on the program caption bar.
Write a preliminary specification of a game you would like to design
by using Pop Framework code as a starting point. Include one
or more sketches of the play screen, sketches of the popup menus
and any dialogs, along with a brief User's Guide which specifies
Menu controls, toolbar buttons, cursor tools, and scoring.
Midterm will be a written test. Review questions are in the textbook.
There will be a kind of programming component. as follows. I'll
assign a design/programming problem to work on out of class and
will ask you a written question about your work in the test.
Use my feedback and the classroom and group discussions to write
a new specification for a game project you'd like to do with your
group. Bring in a copy for me and for each group member.
Group Assignment 6
Write a specificaiton and requirement for the project your group
now plans to do. Break the feature set into a Stage One (alpha)
and a Stage Two (beta) set. Hand in. Don't forget to include a picture.
Group Assignment 7
Rewrite the specificaiton for your project. Also draw a UML diagram
of the classes you will use, specifying the class members and methods.
Give a Powerpoint presentation about your project specification
Group Assignment 8
Alpha release of your program. Should function. Provide
executable, buildable source code, printed help file. Demo
Group Assignment 9
Beta release of your program. Should function with all intended
features in place. Provide executable, buildable source code,
printed help file and online *.HLP file. Demo in class.
Group Assignment 10
Final release and demo.
THINGS TO TRY
Exercise 7.8 Following Waypoints
In adventure games and car racing games we often want to make some
of the computer operated critters move along certain fixed paths.
Thus you might want an enemy guard to patrol a certain route, or
you might want a rival race car to drive around and around a track.
A good method to make this work is to set a series of "waypoints"
that you want the critter to follow. Implement a cForceWaypoint
which has these fields:
CArray<cVector, cVector> _waypoint;
You might also want to give cForceWaypoint an add(cVector newwaypoint)
mutator method for adding points to the _waypoint array. Suppose
that the constructor initialises _currwpindex to 0 and _closeenough
to some reasonable (relative to your world size) value like perhaps
If our waypoints are arranged in a circle, as on a race track, we
might define the cForceWaypoint force method like this.
cVector cForceWaypoint ::force(cCritter *pcritter)
if (distanceTo(_waypoint[_currwpindex]) < _closeenough)
if (currwpindex >= _waypoint.GetSize())
_currwpindex = 0;
setTangent(_waypoint[_currwpindex] - position()); //setTangent will
normalize the arg
Get this to work and then make a variation in which the critter
moves back and forth along a curving line of waypoints. You can
do this either by listing the inner points twice (once in each order),
or by using a _currwpinc field that can be either +1 or -1 to determine
the direction in which you traverse the waypoints.
///HOW TO TELL WHEN YOU CROSS A WALL
BOOL cCritterWall::blocks(const cVector& start, const cVector&
int endoutcode = outcode(end);
int startoutcode = outcode(start);
/* If crossed is TRUE then moving from start to end means moving
across the wall, even
though neither start nor end has to be close to the wall. NOte that
we are checking for
cutting across corners as well. We do this instead use a simpler
check like like
BOOL crossed = (startoutcode == BOX_LOY && endoutcode ==
startoutcode == BOX_HIY && endoutcode == BOX_LOY)), etc.
A different approach would be to look at the HIY LOY parts of the
outcodes relative to the line connecting position and oldposition;
if some are HIY
and some are LOY then the line crosses. */
crossed = (startoutcode == BOX_LOY && !(endoutcode &
(startoutcode == BOX_HIY && !(endoutcode & BOX_HIY));
/* First check for moving across
in direction of normal */
crossed |= (startoutcode == BOX_LOX && !(endoutcode &
(startoutcode == BOX_HIX && !(endoutcode & BOX_HIX));
/* Then Check for moving
across in direction of tangent (can happen either if someone wants
cut across a corner, or, less often, across whole tangent length
(usually this direction
is long, but someone could change this by choosing close endpoints
and a big
Exercise 18.7 Smarter Enemies For Maze Games
Suppose you write an adventure game in which the enemy critters
use a cForceObjectSeek to run towards the player. Suppose also that
your game has cCritterWall walls in it - think of something like
a PacMan game in which the ghosts chase the player (or, if the player
is powered-up, run away from the player).
If you use a simple cForceObjectSeek, the enemies will often get
stuck pushing against a wall they can't get through. The easiest
way out is simply to provide more enemies and expect that some of
them will manage to be a threat.
But really you'd want to create "smarter" kind of seeking
force. Let's discuss three increasingly sophisticated ways in which
we can try and improve the situation.
(a) A simple, but somewhat effective thing you could do instead
is to create a cForceObjectSeekImpatient. The idea is that this
is a seek force that will sometimes turn itself off in the hope
that the enemy might then happen to bounce into a better location.
We'll think of the default, non-seek-force motion as a "cruise"
motoin. that is, bounce off a series of walls.
Give the class these fields and initialize as suggested
int _frustration; //Start at 0
int _maxfrustration; //Try 1 to start with and then try making it
Real _oldsatisfaction; //Start at a large negative number like -1000000.0
Real _cruisetime; //Some time in seconds, like 3.0
BOOL _cruising; //Start FALSE
Real _resumeage //A scratch-paper field we can just initialize to
Now use a cForceObjectSeekImpatient force coded something like this.
cVector cForceObjectSeekImpatient::force(cCritter *pcritter)
pcritter->setSpeed(pcritter->maxspeed()); //Keep moving fast
if (pcritter->age() > _resumeage)
_cruising = FALSE;
Real newsatisfaction = -pcritter->distanceTo(_pnode); /* Use
minus so the bigger the
distance to the target, the lower your satisfaction is. */
if (newsatisfaction <= oldsatisfaction)
if (frustration <= 0)
frustration = 0;
if (frustration > _maxfrustration)
_cruising = TRUE;
_resumeage = pcritter->age() + _cruisetime;
_frustration = 0;
(b) For a more sophisticated solution, you would want to use a
cMaze class that inherits from CArray<cCritterWall *, cCritterWall*>.
As we add cCritterWall object to our world, we also put them into
It will be useful to give the cMaze class a method BOOL blocks(const
cVector& start, const cVector& end) method, which walks
through the array of member cCritterWall, checks the value of cCritterWall::blocks(start,
end) for each wall, and returns TRUE if any of the member walls
blocks the path.
In addition, we'd want to give the cMaze a CArray<cVector, cVector&>
_waypoint member, and as we added in the cCritterWall objects to
the maze, we'd want to fill _waypoint with points corresponding
to significant points in the maze's passageways. In particular,
you'd want to have a waypoint at each corner, and before and after
each gap or doorway in the maze.
Once you have the cMaze in place, you could create a cForceObjectSeekImpatientMaze
which has a cMaze *pmaze member. When "frustrated" the
force could direct the caller critter to proceed towards the nearest
waypoint of the maze. We can measure frustration as before, or simply
become frustrated right away if the cMaze blocks the path from the
enemy position to the player position.
(c) The truly correct thing to do would be to use a cMaze as in
(b), but to have a cForceSolveMaze which would determine the proper
sequence of waypoints to follow in order to get to the critter being
sought. This involves considering the tree of all non-repeating
arrays of waypoints one might visit, starting with the nearest waypoint.
We will only consider those waypoint sequences in which the maze
doesn't block the path between any two successive waypoints. And
our goal will be to reach a waypoint W such that the maze doesn't
block the path from W to the target critter. If you know a little
about AI, you would probably want to use a so-called A* search strategy;
otherwise a simple breadth-first search will work well enough, provide
your maze isn't too big.
To keep the speed of the program up it might suffice to only update
the current path of cForceSolveMaze after every ten or twenty updates.
There is a new build of Pop on the download
site. It includes code for HTML Help, see also the link to "Help
Big Discovery: To make bitmaps work will in OpenGL: Presize ALL
your bitmaps so that both sides have pixel measurements that are
an EVEN P:OWER OF TWO (16, 32, 64, 128, etc.) The two sides don't
have to equal each other, that is, you can have a rect and not a
square. Size the bitmaps in Photoshop or Windows Paint. Otherwise
the code just has to resize them anyway to be powers of two on the