Category : A Collection of Games for DOS and Windows
Archive   : CHASE.ZIP
Filename : CHASE.CPP
Output of file : CHASE.CPP contained in archive : CHASE.ZIP
* chase.cpp *
* *
* DESCRIPTION *
* A robot chase game, as found on Xenix and in other *
* implementations. *
* *
* Uses Turbo C++ conio. Can easily be rewritten *
* to use stdio at lower speed. *
* *
* Alan Meyer, 1990 *
****************************************************************/
/*************************** INCLUDES **************************/
#include
#include
#include
#include
#include
#include
/************************** CONSTANTS ****************************/
#define TRUE 1
#define FALSE 0
#define AROWS 22 // Rows in the playing area
#define ACOLS 65 // Columns in the playing area
#define SAVE_SCORES 10 // Number of saved scores
#define SAVE_NAME 9 // Max size of saved name
#define FILE_NAME 14 // Max size of file name
// Drawing characters
#define DRAW_UL 0xC9 // Upper left corner
#define DRAW_LL 0xC8 // Lower left
#define DRAW_UR 0xBB // Upper right
#define DRAW_LR 0xBC // Lower right
#define DRAW_UT 0xCB // Upper tee
#define DRAW_LT 0xCA // Lower tee
#define DRAW_V 0xBA // Vertical line
#define DRAW_H 0xCD // Horizontal line
// Printable screen chars
#define C_SPACE ' ' // Blank space
#define C_ROBOT 'R' // Robot
#define C_MAN '&' // Man
#define C_HOLE '#' // Point of collision
// Screen dimensions
#define SCREEN_UROW 1 // Upper row
#define SCREEN_LROW 24 // Lower row
#define SCREEN_LEFTCOL 1 // Left column
#define SCREEN_RIGHTCOL 80 // Right column
#define SCREEN_MIDCOL 67 // Middle column
#define SCREEN_PROMPTROW 25 // Prompt goes here
// Directions
#define HORIZ 1
#define VERT 2
// Score positions
#define STATUS_COL (SCREEN_MIDCOL + 8)
#define STATUS_SCORE 17
#define STATUS_ROUND 18
#define STATUS_ROBOTS 19
#define STATUS_BOMBS 20
#define STATUS_HIGH_ROW 3
#define STATUS_HIGH_COL 15
// Completion codes from robot move
typedef enum fin_stat {
FINISHED_MAN, // Man killed
FINISHED_ROBOTS, // All robots killed this round
NOT_FINISHED, // Still playing
FINISHED_ALL // Killed MAX_ROBOTS, won game
} FIN_STAT;
/********************** CLASS DECLARATIONS *********************/
/****************************************************************
* class Area *
* *
* DESCRIPTION *
* Maintain the playing surface. *
****************************************************************/
class Area {
private:
char area[AROWS][ACOLS+1]; // Playing area
public:
void GoRC (int row, int col);
void Clear ();
int Test (int row, int col);
void Set (int row, int col, int token);
void Reset (int row, int col);
void Move (int drow, int dcol, int srow, int scol);
void ShowOne (int row, int col);
void ShowAll ();
void Flash (int row, int col, int count);
};
/****************************************************************
* class robots *
* *
* DESCRIPTION *
* Maintain information about each robot on screen. *
****************************************************************/
#define MAX_ROBOTS 1000 // Max number of robots
#define MAX_SCORE 100500L // Max score possible with MAX_ROBOTS
class Robots {
private:
struct one_robot {
int row; // row position
int col; // column position
int live; // TRUE = alive
} robots[MAX_ROBOTS];
int in_use; // Amount of array in use
int alive; // Number currently alive
public: // Several functions need these
int man_row; // Human row
int man_col; // Column
public:
void Start (Area *a, int count);
FIN_STAT Move (Area *a, int *killed);
int Blast (Area *a);
int Hunt (Area *a,int row, int col);
};
/****************************************************************
* class Status *
* *
* DESCRIPTION *
* Keep the current status information. *
* Maintain all changes, as directed from above. *
* Show changes on screen. *
****************************************************************/
class Status {
private:
struct highs {
char hname[SAVE_NAME]; // Name of player
long hscore; // His score
} hs[SAVE_SCORES]; // Top 10 scores
char name[SAVE_NAME]; // Player name
char fname[FILE_NAME]; // File name for high scores
unsigned last_robots; // Robots at start of round
long score; // Current score
unsigned int bombs; // Number of bombs left
unsigned int round; // Round number
unsigned int robots; // Number of robots left
int bombs_per_round; // Add this num each round
int score_chg; // TRUE=High scores changed
int read_scores; // TRUE=Read scores from disk
public:
Status ();
~Status ();
int DecRobots (int count);
int GetRobots ();
int DecBomb ();
long GetScore ();
void IncRound ();
void ShowHighs ();
void Show (int what);
void Start (int robot_count);
};
/*********************** OTHER PROTOTYPES **********************/
void screen (void);
void draw (int col, int row, int num, int direct, char draw_c);
void get_string (char *prompt, char *string, int length);
void put_string (char *string);
int round (Area *a, Robots *r, Status &s);
/*************************** GLOBALS ***************************/
int G_last_stand; // TRUE=User pressed L command
char *Copyright = "CHASE Copyright 1990 Alan Meyer, AM Systems, Inc.";
/************************** FUNCTIONS **************************/
/****************************************************************
* Functions for class Area *
****************************************************************/
// Area::GoRC
//
// Move the cursor to the screen spot corresponding to
// the row column positions in the Area.
//
inline void Area::GoRC (
int row, // Row in Area, not screen
int col) // Ditto for column
{
gotoxy (col + (SCREEN_LEFTCOL + 1), row + (SCREEN_UROW + 1));
}
// Area::Clear
//
// Clear the playing area to all spaces
//
void Area::Clear ()
{
int line; // Line loop counter
// Clear entire area
memset (area, C_SPACE, sizeof (area));
// Terminate each line for cputs
for (line=0; line
}
// Area::Test
//
// Find what's at a row x column
//
inline int Area::Test (
int row, // Row to test
int col) // Column
{
return (int) (area[row][col]);
}
// Area::Set
//
// Set the value of a row/column
//
inline void Area::Set (
int row, // Row to set
int col, // Column
int token) // What to put there
{
area[row][col] = (char) token;
}
// Area::Reset
//
// Empty a row/column
//
inline void Area::Reset (
int row, // Row to clear
int col) // Column
{
Set (row, col, C_SPACE);
}
// Area::Move
//
// Move contents of one cell to another.
// Empty the source.
//
inline void Area::Move (
int drow, // Destination row
int dcol, // Column
int srow, // Source row
int scol) // Column
{
Set (drow, dcol, Test (srow, scol));
Reset (srow, scol);
}
// ShowOne
//
// Show one object (space, robot, or man) on screen
// Requires no knowledge of what the object is.
//
void Area::ShowOne (
int row, // Row of object to show
int col) // Column
{
// Go to corresponding screen position
GoRC (row, col);
// Output whatever character exists in the Area grid
putch (Test (row, col));
}
// Area::ShowAll
//
// Paint the entire playing screen.
// Done line by line rather than by individual moves.
//
void Area::ShowAll ()
{
int row; // Row index/loop counter
for (row=0; row
cputs (area[row]);
}
}
// Area::Flash
//
// Flash character on screen
// Used when man is hit and to show initial position
//
void Area::Flash (
int row, // Row to flash
int col, // Column
int count) // Number of flashes
{
int i; // Loop counter
// Flash character, interspersed with * and -
for (i=0; i
putch ('*');
delay (100);
GoRC (row, col);
putch ('-');
delay (100);
GoRC (row, col);
putch (Test (row, col));
delay (100);
}
}
/****************************************************************
* Functions for class Status *
****************************************************************/
// Status constructor
//
// Initializes high scores to none.
//
Status::Status ()
{
int i; // Loop counter
// Initialize scores
for (i=0; i
hs[i].hname[0] = '\0';
}
// No player's name yet
*name = '\0';
// No scores yet
read_scores = FALSE;
}
// Status destructor
//
// Writes scores to disk
//
Status::~Status ()
{
FILE *fp; // High scores file
int i; // Loop counter
// If the scores changed, open scores file for writing
if (score_chg) {
if ((fp = fopen (fname, "w")) != NULL) {
// Write high scores
for (i=0; i
fprintf (fp, "%s %ld\n", hs[i].hname, hs[i].hscore);
else
break;
}
fclose (fp);
}
}
}
// Status::Start
//
// Initialize variables for starting new game
// Load high scores.
//
void Status::Start (
int robot_count) // Number of robots to increment
{
FILE *fp; // High scores file
int i; // Loop counter
// Initialize all values
last_robots =
round =
bombs = 0;
score = 0L;
bombs_per_round = robot_count;
if (!read_scores) {
// Separate scores file for each num robots
sprintf (fname, "chase%d.dat", bombs_per_round);
// See if we can find a high scores file
if ((fp = fopen (fname, "r")) != NULL) {
// Get high scores
for (i=0; i
break;
fclose (fp);
// Don't do it twice
read_scores = TRUE;
}
}
}
// Status::IncRound
//
// Start a new round, setting new values for number of robots
// and bombs.
//
void Status::IncRound ()
{
// Set robots to five more than last round
robots = last_robots + 5;
last_robots = robots;
// Turn off last stand, if on
G_last_stand = FALSE;
// Give him more bombs
bombs += bombs_per_round;
// Round number
++round;
// Show the new values
Show (STATUS_SCORE);
Show (STATUS_ROUND);
Show (STATUS_ROBOTS);
Show (STATUS_BOMBS);
}
// Status::DecRobots
//
// One or more robots killed.
// Decrements number of robots, increments score.
//
int Status::DecRobots (
int count) // How many were killed
{
// Decrement robots
robots -= count;
Show (STATUS_ROBOTS);
// Increment score
score += count;
Show (STATUS_SCORE);
// Tell caller how many left
return (robots);
}
// Status::GetRobots
//
// Get the current number of robots
//
int Status::GetRobots ()
{
return (robots);
}
// Status::DecBomb
//
// One bomb used up.
//
// Returns
// TRUE = Success
// FALSE = No bombs left
//
int Status::DecBomb ()
{
if (bombs) {
--bombs;
Show (STATUS_BOMBS);
return (TRUE);
}
return (FALSE);
}
// Status::GetScore
//
// Fetch current score
//
// Returns
// Current score
inline long Status::GetScore ()
{
return (score);
}
// Status::Show
//
// Display one of the status values on screen
//
void Status::Show (
int what) // What to show, passed as column number constant
{
long num; // Value to be displayed
switch (what) {
case STATUS_SCORE: num = score; break;
case STATUS_ROUND: num = (long) round; break;
case STATUS_ROBOTS: num = (long) robots; break;
case STATUS_BOMBS: num = (long) bombs;
}
gotoxy (STATUS_COL, what);
cprintf ("%5ld", num);
}
// Status::ShowHighs
//
// Insert new high score into existing ones.
// Display high scores on midscreen
//
void Status::ShowHighs ()
{
int i, j, // Loop counters
row; // Row on screen
// If new score belongs on the chart, insert it
for (i=0; i
if (score > hs[i].hscore) {
// Copy lower scores down
for (j=SAVE_SCORES-1; j>i; j--) {
hs[j] = hs[j-1];
strcpy (hs[j].hname, hs[j-1].hname);
}
// If we don't have player's name yet, get it
get_string ("Enter your name, 8 chars max: ", name, SAVE_NAME);
// Insert new high score
strcpy (hs[i].hname, name);
hs[i].hscore = score;
// Remember that we changed one
score_chg = TRUE;
// Done
break;
}
}
// Display in clear area
row = STATUS_HIGH_ROW;
gotoxy (STATUS_HIGH_COL - 5, row);
cprintf ("High scores:");
row += 2;
for (i=0; i
gotoxy (STATUS_HIGH_COL, row);
cprintf ("%9s %5ld", hs[i].hname, hs[i].hscore);
++row;
}
}
row += 2;
gotoxy (STATUS_HIGH_COL - 5, row);
cprintf ("Score this game: %5ld", score);
if (score == MAX_SCORE) {
gotoxy (STATUS_HIGH_COL - 5, ++row);
cprintf ("Hooray! You've killed 'em all.");
}
}
/****************************************************************
* Functions for class Robots *
****************************************************************/
// Robots::Start
//
// Initialize array of robots
//
void Robots::Start (
Area *a, // Pointer to area class
int count) // Number of robots to start with
{
int i; // Loop counter
one_robot *r; // Ptr to robot
// Seed generator from clock
randomize ();
// Clear array
a->Clear ();
// Initialize robots
r = robots;
for (i=0; i
r->row = rand () % AROWS;
r->col = rand () % ACOLS;
} while (a->Test (r->row, r->col) != C_SPACE);
r->live = TRUE;
a->Set (r->row, r->col, C_ROBOT);
++r;
}
// Remember count
in_use =
alive = count;
// Place man somewhere in the field
do {
man_row = rand () % AROWS;
man_col = rand () % ACOLS;
} while (a->Test (man_row, man_col) != C_SPACE);
a->Set (man_row, man_col, C_MAN);
}
// Robots::Move
//
// Move all of the robots towards the man
//
// Returns
// FINISHED_MAN = Killed him
// FINISHED_ROBOTS = Killed all robots
// NOT_FINISHED = Still running
//
// Also tells caller how many robots were killed.
//
FIN_STAT Robots::Move (
Area *a, // Ptr to area
int *killed) // Number of robots killed
{
int i, // Loop counters
old_live, // Number alive at start
trow, // Temporary new row
tcol; // Temporary new column
one_robot *r; // Ptr to robot
FIN_STAT retcode; // Return code
// Initialize
retcode = NOT_FINISHED;
old_live = alive;
// Erase all robots from the playing area
// Avoids collisions with robots which haven't yet moved
// Positions will be restored when each one moves
for (i=0; i
a->Set (robots[i].row, robots[i].col, C_SPACE);
// Move live robots
r = robots;
for (i=0; i
// Find new row
if (man_row > r->row)
trow = r->row + 1;
else if (man_row < r->row)
trow = r->row - 1;
else
trow = r->row;
// New column
if (man_col > r->col)
tcol = r->col + 1;
else if (man_col < r->col)
tcol = r->col - 1;
else
tcol = r->col;
// Change is based on what is already at new place
switch (a->Test (trow, tcol)) {
case C_MAN:
// Hit human
a->Flash (trow, tcol, 10);
retcode = FINISHED_MAN;
break;
case C_ROBOT:
// Collision with live robot, kill it & fall through
Hunt (a, trow, tcol);
// Fall through
case C_HOLE:
// Collision with dead body
a->Set (trow, tcol, C_HOLE);
r->live = FALSE;
--alive;
break;
case C_SPACE:
// No hit
a->Set (trow, tcol, C_ROBOT);
}
// Update position
r->row = trow;
r->col = tcol;
}
// Next robot
++r;
}
// Update info for caller
*killed = old_live - alive;
// Update screen
a->ShowAll ();
// If didn't kill man, then if no robots left, then finished 'em.
if (retcode == NOT_FINISHED)
if (!alive)
retcode = FINISHED_ROBOTS;
return (retcode);
}
// Robots::Blast
//
// Blow up all the robots around the man
//
// Returns
// Number killed
//
int Robots::Blast (
Area *a) // Pointer to playing area
{
int killed; // Body count
// None yet
killed = 0;
// Hunt up
if (man_row > 0) {
killed += Hunt (a, man_row - 1, man_col);
if (man_col > 0)
killed += Hunt (a, man_row - 1, man_col - 1);
if (man_col < ACOLS+1)
killed += Hunt (a, man_row - 1, man_col + 1);
}
// Hunt down
if (man_row < AROWS-1) {
killed += Hunt (a, man_row + 1, man_col);
if (man_col > 0)
killed += Hunt (a, man_row + 1, man_col - 1);
if (man_col < ACOLS-+1)
killed += Hunt (a, man_row + 1, man_col + 1);
}
// Hunt sideways
if (man_col > 0)
killed += Hunt (a, man_row, man_col - 1);
if (man_col < ACOLS-1)
killed += Hunt (a, man_row, man_col + 1);
// Return count
return (killed);
}
// Robots::Hunt
//
// Find out which robot, if any, exists at a space
// If there is one there, kill him
//
// Returns
// Number of robots killed, 0 or 1.
//
int Robots::Hunt (
Area *a, // Playing area
int row, // Putative row
int col) // Column
{
int i, // Loop counter
killed; // Body count
// None yet
killed = 0;
// Only search if there will be a hit
if (a->Test (row, col) == C_ROBOT) {
// Search the array, stopping if we find a hit
for (i=0; i
if (robots[i].col == col)
if (robots[i].live) {
a->Set (row, col, C_SPACE);
robots[i].live = FALSE;
++killed;
--alive;
break;
}
}
}
return (killed);
}
/****************************************************************
* Independent Functions *
****************************************************************/
// screen
//
// Draw the invariant parts of the screen.
// Borders, instructions, status labels.
//
void screen (void)
{
static char *screen_text[] = {
" Commands ",
" ÄÄÄÄÄÄÄÄ ",
" 7 8 9 ",
" \\ | / ",
" 4 - 5 - 6 ",
" / | \\ ",
" 1 2 3 ",
" ",
" T=Teleport ",
" B=Bomb ",
" Sp=5=Stand ",
" L=LastStand",
" ",
" Status ",
" ÄÄÄÄÄÄ ",
" Score ",
" Round ",
" Robots ",
" Bombs ",
""
};
int i, // Index into screen_text
line; // Line counter
char *t; // Ptr to lines of screen text
// Clear screen
clrscr ();
// Draw 4 corners and two tees
gotoxy (SCREEN_LEFTCOL, SCREEN_UROW); putch (DRAW_UL);
gotoxy (SCREEN_LEFTCOL, SCREEN_LROW); putch (DRAW_LL);
gotoxy (SCREEN_RIGHTCOL, SCREEN_UROW); putch (DRAW_UR);
gotoxy (SCREEN_RIGHTCOL, SCREEN_LROW); putch (DRAW_LR);
gotoxy (SCREEN_MIDCOL, SCREEN_UROW); putch (DRAW_UT);
gotoxy (SCREEN_MIDCOL, SCREEN_LROW); putch (DRAW_LT);
// Draw horizontal lines
draw (SCREEN_LEFTCOL + 1, SCREEN_UROW,
SCREEN_MIDCOL - 2, HORIZ, DRAW_H);
draw (SCREEN_MIDCOL + 1, SCREEN_UROW,
SCREEN_RIGHTCOL - (SCREEN_MIDCOL + 1), HORIZ, DRAW_H);
draw (SCREEN_LEFTCOL + 1, SCREEN_LROW,
SCREEN_MIDCOL - 2, HORIZ, DRAW_H);
draw (SCREEN_MIDCOL + 1, SCREEN_LROW,
SCREEN_RIGHTCOL - (SCREEN_MIDCOL + 1), HORIZ, DRAW_H);
// Vertical lines
draw (SCREEN_LEFTCOL, SCREEN_UROW + 1, SCREEN_LROW - 2, VERT, DRAW_V);
draw (SCREEN_MIDCOL, SCREEN_UROW + 1, SCREEN_LROW - 2, VERT, DRAW_V);
draw (SCREEN_RIGHTCOL, SCREEN_UROW + 1, SCREEN_LROW - 2, VERT, DRAW_V);
// Text in right box
i = 0;
line = SCREEN_UROW + 1;
while (*screen_text[i]) {
t = screen_text[i];
gotoxy (SCREEN_MIDCOL + 1, line);
cputs (t);
++line;
++i;
}
}
// draw
//
// Draw a line.
//
void draw (
int start_col, // Starting column
int start_row, // Row
int num_chars, // Number of chars to draw
int direct, // Direction, horizontal right or vertical down
char draw_char) // Character graphic to place on screen
{
int i, // Loop counter
row; // Changing row value
// Horizontal line
if (direct == HORIZ) {
gotoxy (start_col, start_row);
for (i=0; i
}
// Vertical line
else {
row = start_row;
for (i=0; i
putch (draw_char);
++row;
}
}
}
// get_string
//
// Display a prompt on the bottom line and get a string.
//
// Returns
// TRUE = Got answer
// FALSE = No answer
//
#define BACKSPACE 8
#define ENTER 13
void get_string (
char *prompt, // Prompt string
char *string, // Put result here
int length) // Max length, including null
{
int c, // Entered character
i, // Loop counter
rlen, // Result string length
plen; // Prompt string length
// Display prompt
put_string (prompt);
// Find place where input goes
plen = strlen (prompt);
rlen = 0;
// Put cursor on screen
_setcursortype (_NORMALCURSOR);
// Get result, handling backspace and return
do {
c = getch ();
// Printable character
if (c > 31 && c < 127 && rlen < (length - 1)) {
*(string + rlen) = c;
putch (c);
++rlen;
}
// Backspace
else if (c == BACKSPACE && rlen > 0) {
gotoxy (plen + rlen, SCREEN_PROMPTROW);
putch (C_SPACE);
gotoxy (plen + rlen, SCREEN_PROMPTROW);
--rlen;
}
} while (c != ENTER);
// Remove cursor
_setcursortype (_NOCURSOR);
// Remove all this from the screen
gotoxy (1, SCREEN_PROMPTROW);
for (i=0; i<(plen+rlen); i++)
putch (C_SPACE);
// Terminate string
*(string + rlen) = '\0';
}
// put_string
//
// Display a string on the bottom line.
//
void put_string (
char *string) // String to display
{
// Display string
gotoxy (1, SCREEN_PROMPTROW);
cprintf (string);
}
// round
//
// Play one round, making one move.
//
// Returns
// Game termination code.
// FINISHED_MAN = Man killed.
// FINISHED_ROBOTS = All robots killed.
// NOT_FINISHED = Neither happened this round.
//
int round (
Area *a, // Playing area
Robots *r, // Robot control
Status &s) // Scores
{
int c, // User input character
retcode, // Return code
input_ok, // TRUE=Valid input received
killed, // Number killed
trow, // Temp row
tcol; // Temp column
// User input
do {
// Clear cursor every round, e.g., in case game interrupted by tsr
_setcursortype (_NOCURSOR);
// Cover many cases with defaults
trow = r->man_row;
tcol = r->man_col;
// Clear old position, will move or restore it later
a->Set (trow, tcol, C_SPACE);
// No input if user asked for last stand
if (!G_last_stand) {
// Get user input
c = getch ();
// Erase previous message, if any
put_string (" ");
// Execute command
switch (c) {
case '1':
++trow;
--tcol;
break;
case '2':
++trow;
break;
case '3':
++trow;
++tcol;
break;
case '4':
--tcol;
break;
case '5':
case ' ':
break;
case '6':
++tcol;
break;
case '7':
--trow;
--tcol;
break;
case '8':
--trow;
break;
case '9':
--trow;
++tcol;
break;
case 'T':
case 't':
do {
trow = rand () % AROWS;
tcol = rand () % ACOLS;
} while (a->Test (trow, tcol) == C_HOLE);
break;
case 'B':
case 'b':
// Eliminate everything around
if (s.DecBomb ()) {
if (!s.DecRobots (r->Blast (a)))
retcode = FINISHED_ROBOTS;
}
else
// No bombs left, invalidate move
trow = -1;
break;
case 'L':
case 'l':
G_last_stand = TRUE;
break;
default:
// Unknown key. Render input invalid
trow = -1;
}
}
// Make sure change was valid
input_ok = TRUE;
if (trow < 0 || trow == AROWS || tcol < 0 || tcol == ACOLS
|| a->Test (trow, tcol) == C_HOLE) {
put_string ("Invalid");
input_ok = FALSE;
}
} while (!input_ok);
// Erase last position
a->ShowOne (r->man_row, r->man_col);
// Check if we ran into a robot
if (a->Test (trow, tcol) != C_SPACE) {
a->Flash (trow, tcol, 10);
retcode = FINISHED_MAN;
}
else {
// Move man
r->man_row = trow;
r->man_col = tcol;
a->Set (trow, tcol, C_MAN);
a->ShowOne (r->man_row, r->man_col);
retcode = NOT_FINISHED;
}
// Move robots
if (retcode == NOT_FINISHED) {
retcode = r->Move (a, &killed);
if (killed)
s.DecRobots (killed);
}
return (retcode);
}
/***************************** MAIN ****************************/
main (int argc, char **argv)
{
int stat, // Result of playing one round
r_count; // Num robots, from command line
Area *a; // Playing area
Robots *r; // Robot array
Status s; // Scores, etc.
char again[2]; // Response to play again
// Default number of robots per round
r_count = 1;
// Get optional parameter
if (argc > 1) {
r_count = atoi (argv[1]);
if (r_count < 1 || r_count > 5) {
printf ("usage: chase {Num_robots (1..5)}\n");
exit (1);
}
}
// Allocate required space
a = new Area;
r = new Robots;
if (a == NULL || r == NULL) {
printf ("Insufficient memory\n");
exit (1);
}
// Initialize screen
_setcursortype (_NOCURSOR);
screen ();
do {
s.Start (r_count);
do {
// Setup robots and scores
s.IncRound ();
r->Start (a, s.GetRobots ());
a->ShowAll ();
// Show player where man is
a->Flash (r->man_row, r->man_col, 4);
// Play until one side or the other wins
do {
stat = round (a, r, s);
} while (stat == NOT_FINISHED);
// Can only accomodate so many robots
if (s.GetScore() == MAX_SCORE)
stat = FINISHED_ALL;
} while (stat == FINISHED_ROBOTS);
// Show scores
a->Clear ();
a->ShowAll ();
s.ShowHighs ();
// Play again?
get_string ("Play again? Y/", again, 2);
} while (*again == '\0' || *again == 'Y' || *again == 'y');
// Restore cursor and clear screen
_setcursortype (_NORMALCURSOR);
clrscr ();
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/