Skip to main content
留学咨询

辅导案例-CS4233

By May 15, 2020No Comments

CS4233 Programming Assignment Generic Piece Move Validation Gary F. Pollice March 28, 2020 Introduction Many board games, such as chess, checkers, and Stratego, have pieces that have their movement constrained in different ways. Many properties and rules determine the constraints and during the game, a human or program would look at the constraints to determine if the piece can move from one location on the board to another without violating the constraints. This assignment requires you to extend a small, flexible example to implement and test code that checks whether pieces in the game of chess may make a specified move, given a board that provides the locations of pieces, and the starting and ending squares of the move that the piece wants to make. You simply have to return Yes (true) or No (false). This assignment has these objectives: • let you practice TDD and the process described for this course • learn or improve your knowledge and application of interfaces and generics in Java • improve your understanding of abstraction and separation of concerns • learn or improve your knowledge of lambdas in Java You should read this document carefully and ask any questions about it in the discussion thread for this assignment that you will find on Canvas. We look at these several times a day and we expect students to do the same. If you have an answer to a post in a discussion, feel free to provide the answer unless the discussion explicitly asks you not to. Download the starting code for this assignment and use it as your base for starting work. Try to follow the code style in the base code. The Canvas site has the formatting conventions that we use, feel free to install them in your Eclipse. Take time to look over the code and the initial design described in this document before starting to modify it. Spending a few minutes to understand the organization and purpose of each class and method will save a couple of hours reworking code that might be in error. You should follow the TDD approach described previously as strictly as possible in order to ensure that you’re doing it correctly and also to let you evaluate the effectiveness of using this approach as one of your personal process practices. Prerequisites First, you need to know a little bit about chess an how the pieces move. In general, the moves are straight forward, like the ability to move a rook orthogonally (horizontally or vertically) any number of squares as long as there are no intervening pieces. We will use these rules of chess as our official guide. We will not use the “en passant” special rule. You do not need to know all of the special rules, but you should pay special attention to the Learn to move the Pieces section. 1 Next you need to download the starting code and load the java project into Eclipse. The starting code is stored as an Eclipse Java project in a zip archive. You simply select File→Import…→General and then select Existing Projects into Workspace. Make sure that after clicking the Next button that you click on the Select archive file radio button and follow the prompts to import the project. We suggest that you keep this in a private git repository. Make sure that you have have installed a Java JRE that is at the Java 8 level or higher. You can ensure that the project has imported properly by selecting the project in the Project Browser and then right click and choose Run As→JUnit Test. All tests except one should pass. Next, take time to understand the code. See the code description in the next section of this manual. There may be videos provided in the module on Canvas if you need them. Make your task list, write some tests and start implementing the required functionality. The starting code base This section describes the starting code base. We use UML diagrams to describe the structure and elaborate with text as needed. Package structure The code base consists of three packages (Figure 1). Two contain core elements and utilities that might be used for many types of games. The other package contains the chess-specific code. This is where all classes that are unique to the game of chess, and this assignment belong. Figure 1: Packages in the starting code. Each of these packages contains classes that are logically grouped. The general contents of each package are 2 gpv This is the top-level package. The files contained in this package are all generic-based and are extended for each particular game type. gpv.util This package contains utility files like Board that might be used in any game. As the framework expands, some of these might go into the gpv package or some other package that contains generic classes that must be extended for specific games. gpv.chess This package contains all of the classes for this assignment that are specific to the game of chess. Top-level interfaces There are three interfaces in the top level package, gpv (Figure )2). These describe the basic behaviors and connections between the main abstractions for this assignment. Figure 2: Top-level interfaces. Notice that two of the interfaces are generic and have generic type parameters. The following sections describe the purpose of each of these. Piece This is the main abstraction for the assignment. You will be implementing chess pieces that have different constraints placed on their movement. The Piece interface describes the behavior that any piece must supply to its clients. The primary behavior is canMove(). Given a board state (i.e. the board and current location of any pieces) and two coordinates that indicate the source and destination of the move, this boolean method simply returns a yes/no response (true/false) that tells the client whether the proposed move is legal. The Piece is generic. We want to be able to use it for any game, even though for this assignment, we will focus only on the game of chess. The generic type parameter for this is D, where D must implement the PieceDescriptor interface. The intention is that the descriptor contains the necessary information to describe the piece’s properties. Any piece must have a getter method getDescriptor() that returns this descriptor. PieceDescriptor This is a marker interface. That is, it describes no methods, but any piece descriptor must implement it. This lets the Java compiler generate the appropriately typed classes. Any given game and its pieces may implement the piece descriptors as it sees fit. The concrete descriptor may be a class or an enumeration. 3 PieceFactory The PieceFactory is another generic class that implements a factory design pattern. It must have a single factory method that creates instances of a concrete piece that is defined by a specified descriptor. Using a PieceFactory requires two steps. 1. Create the desired PieceFactory instance. This is usually done one time and is often made a class variable (i.e. static). static ChessPieceFactory factory = new ChessPieceFactory(); In this case a concrete class that implements the PieceFactory interface, called ChessPieceFactory gets instantiated. 2. Any time a client needs a new piece it calls the factory method ChessPiece p = factory.makePiece(d);. The two generic type parameters, P and D, define the concrete piece type and the appropriate descriptor. Given a PieceDescriptor instance, the factory returns the required Piece instance. Chess-specific classes The gpv.chess package contains five classes (Figure 3). Two of them, PieceName and PlayerColor are simple enumerations. The following sections describe the rest of the classes. Figure 3: Classes in the gpv.chess package. ChessPieceDescriptor In order to describe a chess piece, you need to know the type of piece (e.g. Rook) and the color of the piece (White/Black). The ChessPieceDescriptor makes use of the PieceName and the PlayerColor. The ChessPieceDescriptor implements the PieceDescriptor marker interface from the gpv package. ChessPieceDescriptor has getter methods that allow a client to obtain the piece type and the color of the piece. 4 ChessPiece The ChessPiece is the main class that you will work with for this assignment. It implements the Piec
e interface. It contains some getter methods to obtain the piece type, color, descriptor and name. Other public methods that are in the ChessPiece class are hasMoved() Returns true if the piece has moved from it’s starting position. It may have moved back to its starting position, but this method will return false only if it has never moved. setHasMoved() Sets the hasMoved instance variable to true. For this assignment, this method is used for setting up initial test states. For a game, the game manager would set this as the game progresses and the piece is moved. canMove() Inherited from the Piece interface. This is the main method that you must implement for this assignment by creating new private methods, instance variables, and classes as necessary. ChessPieceFactory This is a factory class with a single factory method. It implements the PieceFactoryChessPieceDescriptor> interface. You may want to modify the factory method, but you may not change its signature. Utility classes The gpv.util package contains just three classes that represent a rectangular board and ways coordinates that can reference locations on the board. There is a helper class, SquareInitializer that is helpful for initializing a board configuration. This class instances are simply data objects with no behavior. The implementations of these classes is straight forward and you should be able to understand it quickly in a few minutes of reading the code. You may not change the SquareInitializer class. You may add methods to the Board and Coordinate classes, but you may not change the signatures or implementation of methods that are already defined. The board layout The chess board has the following layout, with the coordinates (row, column) shown in each square (Figure 4) Test code I have supplied a few initial tests for you. These are not complete, but are examples of the how I will run the tests. One test fails due to the fact that ChessPiece.canMove() simply returns false. All of the tests are simple and just ensure that the Board and some other classes are correct. Some of these tests are parameterized. You may want to look at the JUnit user guide if you don’t understand how they work. What you will do You will write code that, given an instance of the ChessPiece class, it will return the correct answer when the canMove() method is called. You should not have separate subclasses of ChessPiece for each type of chess piece. The starting code has enough to identify any piece. What the starting code lacks is the implementation of the movement rules for the different pieces. One way to do this might be to have a long switch statement where each case handles a different chess piece type. This would look something like this: 5 Figure 4: The chess board and square coordinates. switch {descriptor.getName()} { case KING: … break; case QUEEN: … break; … } This is a terrible solution and will most likely contain a lot of duplicate code, making it difficult to maintain. It is not a very flexible and extensible solution. It is not cohesive. The ideal solution is to be able to have each piece know just the movement rules that it needs to use when determining if a proposed move is valid or not. There are some rules that would apply to any piece (such as trying to move to a square that’s not on the board), and some that only apply to one or a few pieces (e.g. may move orthogonally any number of squares for a Rook or Queen). You should think of using Java lambdas at the very least to encapsulate the movement rules. 6 You need to make sure that all of the input you receive is valid. Any invalid input should cause canMove() to return false. Your code should never throw any type of exception. If an exception occurs during the processing of your canMove() implementation, you must catch the exception and return false. Finally, you will use Test-Driven Development (TDD) for this assignment. Keep a TODO task list as a text file in your project. Number the tasks in the order you implement them. Assumptions There are some conditions that you do not have to check for. You may make the following assumptions. • None of the arguments to canMove() will be null. • The Board object for any test will be initialized. • Any piece that is on the board will have it’s hasMoved property set properly. • There are no en passant moves in this version. • You do not need to check to see if the King is in check, or if the King moves into check. • There is a piece on the board at the location where the move starts. • You can assume that any piece on the board that is the source of a move is at a location where it might possibly be during a game (e.g. a white pawn will never be on the first row). You may not assume • that there are any pieces on the board, even though it is initialized. • that the coordinates are valid for the 8 X 8 board. ther the piece at the from location can legally move to the to location given the board confifuration in the test. Submitting your work Submitting your work should be easy, but it’s amazing how many people do not seem to know how to export a project in Eclipse and make sure that it can be imported by the graders. Here are the steps you should follow to ensure that there are no problems that will cost you points on the grade. 1. When you have your project ready to submit, change the name of the project to Generic Piece Valdator username where you replace username with your username. For example, my project would be named Generic Piece Validator gpollice. 2. Export your project to a zipped archive. You can right-click on the project and select the Export… context menu item. Export to an archive file under the General menu. The project should have a check in the box next to its name and the project and classpath should be checked on the right side of the pane. 3. Save the project to a file called Generic Piece Validator username.zip where the username is yours. 4. Change the name of your project to some other name. Now try to import the project from your zipped archive that you saved in the previous step. 5. Run the tests to make sure everything is still working. 6. Submit the archive to the assignment on the Canvas page for the assignment. My estimate of the time it will take you to complete this assignment is 4-10 hours. It took me about 4 hours. Make sure that you allow enough time to get the assignment completed, cleaned up, checked, and submitted. Remember that late submissions are not accepted. 7 Grading This assignment is worth 100 points. The grade is calculated as follows. Note that some of the categories might yield negative points. Table 1: Grading rubric Criterion Max Points Code correctness. You begin with 65 points and lose one point for each test of mine that fails 65 Intentional code. When looking at your code, is it clear what the purpose of each class is? Are the methods named such that they are clear as to their purpose? Are there comments that follow the class guidelines. Is your code consistently formatted? 10 Code coverage/waste. Do you expose only what a client needs? Do you have code with no purpose and is not used? We will use the EclEmma code coverage too that is in Eclipse to see how much of your code is executed when running your tests. You begin with 15 points and lose one point for each percent or fraction of a percent less than 90%. This does not include enumerations and interfaces 15 TDD. Does your TODO task list clearly indicate the use of TDD? The grder will assess 0, 5, or 10 points on their assessment of your tasks, the order of the tasks, and your tests. 10 8

admin

Author admin

More posts by admin