ulrail.gif

HW 10: 2-D Arrays

  ur-2c.gif urrail.gif
blrail-nonavbar.gif

Home | Resources | Homeworks | Exams
Lectures | Labs | Contacts | Submit | TAs

br-2a.gif   br-2c.gif brrail.gif
spacer.gif spacer.gif

Course Project

This homework will complete to the course project, an implementation of a simple computerized version of the classic game of the Oregon Trail computer game.  You will submit the following files: Map.java, MapTest.java, Control.java.

Because we are now at the end of the semester, we would like to put the course project in context and to leave you with a broader view both of what you've done in CS101 and of the vast possibilities and responsibilities that lie beyond CS101. In addition to the programming part of this assignment, you are also responsible for being familiar with the material in the following paragraphs, which we reserve the right to test on the upcoming semester exam.

Professional Competency and Ethics in Software Architecture and Engineering

In industrial practice, many software developers start out as programmers. In this role, the job is to produce program implementations that satisfy given specifications. As one gains experience in software development, one begins to take on tasks in the area of software architecture, and software engineering more broadly.
  • Beyond mere programming, software architects and engineers decide not just how to implement specifications as programs but also what specifications to implement, which involves understanding the given application domain, ongoing interactions with subject domain experts, and so forth. In many cases, software engineers are responsible for the key computational components of larger engineering systems, such as aircraft, medical imaging systems, gene sequencing technologies and global entertainment networks.
  • Software is now the major determinant of cost, schedule and success and the major place where innovation is happening in most engineering domains and in many other areas of our society, including business, medicine and defense. Beyond mere programming, the software engineering tasks required to develop software for such applications also involves rigorous verification of programs (including but not limited to software testing) to provide adequate assurance that programs satisfy their specifications. After all, you would not want to fly in a software-controlled commercial jetliner (and today many literally cannot fly unless their software and computers are working), unless the most stringent and demanding techniques had been used to assure that the software wouldn't crash in the air, leading the airliner to crash on the surface of the earth.
  • Beyond purely technical considerations, software engineering in practice also involves the design and management of complex engineering processes and organizations. Directing a team of 1000 or 5000 developers, which includes partitioning and managing the work of developing large systems, is a very different task than writing small programs. Software engineers, like all engineers, also attend to human, economic, environmental, ethical and political considerations that arise in large-scale engineering practice.

Our technological future will increasingly be shaped by software: human intelligence automated and running the machinery of our civilization. Software architecture and engineering thus involves diverse technical and human aspects and are major tasks of software professionals. Programming per se, although demanding great intelligence, diligence and creativity, is but one small part of computer science, in general, and of software engineering, in particular.

Many people assume that because they understand programming, they are competent to act as industrial software architects and engineers. That is generally not true. You finish CS 101 knowing that you understand software far better (it is one of the most exciting and powerful concepts in all of science and engineering). You have taken a first important step to becoming a competent software architect, engineer or even computer scientist. However, CS101 is not intended to and it does not give you the knowledge or the experience to perform competently as a software architect or engineer. As one of the last and most important lessons in CS101, we wish to emphasize that knowledge of mere programming does not qualify one as a professional in software engineering or software architecture; and it is a crucial mark of the professional to recognize and acknowledge the limits of one's competence and to decline to operate professionally in a manner for which one is not adequately trained and competent.

An Invitation to Take the Next Steps Toward Professional Competency in Computer Science and Engineering

If you are interested in exploring the next steps toward professional competency, whether in software architecture or engineering or in research in computer science (and we really hope that you are interested!), we encourage you to consider joining the Computer Science (CS) department as a major or a minor. CS is now the main catalyst for major advances in nearly all fields of human inquiry, from the arts to engineering. Recognizing this fact, UVa has made Computer Science the only department at the University of Virginia to offer degrees in both the School of Engineering (BS) and the College of Arts and Science (BA). The CS at UVa department is:

  • highly ranked nationally,
  • by far the best-ranked department in Virginia, and
  • one the best departments in the world in several major areas of computer science and engineering, including software engineering.

We are also active in research and teaching in most of the major areas of contemporary research and practice. We encourage undergraduate participation in faculty research projects, and we routinely place our graduates in the best graduate schools and professional positions in the country.

