Exercises


  1. Create an enumeration for the two colors. Encapsulate the enumeration so that only the Piece class is aware of its existence. Depending on your implementation, this may require significant refactoring. Note each place you have to change in order to introduce the changeHow could you have removed the need for any changes you felt were done twice?

    You might consider also creating an enumeration for the piece values. If your code allows you to do so easily, go ahead. You may want to wait until Lesson 6, where you will learn how to associate data with enumeration values.

  2. Introduce an enum for each piece. You will want to divorce the piece representation from the piece enum.

  3. Create a separate factory method on Piece for each color/piece combination (e.g., createWhitePawn, createBlackRook).

     package pieces; import junit.framework.TestCase; public class PieceTest extends TestCase {    public void testCreate() {       verifyCreation(          Piece.createWhitePawn(), Piece.createBlackPawn(),          Piece.Type.PAWN, Piece.PAWN_REPRESENTATION);       verifyCreation(          Piece.createWhiteRook(), Piece.createBlackRook(),          Piece.Type.ROOK, Piece.ROOK_REPRESENTATION);       verifyCreation(          Piece.createWhiteKnight(), Piece.createBlackKnight(),          Piece.Type.KNIGHT, Piece.KNIGHT_REPRESENTATION);       verifyCreation(          Piece.createWhiteBishop(), Piece.createBlackBishop(),          Piece.Type.BISHOP, Piece.BISHOP_REPRESENTATION);       verifyCreation(Piece.createWhiteQueen(), Piece.createBlackQueen(),          Piece.Type.QUEEN, Piece.QUEEN_REPRESENTATION);       verifyCreation(Piece.createWhiteKing(), Piece.createBlackKing(),          Piece.Type.KING, Piece.KING_REPRESENTATION);       Piece blank = Piece.noPiece();       assertEquals('.', blank.getRepresentation());       assertEquals(Piece.Type.NO_PIECE, blank.getType());    }    private void verifyCreation(Piece whitePiece, Piece blackPiece,          Piece.Type type, char representation) {       assertTrue(whitePiece.isWhite());       assertEquals(type, whitePiece.getType());       assertEquals(representation, whitePiece.getRepresentation());       assertTrue(blackPiece.isBlack());       assertEquals(type, blackPiece.getType());       assertEquals(Character.toUpperCase(representation),          blackPiece.getRepresentation());    } } 

    Reduce the createWhite and createBlack methods to a single private factory method that uses an if clause.

  4. Write code in Board to return the number of pieces, given the color and piece representation. For example, the below board should return 3 if you ask it for the number of black pawns. Calculate the count on demand (in other words, do not track the counts as you create pieces).

      . K R . . . . .   P . P B . . . .   . P . . Q . . .   . . . . . . . .   . . . . . n q .   . . . . . p . .   . . . . . . p .   . . . . r k . .  

  5. Create a method to retrieve the piece at a given location. Given an initial board setup, asking for the piece at "a8" returns the black rook. The white king is at "e1".

    Use utility methods defined on the Character class to help convert the individual characters of the location string to numeric indexes. Note: Your board may be flipped; in other words, rank 1 may be at the top and rank 8 at the bottom. Your code will have to invert the rank passed in.

     R N B Q K B N R 8 (rank 8) P P P P P P P P 7 . . . . . . . . 6 . . . . . . . . 5 . . . . . . . . 4 . . . . . . . . 3 p p p p p p p p 2 r n b q k b n r 1 (rank 1) a b c d e f g h    files 

    In the next exercise, you will create the ability to place pieces on an empty board. Start by adding a test that verifies that a newly instantiated Board object contains no pieces. This will lead you to a bit of refactoring. You may need to replace use of the add method on ArrayList with the set method.

  6. Create the code necessary to place pieces at arbitrary positions on the board. Make sure you refactor your solution with earlier code you've written to manage squares.

     . . . . . . . . 8  (rank 8) . . . . . . . . 7 . K . . . . . . 6 . R . . . . . . 5 . . k . . . . . 4 . . . . . . . . 3 . . . . . . . . 2 . . . . . . . . 1  (rank 1) a b c d e f g h       files  

  7. In chess programs, determining the relative strength of board positions is pivotal in determining which move to make. Using a very primitive board evaluation function, you will add up the values of the pieces on the board. Calculate this sum by adding 9 points for a queen, 5 points for a rook, 3 points for a bishop, and 2.5 points for a knight. Add 0.5 points for a pawn that is on the same file as a pawn of the same color and 1 point for a pawn otherwise. Remember to count the points for only one side at a time.

       . K R . . . . . 8   P . P B . . . . 7   . P . . Q . . . 6   . . . . . . . . 5   . . . . . n q . 4   . . . . . p . p 3   . . . . . p p . 2   . . . . r k . . 1   a b c d e f g h 

    For the example shown, black would have a strength of 20, and white would have a strength of 19.5.

    Develop your solution incrementally. Start with a single piece on the board. Add pieces to the board one by one, altering your assertions each time. Finally, add the complex scenario of determining if another pawn is in the same file.

  8. As you loop through all pieces on the board, assign the strength of each piece to the Piece object itself. For each side (black and white), gather the list of pieces in a collection. Ensure that the collection is sorted in order from the piece with the highest value to the piece with the lowest value.

  9. Examine your code for an opportunity to create an interface. Does the system feel cleaner or more cluttered? Be wary of introducing an interface without needremember that simplicity requires "fewest classes, fewest methods" shortly after "no duplication."

  10. Go through the code you have produced so far and look for opportunities to use early returns and guard clauses to simplify your code.

  11. Go through the code you have produced so far and ensure that you are using interfaces rather than concrete implementations wherever possible. In particular, examine your usages of collections and ensure you are programming to the interfaces.

Also: While the static import facility can make code more difficult to follow, one appropriate place you can use it is in test code. Test code generally interacts with a single target class. If the target class contains class constants, you can use static import in the test class for these constants. The context should make it clear as to where the constants are defined.

Alter your code to make judicious use of import static.



Agile Java. Crafting Code with Test-Driven Development
Agile Javaв„ў: Crafting Code with Test-Driven Development
ISBN: 0131482394
EAN: 2147483647
Year: 2003
Pages: 391
Authors: Jeff Langr

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net