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
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
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
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
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
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 }