Job Prospects for Software and Computing Professionals Relative to Other Engineering Disciplines: 2004-2014.

Many students are drawn to computing, but some are concerned about being isolated as a mere programmer, or, worse, (a) in the wake of the .COM implosion, either not being able to find a job, or (b) being laid off due to the off-shoring of software development. Although we obviously cannot make promises about your specific career path or the future, we can give you a  few facts.

  1. First, for those who are concerned about being isolated, understand that, in general, computing is generally one of the most human-intensive of professions. As a software architect or engineer, one is at the center of activity in the conception and development of next-generation systems across all application domains. Software engineers generally interact with people from many other areas in order to do their jobs, because their jobs centrally involve understanding other domains (whether music, transportation, medicine, or radar) and representing them in terms of software constructs.
  2. Second, for those who are concerned about jobs, the facts are clear: according to the U.S. Bureau of Labor Statistics (BLS) the computing professions even excluding mere programming are by far (and we mean, by a long shot) the largest and the fastest growing professions in computing and engineering. There is only one other engineering area that the BLS ranks as growing much faster than average in the 2004-2014 time, and it is among the very smallest of engineering fields, employing today only a few tens of thousands of people, and expected to produce only a few thousand new jobs in the coming decade. By contrast, there are over 2 million professionals already at work in advanced computing fields, and the BLS expects hundreds of thousands of new, high-paying jobs to be created in the next ten years.

Thus, the best information that is available today clearly indicates that computer science and engineering, including software engineering, remains a very large, vibrant, important, robust, and promising sector of the economy. If you would like to learn more, including projected job prospects for engineering and other fields, we encourage you to check the BLS web site for yourself (www.bls.gov).

And Finally, Your Assignment

The rest of this final CS101 semester project assignment is written in a way meant to emphasize the distinction between mere programming and the separate issue of software architecture and specification, and to encourage you to think about making the transition from programmer to engineer/designer. In particular, it is written in the form of the kind of programming task that you might see in practice.

  1. We provide the class outline (design).
  2. You provide the detailed programming implementations.

As you do this work, think about the task of the architect: to organize the development of much more complex systems be the careful design of the interfaces by which such systems are decomposed (broken down) into subsystems and even smaller parts (such as classes) that can be implemented by smaller teams and individuals. We've done that task for you this semester. We encourage you to consider continuing in the field to deepen your ability to design more complex systems yourself.

You will now complete your game by providing an implementation of the Map class. We provide a specification of the class. You will produce an implementation satisfying this specification. The specification defines:

  • the data members of the class, and
  • the syntax and semantics of its methods.

By syntax we mean names and signatures. We define the syntax in the Java language, as is typical.  By semantics we mean the required behaviors of the methods.  We describe the semantics informally in natural language (English).

Your job is to provide implementations of the methods, using the given data members, to meet the given semantic specifications.  You should test your programming before turning it in, in two ways:

  1. First, by developing a simple MapTest class (as we have done on previous assignments and labs) that minimally tests each method in your class implementation, and,
  2. Second, by playing at least 5 games! For this purpose, you can use our implementation of the Game class.

In this homework, you will develop the Map class and a MapTest class that will serve as a "test harness" to test your Map class (at a minimum testing each method). We will provide you with one class for this homework, namely Game, the class with the main() method that will run the game.  It ties together all the other classes. Lab 11 developed one of the last classes, MapPrinter, that allows for easy printing of the map to the text-based screen.

Project Files

