GIDForums  

Go Back   GIDForums > Computer Programming Forums > C Programming Language
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rating: Thread Rating: 3 votes, 5.00 average.
  #1  
Old 23-Mar-2004, 00:06
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough

[Program/Tutorial] RandMouse


Name/Brief Description:
RandMouse -- A small, morbid program that simulates a mouse running around on a deserted island looking for a bridge.
Date of Original Submission:
March 22, 2004
Submitted by:
Aaron Cohn
License:
Free to be used/modified... but not to be turned in as homework!
Problems/Limitations:
Of course, it's only pseudo-random... other than that, my coding is flawless and perfect. Ye who vieweth the almighty RandMouse shall remove thy tongue from the floor and place it in thine mouth. Just kidding :-P
Well, let's start this off with a brief intro as to where I got the idea to write this program, what it does, and why I'm posting it. I am an entry level C/C++ programmer and recently finished my first real programming course. The teacher actually had us get some text books that turned out to be surprisingly good, and I'll tell you exactly which book I'm talking about at the end, but it's basically a general programming book that focuses entirely on C/C++, and delves into object-oriented programming and the like. At the end of each chapter is a bunch of exercises, followed by some practice problems, followed by some examination problems. At the end of chapter twelve, which is a chapter on arrays, there's a problem that involves creating a two-dimensional array to represent a playing field. Now, this has been done over a million times in every which way you could think of, but it was pretty new to me, so I just went at it until it was done. The task the program was designed for is (in the words of the book) this:
Quote:
The following diagram (I've created a mock-up) represents an island surrounded by water (shaded area).



Two bridges lead out of the island. A mouse is placed on the black square. Write a program to make the mouse take a walk across the island. The mouse is allowed to travel one square at a time, either horizontally or vertically. A random number from 1 through 4 should be used to decide which direction the mouse is to take. The mouse drowns when he hits the water; he escapes when he enters a bridge. You may generate a random number up to 100 times. If the mouse does not find his way by the hundredth try, he will die of starvation. Restart the mouse in a reinitialized array and go back and repeat the whole process. Count the number of times he escapes, drowns, and starves.
Well, this doesn't seem so simple at first glance, but it's really not a tough problem to solve once we put our thinking caps on. The first thing we need to do is to figure out what this program needs to do, how it needs to do it, then organize the information so that it can be viewed in a more clear manner.

So, what's the first thing that this program needs in order to do what we want it to do? Well, I'd say we should start by creating a playing field. The next thing we might need would be something to fill that field. Particularly, we'll want to fill it with land, water, and a couple of bridges. Well, this is looking pretty good so far, but what else do we need? Ah, yes... a mouse. I believe those are all the things that we'll need. Now we have to figure out how to make them!

Upon viewing the picture above, you can see that the playing field should be a two-dimensional grid with each square consisting of a type of terrain. Since this chapter is about arrays, and arrays can form grids in different dimensions, then it would probably be in our best interest to use a two-dimensional array as a representation of our playing field. Well, the terrain types can be taken care of using enumeration, but how would we go about creating a mouse? This isn't so hard if you think about what a "mouse" should consist of. For our purposes, a mouse must consist only of a location. It doesn't matter to the user if we do something really complicated or really simple, so we'll just stick with something simple. In this case, all the mouse needs to consist of is a point denoting where it is on the field. Of course, we'll be adding a few things to it, but the only thing necessary for the mouse to exist is a point. So, we'd probably be better off creating a structured data-type representing a point.

It's important to think ahead and predict what you'll be doing with your variables, since you'll be working with them a lot. Make sure to make them easy to work with, and name them very clearly. I have found that when naming a data-type, it's best to use a very generalized term... if you were creating a living organism, such as a mouse, you might use the word rodent to describe what type of data the mouse consists of. We'll just call it an Entity. Since the word encompasses all living things, we could really use any type of living thing we wanted as a subject, and it would still be easy to find out what the variable is for. It's important to do this, because when you start working with other people, or other people attempt to modify your code, those people will have to be able to read and understand it, and you'd like to make that as easy as possible. Not to mention, it makes things easier for you to write in the first place. Right, then... well, on with it.
__________________
-Aaron
  #2  
Old 23-Mar-2004, 12:38
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough
Let's start writing code for the things we need in order to write this program. The first file we should create is a header file that contains declarations of our various data types, so that they don't clutter up the main code. We'll call this file MouseTypes.h.

CPP / C++ / C Code:
#ifndef MouseTypesH
#define MouseTypesH
//---------------------------------------------------------------------------
enum SurfaceType { LAND, WATER, BRIDGE };
enum EventType { MOVE, DROWN, ESCAPE, STARVE };
enum MoveType { NONE, LEFT, RIGHT, UP, DOWN };

typedef struct
{
  int x;
  int y;
} Point;

typedef struct
{
  Point     curpos;
  Point     oldpos;
  MoveType  directionMoved;
  EventType status;
} EntityType;

typedef struct
{
  int moves_this_round,
      total_moves,
      drownings,
      starvings,
      escapes;
} InfoType;
//---------------------------------------------------------------------------
#endif
Now, you may be asking a few questions when you see all that, but it's very simple, really. Let's walk through each piece of the file starting at the top.

CPP / C++ / C Code:
#ifndef MouseTypesH
#define MouseTypesH
.
.
.
#endif
This code is called a pre-processor directive. It tells the compiler to compile everything between #define and #endif, but ONLY if the keyword MouseTypesH has not already been defined. This keeps the user from accidentally building the same file more than once with #include statements.

CPP / C++ / C Code:
enum SurfaceType { LAND, WATER, BRIDGE };
enum EventType { MOVE, DROWN, ESCAPE, STARVE };
enum MoveType { NONE, LEFT, RIGHT, UP, DOWN };
//               0     1      2    3    4
For those who don't know, enum is a keyword that allows the user to define his or her own simple data-type. What does enum mean? Enum, short for enumerate, applies numbers to a list of identifiers that have been declared between a set of braces immediately followed by a semi-colon. The values go from left to right starting at 0. Since the identifiers are actually just numbers that have been given fancy names, you can compare them like numbers.

CPP / C++ / C Code:
SurfaceType surface1 = LAND,  // We can declare variables of enumerated
            surface2 = WATER; // types the same way as usual

if (surface1 != LAND) //Yep, you can do this!
  surface1 = LAND;

if (surface1 < surface2)
  cout << "Land is less than water.";

// This expression would evaluate to true, because land has 
// a default value of 0, and water has a default value of 1.
// You can change the value for each identifier by saying 
// something like this:

enum SurfaceType { LAND=1, WATER=5, BRIDGE }; // Sometimes this is helpful for reference purposes.
                                              // every value after the last value declared will be
                                              // assigned in consecutive order

enum SurfaceType { LAND=1, WATER, BRIDGE=5 }; // Illegal syntax... you can't set the default value for an identifier
                                              // that has already been sequenced.

enum SurfaceType { LAND=3, WATER=2, BRIDGE=7 }; // Also illegal. An identifier cannot be associated with a value
                                                // lower than that of any preceding identifier.

enum MoreSurfaces { GRAVEL, GRAIN, LAND }; // This is illegal because LAND was already used.

SurfaceType rock = LAND + WATER; // Error!
// You cannot do any kind of math or increment/decrement operations on
// enumerated types. You can try it, but you'll get an error.

/* Don't forget the semi-colon at the end! */
Okay, now that we know what enumerated types are, I'll tell you why I used them. For one thing, it makes your code-self documenting. No one wants to see a bunch of numbers. Why would you want to see those? It's much more readable if we can use a name instead of a number. I could have easily used the number 0 in our array later to mean land, 1 to mean water, and 2 to mean bridge, but then anyone who read my code would have to know that beforehand, either through me or through a comment in the code. Why write a comment when I can just use a name instead of a number? Well, that's what I did. I also did this for a couple of other things for the same reason. Enum was designed to create self-documenting code, so use it... just make sure you use meaningful identifiers. Alright, let's move on.

CPP / C++ / C Code:
typedef struct // Creates a new structured data-type
{
  int x;       // This type contains two members of type int
  int y;
} Point;       // This type is called Point... note semi-colon!
Structured data-types are a great way to organize information and minimize the amount of parameters you have to pass to a function. Instead of passing an x and y, I can just pass a Point type variable, and both of those ints will go along with it. It's just as easy to play with those ints, too. All I have to do to get at them is use dot notation.

CPP / C++ / C Code:
Point newpoint;
Point otherpoint;
int sum;

newpoint.x = 1;
newpoint.y = 3;
otherpoint.x = 5;
otherpoint.y = 2;
sum = newpoint.x + newpoint.y + otherpoint.x + otherpoint.y;

if (sum == 11)
  cout << "Structured types rock!";
As you can see, it is very easy to access and manipulate your variables once they are locked inside a structured type. Whenever I create a variable of type Point, those x and y variables will be created with it. Watch out if you start using them with pointers, though, because the dot notation will change to pointer notation when you try to access the members of a pointer to a structured type. I'm not going into that right now, though.

CPP / C++ / C Code:
typedef struct
{
  Point     curpos;         // curpos: Current position
  Point     oldpos;         // oldpos: Previous postion
  MoveType  directionMoved; // directionMoved: What direction it went
  EventType status;         // status: Whether it's dead or not
} EntityType;

typedef struct
{
  int moves_this_round, //syntax hilighting can be stupid!
      total_moves,
      drownings,
      starvings,
      escapes;
} InfoType;
The EntityType structure contains various information about the mouse's current status, such as its current position, where it was last, what direction it just moved in, and how it's doing in its attempt to escape the island. As you can see, I created every single type used in the EntityType structure. However, all of that stuff is pretty much fluff to show the user. If I hadn't wanted to include info about the mouse, we could just make a single variable of type Point and call it our mouse. This is more fun, though. I created the second structure to prevent having to pass all 5 of those variables to a displaystats function. Now I can just pass a single InfoType variable wherever I want to pass those stats. This made the stats MUCH easier to work with, so you might consider doing things like that in your programs.

That's the end of the header file! The next file we're going to go over is the implementation file for RandMouse.
__________________
-Aaron
  #3  
Old 23-Mar-2004, 21:45
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough
The file that we're working on next contains the code for running the program, as well as all the code for the things it needs to do. We're going to go through this file a little bit differently than we went through the header, since it's bigger and more complicated. Keep in mind that we have an objective to complete, and we need to do a few things to get there.

Let's figure out what the main module should look like.

MAIN
CPP / C++ / C Code:
/* MAIN**********************************************************************
* Initialize the map, mouse, and stats                                      *
* Ask the user to begin                                                     *
*   WHILE it's ok to continue...                                            *
*     Move the mouse                                                        *
*     Find out if something happened                                        *
*     IF something did happen...                                            *
*       Increment common counters                                           *
*       Increment event specific counter (Unless there isn't one)           *
*       Display game stats and field map                                    *
*     Ask the user to continue                                              *
*   ENDLOOP                                                                 *
* Thanks for playing!                                                       *
****************************************************************************/
Well that wasn't so painful, now was it? Well, it wasn't painful for you, because I did all the work, but you can look at that and see how I thought it up. It's always important to write your pseudo-code before you start coding, because it'll help you to spot problems in your logic, and you'll have a better picture of what your program's doing once you write it out in plain english. Looks like the first thing we've got to do is initialize the map, the mouse, and the stats. So, let's do it!

RESET
CPP / C++ / C Code:
void Reset( SurfaceType field[][MAX_WIDTH], EntityType *entity, InfoType *info );

/*RESET**********************************************************************
*  Seed the random number generator with the current time                   *
*  in seconds.                                                              *
*  Fill the whole array with WATER                                          *
*  Fill the whole array except the outer units with LAND                    *
*  Fill whatever points with BRIDGE                                         *
*  Set the default starting point for the entity                            *
*  Set status to MOVE                                                       *
*  Zero the move counter                                                    *
****************************************************************************/
Here I have passed the field, a pointer to the mouse's address in memory, and a pointer to the info's address in memory. Pointing to the addresses of these variables allows me to modify their contents directly instead of having to return the updated values in the return value of the function. I didn't use a pointer for the field, because arrays are always passed by pointer/address. I can leave it just the way it is and still be able to modify its contents. I left the variable names generalized so that the function can be reused/modified easily if we ever need it again. Next on the list is the ability to move the mouse, so let's take care of that now.

MOVE ENTITY
CPP / C++ / C Code:
EntityType MoveEntity( EntityType entity );

/*MOVE ENTITY****************************************************************
*  Grab a random number between 1 and 4                                     *
*  IF it's a 1, go RIGHT                                                    *
*  IF it's a 2, go LEFT                                                     *
*  IF it's a 3, go UP                                                       *
*  IF it's a 4, go DOWN                                                     *
****************************************************************************/
The reason we pass the entire entity instead of just its current location is so that we can update some of the stuff in the entity, like set its previous position and the direction moved. All of that was pretty easy and shouldn't need any more explanation. Let's move on to the next thing in MAIN. Looks like the next thing we need to do is increment the counters that each event has in common. Since that's a lot of typing that I don't want to do, I'll make a macro to do it with one word.

CPP / C++ / C Code:
#define STATSMACRO mouseInfo.moves_this_round++; mouseInfo.total_moves++; // Stupid syntax hilighting again
Now I can just say STATSMACRO; any time I want to increment those two counters. Next on the list is to increment event-specific counters. These counters will be updated on a case-by-case basis. For instance, if the mouse falls into the water, the counter for the amount of times he has drowned will be incremented. We'll take care of this later, since it's pretty simple, and doesn't involve a function of any kind. Next on the list is to display the game stats. Let's write a quick function to take care of that.

DISPLAY STATS
CPP / C++ / C Code:
void DisplayStats( EntityType entity, InfoType info );

/*DISPLAY STATS**************************************************************
*  Display previous position                                                *
*  Display current position                                                 *
*  Display last direction moved                                             *
*  Display number of moves taken this round                                 *
*  Display number of escapes                                                *
*  Display number of drownings                                              *
*  Display number of starvings                                              *
*  Display total number of moves                                            *
*  Make space for the field to be displayed                                 *
****************************************************************************/
Nothing new here... just throwing information from memory onto the screen. Turns out we run into an itsy bitsy problem, though. If you display an enumerated type, you'll just get a number. You'd think that you might get the identifier, but that's where the flaw in that logic is... it's just an identifier. It's not a string. So, we need to write a function to convert the MoveType to a string once we figure out what direction we're moving.

DIR TO STR
CPP / C++ / C Code:
void DirToStr( MoveType dir );

/*DIR TO STR*****************************************************************
*  IF dir is RIGHT                                                          *
*    Return "right"                                                         *
*  IF dir is LEFT                                                           *
*    Return "left"                                                          *
*  IF dir is UP                                                             *
*    Return "up"                                                            *
*  ELSE                                                                     *
*    Return "down"                                                          *
****************************************************************************/
You could translate that pseudo-code into almost any language with your eyes closed if you were careful while typing! I don't complain when I'm given a simple task. The next function is a fun one. It displays a picture of our map rendered in text. It's actually quite a simple thing to do, even though it my not seem like it. We can draw this array the same way in nearly the same way we initialized it, using loops.

DISPLAY FIELD
CPP / C++ / C Code:
void DisplayField( SurfaceType field[][MAX_WIDTH], Point curpos );

/*DISPLAY FIELD**************************************************************
*  IF the current value is the same as current entity                       *
*  position...                                                              *
*    Display the entity character.                                          *
*  ELSE                                                                     *
*    IF the current value is WATER...                                       *
*      Display '~'                                                          *
*    ELSE IF the current value is LAND...                                   *
*      Display '+'                                                          *
*    ELSE IF the current value is BRIDGE...                                 *
*      Display '!'                                                          *
****************************************************************************/
All I need to pass to this function is the field and the current position of the mouse. Since we wrote some nifty enumerated types earlier, determining what to do with each case is a cinch, and it's very easy on the eyes. Now that we've got our pseudo-code done, we can write the actual code to do this stuff.
__________________
-Aaron
  #4  
Old 28-Mar-2004, 17:53
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough
Okay, now that we've got the pseudo-code done, we can create the code in our implemation file, Mouse.cpp. First thing to do is do all of our #includes, #defines, and function prototypes.

CPP / C++ / C Code:
#include <stdio.h>
#include <stdlib.h>
#include <iostream.h>
#include <time.h>
#include "MouseTypes.h"
//---------------------------------------------------------------------------
#define MAX_HEIGHT 6
#define MAX_WIDTH 6
#define STATSMACRO mouseInfo.moves_this_round++; mouseInfo.total_moves++;

void Reset( SurfaceType field[][MAX_WIDTH], EntityType *entity, InfoType *info );
EntityType MoveEntity( EntityType entity );
EventType UpdateStatus( InfoType info, Point curpos, SurfaceType field[][MAX_WIDTH] );
char* DirToStr( MoveType dir );
void DisplayStats( EntityType entity, InfoType info );
void DisplayField( SurfaceType field[][MAX_WIDTH], Point curpos );
//---------------------------------------------------------------------------
There, you can see I have included stdlib.h, which is a standard library header containing a couple of functions needed for this program... namely, rand() and srand(). I also included time.h. With that header file, I can get the current time and use it to initialize the random number generator. The final header I've included is the MouseTypes.h file, which contains the various data types that we created above. Then, of course, we define the maximum size of the field with the two constants, MAX_HEIGHT and MAX_WIDTH. We also defined a macro, which stores commands in a constant so that the creator of the macro can execute them all at once just by executing the macro. Macros are helpful for cleaning up code, because sometimes you have to do the same thing a bunch of times in various places. Lastly, we declare the prototypes for our functions. We could have just written all the functions in place of their prototypes and placed main() at the bottom, but I prefer to have main at the top, so I require function prototypes. It's always good to have them there as a reference, anyway.

Well, that's it! Everything from here to the end is implementation. I have some comments on certain things, but it'll mostly be code. You may use the links at the bottom of this post to download a zip file containing both the header file and the implementation file, as well as an alternate file that implements colored text. The only difference between the two is color, and you can compile either one with the same headers, except the color one requires the windows.h header file.

CPP / C++ / C Code:
int main()
{
  SurfaceType field[MAX_HEIGHT][MAX_WIDTH];
  EntityType  mouse;
  InfoType    mouseInfo = {0,0,0,0,0};
  char        userApproval; 

  Reset(field, &mouse, &mouseInfo); // Initialize the map and the mouse

  fputs("Type any character to begin, or q to quit: ",stdout);
  cin >> userApproval;
  cin.ignore(255,'\n');
  while (userApproval != 'q')
    {
      fputs("\n\n\n\n\n\n\n\n\n\n",stdout); // 10 newlines to "clear" screen
      mouse = MoveEntity(mouse);
      mouse.status = UpdateStatus(mouseInfo, mouse.curpos, field); 

      switch (mouse.status)
        {
          case DROWN:
            STATSMACRO;
            mouseInfo.drownings++;
            DisplayStats(mouse, mouseInfo);
            DisplayField(field, mouse.curpos);
            Reset(field, &mouse, &mouseInfo);
            break;
          case STARVE:
            STATSMACRO;
            mouseInfo.starvings++;
            DisplayStats(mouse, mouseInfo);
            DisplayField(field, mouse.curpos);
            Reset(field, &mouse, &mouseInfo);
            break;
          case ESCAPE:
            STATSMACRO;
            mouseInfo.escapes++;
            DisplayStats(mouse, mouseInfo);
            DisplayField(field, mouse.curpos);
            Reset(field, &mouse, &mouseInfo);
            break;
          default:
            STATSMACRO;
            DisplayStats(mouse, mouseInfo);
            DisplayField(field, mouse.curpos);
        }
      fputs("Type any character to continue, or q to quit: ",stdout);
      cin >> userApproval;
      cin.ignore(255,'\n');
    }
  fputs("\nThanks for playing!\n",stdout);
  return 0;
}
Remember, if you are confused about what anything in this code is doing, just refer to the pseudo-code in the above post. I will not be placing pseudo-code in this post, because it's going to be big enough as it is, and I've already written it up there. No need to repeat myself!

CPP / C++ / C Code:
void Reset( SurfaceType field[][MAX_WIDTH], EntityType *entity, InfoType *info )
{                                                                                                
  int x, y; 
  time_t seconds; // time_t is a type defined in <time.h>

  srand((unsigned)time(&seconds)); // Seed rand() with the current time in seconds
                                   // whenever Reset() is called.               
  for (x = 0; x < MAX_HEIGHT; x++)
    for (y = 0; y < MAX_WIDTH; y++)
      field[x][y] = WATER;         // Set all units in the field to WATER               
                                                  
  for (y = 1; y < MAX_WIDTH-1; y++)
    for (x = 1; x < MAX_HEIGHT-1; x++)
      field[x][y] = LAND;          // Set all units (except outer edge)
                                   // to LAND
                                                
  field[MAX_HEIGHT-1][1] = field[3][MAX_WIDTH-1] = BRIDGE;
  // Makes it so the bridges are always the same distance from the
  // edge of the map they're anchored to (MAX_HEIGHT or MAX_WIDTH)

  entity->curpos.x = 2; // Here we set the default point for the mouse to
  entity->curpos.y = 3; // (2,3). If you change it, be sure the point you
  entity->status = MOVE; // choose is within the array, or you'll have a problem.

  info->moves_this_round = 0;
}
The only new thing here is pointer notation. We have a pointer to an entity, which means we must use pointer notation (->) to access its members. However, you may still use dot notation to access the sub-members of the entity.

CPP / C++ / C Code:
EntityType MoveEntity( EntityType entity )
{
  entity.directionMoved = (MoveType)((rand() % 4) + 1);
  entity.oldpos = entity.curpos;

  switch (entity.directionMoved)
    {
      case LEFT:
        entity.curpos.y -= 1;
        break;
      case RIGHT:
        entity.curpos.y += 1;
        break;
      case UP:
        entity.curpos.x -= 1;
        break;
      case DOWN:
        entity.curpos.x += 1;
        break;
      default:
        return entity; // This will never happen, but it's good to
    }                  // have a default in all switch statements.
  return entity;
}
Don't get confused about that defaut: return entity; stuff. It's just there because I like to have a default statement in all of my switches, and that was the one that would cause the least amount of damage if it went off. Let's continue.

CPP / C++ / C Code:
EventType UpdateStatus( InfoType info, Point curpos, SurfaceType field[][MAX_WIDTH] )
{
  if (info.moves_this_round == 10)
    return STARVE;
  switch (field[curpos.x][curpos.y])
    {
      case WATER:
        return DROWN;
      case BRIDGE:
        return ESCAPE;
      default: 
        return MOVE; // If at first we don't succeed... keep trying!
    }
}
For those of you astute enough to notice that my mouse starves at 10 moves instead of 100 (as specified in the assignment), there's a reason for it. Quite simply, it's highly improbable that, in a 6 by 6 unit area, the mouse could move 100 times without drowning or escaping. So, instead of having the starvation occur on an extremely rare basis, I lowered the number to 10. Now it occurs in more realistic intervals. You can change it if you want, though.

CPP / C++ / C Code:
void DisplayStats( EntityType entity, InfoType info ) 
{
  printf("\nPrevious position: (%d,%d)", entity.oldpos.x, entity.oldpos.y);
  printf("\nCurrent position:  (%d,%d)", entity.curpos.x, entity.curpos.y);
  printf("\nLast move taken:   %s", DirToStr(entity.directionMoved));
  printf("\nMoves this round:  %d", info.moves_this_round);
  printf("\nEscapes:     %d", info.escapes);
  printf("\nDrownings:   %d", info.drownings);
  printf("\nStarvings:   %d", info.starvings);
  printf("\nTotal Moves: %d", info.total_moves);
  fputs("\n\n",stdout); // Make space to display the field
}
Here's the last function. Fortunately, this one is also the most fun!

CPP / C++ / C Code:
void DisplayField( SurfaceType field[][MAX_WIDTH], Point curpos )
{
  int localX,
      localY;

  for (localX = 0; localX < MAX_HEIGHT; localX++)
    {
      for (localY = 0; localY < MAX_WIDTH; localY++)
        {
          if ((localX == curpos.x) && (localY == curpos.y))
            fputs(" X",stdout);
          else
            {
              switch (field[localX][localY])
                { 
                  case WATER:
                    fputs(" ~",stdout);
                    break;
                  case LAND:
                    fputs(" +",stdout);
                    break;
                  case BRIDGE:
                    fputs(" !",stdout);
                    break;
                }
            }
        }
      fputc('\n',stdout);
    }
}
Well, that's it! There's nothing left. Thank you for taking the time to read this walkthrough. I appreciate any feedback in the form of reputation points, so if you liked it, tack on some points with the little button at the top of this post. Feel free to PM me for any questions or bug reports for this tutorial. I have included all of the files stated above in the zip file below, as well as this tutorial with formatted text and syntax hilighting. I hope you enjoyed reading this tutorial as much as I enjoyed writing it!
Attached Files
File Type: zip RandMouse.zip (27.4 KB, 82 views)
__________________
-Aaron
  #5  
Old 31-Mar-2004, 11:54
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough
Oh, also.. the book I referred to at the beginning of this tutorial is titled:

"Programming and Problem Solving with C++" -- by Nell Dale, Chip Weems, and Mark Headington
__________________
-Aaron
  #6  
Old 17-Dec-2004, 19:22
aaroncohn's Avatar
aaroncohn aaroncohn is offline
Regular Member
 
Join Date: Feb 2004
Location: Bay Area, CA.
Posts: 564
aaroncohn is a jewel in the roughaaroncohn is a jewel in the roughaaroncohn is a jewel in the rough
Another good book - "Absolute C++" -- by Walter Savitch
__________________
-Aaron
 
 

Recent GIDBlogProblems with the Navy (Enlisted) by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 14:13.


vBulletin, Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.