Rudy Rucker's CS 160 Software Engineering









Paintings & Links



CS 160 Green Sheet, Spring 2002

Prof. Rudy Rucker, MH 213, 924-5147,
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 games.

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:

        Rudy 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 be obsolete.) The  Book Website 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 network.

        Microsoft 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. Individual 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.

Assignment 1 

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.


Asignment 4

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.

Assignment 5

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 and design.

Group Assignment 8

Alpha release of your program.  Should function.  Provide executable, buildable source code, printed help file.  Demo in class.

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.


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;
int _currwpindex;
Real _closeenough;
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 2.0.
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)
_currwpindex ++;
if (currwpindex >= _waypoint.GetSize())
_currwpindex = 0;
setTangent(_waypoint[_currwpindex] - position()); //setTangent will normalize the arg
return cVector::ZEROVECTOR;

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.



BOOL cCritterWall::blocks(const cVector& start, const cVector& end)
BOOL crossed;
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 == BOX_HIY) ||
startoutcode == BOX_HIY && endoutcode == BOX_LOY)), etc.
A different approach would be to look at the HIY LOY parts of the wallbox corners'
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 & BOX_LOY)) ||
(startoutcode == BOX_HIY && !(endoutcode & BOX_HIY)); /* First check for moving across
in direction of normal */
crossed |= (startoutcode == BOX_LOX && !(endoutcode & BOX_LOX)) ||
(startoutcode == BOX_HIX && !(endoutcode & BOX_HIX)); /* Then Check for moving
across in direction of tangent (can happen either if someone wants to
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
thickness). */
return crossed;

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 larger.
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 0.0
Now use a cForceObjectSeekImpatient force coded something like this.

cVector cForceObjectSeekImpatient::force(cCritter *pcritter)
if (_cruising)
pcritter->setSpeed(pcritter->maxspeed()); //Keep moving fast
if (pcritter->age() > _resumeage)
_cruising = FALSE;
return cVector::ZEROVECTOR;
Real newsatisfaction = -pcritter->distanceTo(_pnode); /* Use minus so the bigger the
distance to the target, the lower your satisfaction is. */
if (newsatisfaction <= oldsatisfaction)
_frustration ++;
if (frustration <= 0)
frustration = 0;
if (frustration > _maxfrustration)
_cruising = TRUE;
_resumeage = pcritter->age() + _cruisetime;
_frustration = 0;
return cForceObjectSeek::force(pcritter);

(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 the cMaze.
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 Without Tears".

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 edges.



 Home         Biography         Books        Writing         Painting        Classes         Email