For each class, you can either download our version (right-click and select "save as..."), or use your own (if you are sure that your code is bug-free).  Save all your code, both old and new, in a separate directory than the previous labs and homeworks, so you do not overwrite your files. (NOTE: If you choose to use your own classes, you will need to make sure that your classes address the issues in project errata list.  Please note that your previous assignments/labs will not be penalized for not addressing these issues.)

  • Location.class (hw 7): This class represents a location on the map.  A Location has a given type of terrain, and can have a Depot.
  • Person.class (hw 7): This class represents a single person in the game.
  • Depot.class (hw 8): This is a "market" (fort, etc.) that can occur at a location.  You can buy and sell goods at a Depot.
  • Inventory.class (hw 8): This class represents the inventory that holds items.  Every depot, as well as the player's Vehicle, will have an inventory.  It holds such things as food, money, and oxen.
  • Parser.class (lab 9): This class is in charge of obtaining all user input.  No user input is read in in any other class.
  • Party.class (hw 9): This class represents a party of people that are traveling.  There will be 5 or so people per party (i.e. you are leading a group of 5 or so people).
  • Vehicle.class (hw 9): This class represents the player's vehicle.  The vehicle contains the party (i.e. all the people that are traveling), as well as an Inventory (how much food, etc. the player has).
  • Descriptions.class (lab 10): This class allows you to customize the game -- you choose the names for various things in the game, such as the party members, the name of the vehicle, etc.
  • MapPrinter.class (lab 11): This class will print out the Map to the screen.

We provide you with two classes for the homework:

  • Game.java: The class with the main() method that will run the game.  It ties together all the other classes.
  • Control.java: This class provides a number of methods that allow the game to progress (such as handling the turns, ending the game, etc.). We give you the implementations for the methods in this class, and ask you to write the specification for each method in the comments. We ask you to add comments to the methods in this class, similar to those given to you in the Map class.  You should submit your commented Control.java as part of your homework submission.

In this assignment you will implement the final piece:

  • Map.java (hw 10): The 2-D grid that composes the board of the game.  It's a 2-D grid of Locations.

Documentation

As one develops more classes for a project, one comes to rely on previously defined classes and methods.  Programmers and designers often need to refer to the details of the previously defined classes.  To this end, we have provided documentation of all the classes online.  The format of this documentation is the same as the Java SDK.  In particular, the comments in the code below are contained in the documentation for the Map class.

Specification: The Map Class

Here, below, in the Java language, is the specification of the Map class. This class specification is available online here. The syntax is specified by the method declarations. The semantics are specified in the comments above each method declaration. The places where you are to write your code are indicated by the comments in place of method bodies. Replace these comments with your code. At the same time (and we recommend doing it incrementally and in parallel), write a MapTest class to test your newly coded methods. When you're done, use our Game class to test your Map class and system. Turn in your Map and MapTest classes.

/** 
 * This class creates a map of locations which represents
 * the game board for Oregon Trail
 **/
 
public class Map {
	//------------------------------------------------------------
	// DATA MEMBERS
	//------------------------------------------------------------
	
	/** The 2d array of locations in the map, indexed by row-col coordinates. */
	private Location[][] map;
	/** The density of the number of Depots on the map */
	private double depotDensity = Game.DEPOT_CHANCE;
	/** The density of the number of forests on the map. */
	private double forestDensity = Game.DENSITY_FOREST;
	/** The density of the number of mountains on the map. */
	private double mountainDensity = Game.DENSITY_MOUNTAIN;

	/**  
	 * Default constructor.  Creates a 2d array of null Location references using the
	 * {@link Game#BOARD_HEIGHT} and {@link Game#BOARD_WIDTH} as dimensions.
	 * After the constructor is executed, the map will contain BOARD_HEIGHT
	 * by BOARD_WIDTH null Location references.
	 */
	public Map () {
		// your implementation here
	}
    

	/** 
	 * This constructor initializes a 2D map of null Location references using the values
	 * specified by height and width as row and column dimensions, if they are positive.
	 * If height is 0 or negative, the row dimension is set to 1.
	 * If width is 0 or negative, the column dimension is set to 1.
	 * 
	 * @param height The height of the map
	 * @param width The width of the map
	 */
    	public Map (int height, int width) {
		// your implementation here
    	}


	/** 
	 * This specific constructor initializes the 2D map using the given height
	 * and width parameters, if positive, as the row and column dimensions.  
	 * There will be height x width null Location references.
	 * (See the 2-parameter specific constructor.)
	 * The remaining parameters are used to set the other private data member
	 * values by calling the appropriate mutator methods.
	 * 
	 * @param height The height of the map
	 * @param width The width of the map
	 * @param theDepotDensity The density value for Depots.  Must be greater than 0.0.
	 * @param theForestDensity The density value for Forests. Must be greater than 0.0.
	 * @param theMountainDensity The density value for Mountains. Must be greater than 0.0.
	 * 
	 */
    	public Map (int height, int width, double theDepotDensity, double theForestDensity,
                    double theMountainDensity) {
		// your implementation here
    	}

