Course ProjectThis 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.
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 EngineeringIf 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:
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.
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 AssignmentThe 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.
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:
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:
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. 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.)
We provide you with two classes for the homework:
In this assignment you will implement the final piece:
DocumentationAs 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 ClassHere, 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); } } } 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 ClassThe 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 StartWork 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 PracticesAll 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. SubmissionWhen 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! |