2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * The contents of this file are subject to the terms of either the GNU
5 * General Public License Version 2 only ("GPL") or the Common
6 * Development and Distribution License("CDDL") (collectively, the
7 * "License"). You may not use this file except in compliance with the
8 * License. You can obtain a copy of the License at
9 * http://www.netbeans.org/cddl-gplv2.html
10 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
11 * specific language governing permissions and limitations under the
12 * License. When distributing the software, include this License Header
13 * Notice in each file and include the License file at
14 * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
15 * particular file as subject to the "Classpath" exception as provided
16 * by Sun in the GPL Version 2 section of the License file that
17 * accompanied this code. If applicable, add the following below the
18 * License Header, with the fields enclosed by brackets [] replaced by
19 * your own identifying information:
20 * "Portions Copyrighted [year] [name of copyright owner]"
24 * Portions Copyrighted 2009 Jaroslav Tulach
27 package cz.xelfi.quoridor;
29 import cz.xelfi.quoridor.Player.Direction;
30 import java.util.Arrays;
32 /** Encapsulates one possible move that can be applied to existing {@link Board}
33 * by calling its {@link Board#apply} method.
35 * @author Jaroslav Tulach <jtulach@netbeans.org>
37 public final class Move extends Object {
38 final Direction[] direction;
41 private Move(Direction... arr) {
45 private Move(Fence f) {
50 /** Moves the player's figure to north */
51 public static final Move NORTH = new Move(Direction.NORTH);
52 /** Moves the player's figure to east */
53 public static final Move EAST = new Move(Direction.EAST);
54 /** Moves the player's figure to south */
55 public static final Move SOUTH = new Move(Direction.SOUTH);
56 /** Moves the player's figure to west */
57 public static final Move WEST = new Move(Direction.WEST);
59 /** Places a fence into given position with specified orientation.
60 * The faces postions are numbered 1-8 and A-H according to following
64 +-----------------------------------+
66 1--| + + + + + + + + |--1
68 2--| + + + + + + + + |--2
70 3--| + + + + + + + + |--3
72 4--| + + + + + + + + |--4
74 5--| + + + + + + + + |--5
76 6--| + + + + + + + + |--6
78 7--| + + + + + + + + |--7
80 8--| + + + + + + + + |--8
82 +-----------------------------------+
88 * @param column x-coordinate of the middle of the fence from 'A' to 'B'
89 * @param row y-coordinate of the middle of the fence
90 * @param orientation place the fence horizontally or vertically
91 * @return the new board
92 * @exception IllegalPositionException if the move is not possible
94 public static Move fence(char column, int row, Fence.Orientation orientation) throws IllegalPositionException {
95 if (column < 'A' || 'H' < column) {
96 throw new IllegalPositionException ("x coordinate has to be from A to H"); // NOI18N
98 if (row < 1 || row > 8) {
99 throw new IllegalPositionException ("y coordinate has to be from 1 to 8"); // NOI18N
101 return new Move(new Fence ((column - 'A') * 2 + 1, row * 2 - 1, orientation));
104 /** Moves the player in given directions. After applying
105 * the first direction, the pawn has to get on a position
106 * that is occupied by other player's pawn.
108 * @param where one or two directions saying where
109 * @return the new board
110 * @exception IllegalPositionException if the move is not possible
112 public static Move jump(Direction first, Direction second) {
113 return new Move(first, second);
116 /** Converts the value of the move string into valid move, if possible.
118 * @param move the string in format used by {@link #toString()}
119 * @return the move which's toString() returns the move parameter
120 * @throws IllegalPositionException raised in case the parameter does not
121 * represent a valid move
123 public static Move valueOf(String move) throws IllegalPositionException {
124 switch (move.length()) {
126 if (move.startsWith("H")) {
127 return Move.fence(move.charAt(1), move.charAt(2) - '0', Fence.Orientation.HORIZONTAL);
129 if (move.startsWith("V")) {
130 return Move.fence(move.charAt(1), move.charAt(2) - '0', Fence.Orientation.VERTICAL);
134 return Move.jump(Direction.valueOf(move.charAt(0)), Direction.valueOf(move.charAt(1)));
136 switch (move.charAt(0)) {
137 case 'N': return Move.NORTH;
138 case 'S': return Move.SOUTH;
139 case 'E': return Move.EAST;
140 case 'W': return Move.WEST;
143 throw new IllegalPositionException(move);
147 public String toString() {
149 switch (fence.getOrientation()) {
150 case HORIZONTAL: return "H" + fence.getColumn() + fence.getRow();
151 case VERTICAL: return "V" + fence.getColumn() + fence.getRow();
153 throw new IllegalStateException();
155 StringBuilder sb = new StringBuilder();
156 for (Direction d : direction) {
157 sb.append(d.name().charAt(0));
159 return sb.toString();
164 public boolean equals(Object obj) {
168 if (getClass() != obj.getClass()) {
171 final Move other = (Move) obj;
172 if (!Arrays.deepEquals(this.direction, other.direction)) {
175 if (this.fence != other.fence && (this.fence == null || !this.fence.equals(other.fence))) {
182 public int hashCode() {
184 hash = 47 * hash + Arrays.deepHashCode(this.direction);
185 hash = 47 * hash + (this.fence != null ? this.fence.hashCode() : 0);