    	//------------------------------------------------------------
	// ACCESSORS AND MUTATORS
	//------------------------------------------------------------
    	/**
    	 * Returns the value of the private data member depotDensity
    	 *	
	 * @return Returns the depotDensity.
	 */
	public double getDepotDensity() {
		// your implementation here
	}

	/** 
	 * Sets the depotDensity property to the value passed.  If the value passed
	 * is negative, then the density is set to {@link Game#DEPOT_CHANCE}.
	 *
	 * @param theDepotDensity The depotDensity to set.
	 */
	public void setDepotDensity(double theDepotDensity) {
		// your implementation here
	}

	/**
	 * Returns the value of the private data member forestDensity 
	 *
	 * @return Returns the forestDensity.
	 */
	public double getForestDensity() {
		// your implementation here
	}

	/** 
	 * Sets the forestDensity property to the value passed.  If the value passed
	 * is negative, then the density is set to {@link Game#DENSITY_FOREST}.
	 *
	 * @param theForestDensity The forestDensity to set.
	 */
	public void setForestDensity(double theForestDensity) {
		// your implementation here
	}
	

	/**
	 * Returns the 2-D private data member map 
	 *
	 * @return Returns the map.
	 */
	public Location[][] getMap() {
		// your implementation here
	}

	/**
	 * Sets the private 2-D map array to the 2-D map that is passed as a parameter.
	 *
	 * @param map The map to set.
	 */
	public void setMap(Location[][] map) {
		// your implementation here
	}

	/**
	 * Returns the value of the private data member mountainDensity. 
	 *
	 * @return Returns the mountainDensity.
	 */
	public double getMountainDensity() {
		// your implementation here
	}

	/** 
	 * Sets the mountainDensity property to the parameter value passed.  
	 * If the parameter value passed is negative, then the 
	 * density is set to {@link Game#DENSITY_MOUNTAIN}.
	 *
	 * @param theMountainDensity The mountainDensity to set.
	 */
	public void setMountainDensity(double theMountainDensity) {
		// your implementation here
	}

    	//------------------------------------------------------------
	// OTHER METHODS 
	//------------------------------------------------------------
    	/** 
    	 * Returns the number of columns on the map.  The columns
    	 * correspond to the second dimension of the 2-D map.  Since
    	 * the map is a 2-D array, this method returns the value
    	 * of the length attribute of map's second dimension.  
    	 * 
    	 * @return The width (number of columns) of the Map
    	 */
    	public int getNumCols() {
 		// your implementation here
    	}

    	/** 
    	 * Returns the number of rows on the Map.  The rows
     	 * correspond to the first dimension of the 2-D map.  Since
     	 * the map is a 2-D array, this method returns the value
    	 * of the length attribute of the map's first dimension.
    	 *
    	 * @return The height (number of rows) of the Map
    	 */
    	public int getNumRows() {
  		// your implementation here
    	}

    	/** 
    	 * Sets the map location at the coordinates specified
    	 * by row and col (if valid) to the passed Location, loc.
    	 * Row and col may not be negative values, nor may they be
    	 * larger than the Map's dimensions.
    	 *
    	 * If invalid row or col values are given, an error message is printed
    	 * and loc is not assigned to any Location in the 2-D map.
    	 *
    	 * @param row The row of the location in the map
    	 * @param col The column of the location in the map
     	 * @param loc The location to set
     	 */
    	public void setLocationAt (int row, int col, Location loc) {
  		// your implementation here
    	}

