View Javadoc

1   /**************************************************************************
2    Copyright 2005 Webstersmalley
3   
4    Licensed under the Apache License, Version 2.0 (the "License");
5    you may not use this file except in compliance with the License.
6    You may obtain a copy of the License at
7   
8    http://www.apache.org/licenses/LICENSE-2.0
9   
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15   *************************************************************************/
16  /*
17   * Created on 23-Aug-2005
18   */
19  package com.webstersmalley.chessweb.model.pieces;
20  
21  import com.webstersmalley.chessweb.model.Board;
22  import com.webstersmalley.chessweb.model.InvalidMoveException;
23  import com.webstersmalley.chessweb.model.Move;
24  import com.webstersmalley.chessweb.model.Piece;
25  import com.webstersmalley.chessweb.model.Position;
26  import com.webstersmalley.chessweb.model.Team;
27  
28  /***
29   * King class.
30   * 
31   * @author Matthew Smalley
32   */
33  public class King extends Piece {
34  
35      /*** White starting positions. * */
36      public static final String WHITE_STARTING_POSITIONS = "e1";
37  
38      /*** Black starting positions. * */
39      public static final String BLACK_STARTING_POSITIONS = "e8";
40  
41      /***
42       * Constructs the King.
43       * 
44       * @param team
45       *            the team.
46       */
47      public King(final Team team) {
48          super(team);
49          if (team == Team.WHITE) {
50              setStartingPositions(WHITE_STARTING_POSITIONS);
51          } else {
52              setStartingPositions(BLACK_STARTING_POSITIONS);
53          }
54      }
55  
56      /***
57       * Assert that a given piece is at a given position.
58       * 
59       * @param board the board
60       * @param position the position
61       * @param piece the piece
62       * @throws InvalidMoveException if the move is invalid.
63       */
64      private void assertPiece(final Board board, final String position,
65              final Piece piece) throws InvalidMoveException {
66          if (board.getAt(new Position(position)) == piece) {
67              return;
68          }
69          throw new InvalidMoveException("Expected a " + piece + " at position "
70              + position);
71      }
72  
73      /***
74       * Valid the Rook part of the castling.
75       * @param board the board.
76       * @param piece the piece. 
77       * @param start the start (of the rook move).
78       * @param destination the destination (of the rook move).
79       * @throws InvalidMoveException if the move is invalid (is not clear).
80       */
81      private void validateRookMove(final Board board, final Piece piece,
82              final String start, final String destination)
83              throws InvalidMoveException {
84          assertPiece(board, start, piece);
85          Move castlingMove = new Move(new Position(start), new Position(
86                  destination));
87          if (!castlingMove.isPathClear(board)) {
88              throw new InvalidMoveException("Rook's path is not clear.");
89          }
90      }
91  
92      /***
93       * Checks whether the castling is valid or not.
94       * Note if the move is not a castling, it just returns (forcing the 
95       * standard King movement check to be performed).
96       * @param move the move.
97       * @param board the board.
98       * @throws InvalidMoveException if the move is invalid.
99       * @return whether it's a castling move or not.
100      */
101     private boolean validateCastling(final Move move, final Board board)
102             throws InvalidMoveException {
103         try {
104 
105             if (getTeam() == Team.WHITE
106                 && move.getDestination().getAlgebraicNotation().equals("g1")) {
107                 // White kingside
108                 validateRookMove(board, WHITE_ROOK, "h1", "f1");
109                 move.setCastling(true);
110                 return true;
111             } else if (getTeam() == Team.WHITE
112                 && move.getDestination().getAlgebraicNotation().equals("c1")) {
113                 // White queenside
114                 validateRookMove(board, WHITE_ROOK, "a1", "d1");
115                 move.setCastling(true);
116                 return true;
117             } else if (getTeam() == Team.BLACK
118                 && move.getDestination().getAlgebraicNotation().equals("g8")) {
119                 // White kingside
120                 validateRookMove(board, BLACK_ROOK, "h8", "f8");
121                 move.setCastling(true);
122                 return true;
123             } else if (getTeam() == Team.BLACK
124                 && move.getDestination().getAlgebraicNotation().equals("c8")) {
125                 // White queenside
126                 validateRookMove(board, BLACK_ROOK, "a8", "d8");
127                 move.setCastling(true);
128                 return true;
129             }
130         } catch (InvalidMoveException e) {
131             throw new InvalidMoveException("Error castling: " + e.getMessage());
132         }
133         return false;
134     }
135 
136     /***
137      * Validates the direction.
138      * 
139      * @param move
140      *            the move
141      * @param board
142      *            the board
143      * @throws InvalidMoveException
144      *             if the move is invalid.
145      */
146     public final void validateDirection(final Move move, final Board board)
147             throws InvalidMoveException {
148         if (move.getSource().getAlgebraicNotation().equals(
149                 getStartingPositions())) {
150             if (validateCastling(move, board)) {
151                 return;
152             }
153         }
154 
155         if (move.getMaximumMagnitude() > 1) {
156             throw new InvalidMoveException(
157                     "Invalid move. Kings can only move one square!");
158         }
159     }
160 
161 }