辅导案例-CS4233

欢迎使用51辅导,51作业君孵化低价透明的学长辅导平台,服务保持优质,平均费用压低50%以上! 51fudao.top
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
Piece 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
51作业君

Email:51zuoyejun

@gmail.com

添加客服微信: abby12468