    	/** 
    	 * Returns the location at the coordinates specified by row and col.
    	 * if an invalid row or column index is given, null is returned. Invalid
    	 * index values are negative or larger than the corresponding dimension of
    	 * the map.
    	 *
    	 * @param row The row of the location in the map
    	 * @param col The column of the location in the map
    	 * @return the location at the position (i,j)
    	 */
    	public Location getLocationAt (int row, int col) {
			// your implementation here
		}

        
    	/** 
    	 * Sets the isVisited flag to true for all the locations within 
    	 * visibility distance from the location specified by row and col.
    	 * This method examines every map coordinate and calculates the row
    	 * distance and the column distance.  If both row distance AND
    	 * column distance are less than or equal to the value of the visibility value,
    	 * then that Location's isVisited data member is set to true using the 
    	 * corresponding Location mutator.
    	 *
    	 * @param row The row position
    	 * @param col The column position
    	 * @param visibility The number of squares of visibility that
    	 * can be seen beyond those that have been visited.
    	 */
    	public void setVisibility (int row, int col, int visibility) {
   			// your implementation here
    	}
  
    
    	/** 
    	 * This method takes care of populating the map. 
    	 * This consists of several tasks: 
    	 * 1) Create new locations for each map coordinate
    	 * 2) Create a Depot at the Location at the default Game starting coordinates 
    	 *		defined by Game constants {@link Game#START_ROW_COORD}
    	 *		and {@link Game#START_COL_COORD}
    	 * 3) Set the initial visibility from the Game starting coordinates,
    	 *		using the default visibility using the setVisibility() method.
    	 * 4) Set the price factors for each Location on the map using
    	 * 		the setPriceFactors() method.
    	 */
    	public void populate() {
  			// your implementation here
    	}

	/** 
	 * Sets the price factors for each Depot that exists on the map.
	 *
	 * This method examines every Location on the map.
	 * If a Depot exists at the Location being examined,
	 * set the Depot's price factor based on its distance from 
	 * the starting position using the equation:
	 * 1 + (distance/Game.PRICE_FACTOR_MODIFIER)
	 * 
	 */
	 // We give you this method as an example implementation
    	public void setPriceFactors() {
    	   for ( int r = 0; r < getNumRows(); r++ )
    		 for ( int c = 0; c < getNumCols(); c++ ) {
    			
    			// If there is no Depot at this location,
    			// continue to next iteration of the loop
    			if ( map[r][c].getDepot() == null )
    				continue;
    				
    			// The current location being examined
    			Location location = map[r][c];
			// determine price factor based on distance from starting position
			int xDis = Game.BOARD_WIDTH - location.getPosCol() - 1;
			int yDis = Game.BOARD_HEIGHT - location.getPosRow() - 1;
				
			// The distance is the square root of (colDist^2) + (rowDist^2)
			double distance = Math.sqrt (xDis*xDis+yDis*yDis);
				
			// Set the price factor at the depot at the location
			location.getDepot().setPriceFactor(1 + distance/Game.PRICE_FACTOR_MODIFIER);
				
    	}
	
    }

}
	
	

MapTest class, Revisited

Your main() method in the MapTest.java file should test all of the methods that you implement for the Map class.  In previous labs, you did this for various classes.  This homework requires the same, but for the Map class.

Control Class

The other class you must submit is the Control class.  Objects of this class will be created to control the main actions of the game.  This time, we have given you the method implementations and you are going to play the role of the specification writer by adding comments similar to the ones we've given you in Map.java.  We have added comments to the source file indicating where you should add your comments.

Where to Start

Work on the methods one by one, making sure that each one works before moving onto the next one.

While the main() method may seem like a lot of work, there are a couple of things that will make it much easier.  If you add the code to MapTest.java as you go along, it will make it much easier.  The idea is to implement a method or two, and then add the test code to MapTest.java.  Then make sure it compiles and works properly.  Then go onto adding more methods.  If you get stuck in a method (i.e. can't get it to work, it won't compile, etc.), then move onto another one, and come back to the one that is giving you problems.

This homework will be much easier if you work through it one method at a time.  Write the first method, and then sufficiently test it in your main() method.  Then write the second method, and sufficiently test it in your main() method.  This will make the entire homework much easier, and it will take much less time to complete.

Good Programming Practices

All the good programming practices from HW 1 should be included here as well.  Since you are providing code in the main() method of the Game class to test your other code, you don't need to include execution runs as comments.

Submission

When you are finished, submit the Map.java, MapTest.java, and Control.java files.

Congratulations on finishing the last programming assignment of CS 101!  Have a great summer!

spacer.gif
spacer.gif footer-middle.gif spacer.gif