quoridor/src/main/java/cz/xelfi/quoridor/Move.java
author Jaroslav Tulach <jtulach@netbeans.org>
Thu, 10 Sep 2009 23:19:40 +0200
changeset 75 6802034b7a6f
parent 34 34baf57f2d4e
child 178 4b78d4f028b3
permissions -rw-r--r--
Support for giving up the game
jtulach@3
     1
/*
jtulach@8
     2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
jtulach@8
     3
 *
jtulach@8
     4
 * The contents of this file are subject to the terms of either the GNU
jtulach@8
     5
 * General Public License Version 2 only ("GPL") or the Common
jtulach@8
     6
 * Development and Distribution License("CDDL") (collectively, the
jtulach@8
     7
 * "License"). You may not use this file except in compliance with the
jtulach@8
     8
 * License. You can obtain a copy of the License at
jtulach@8
     9
 * http://www.netbeans.org/cddl-gplv2.html
jtulach@8
    10
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
jtulach@8
    11
 * specific language governing permissions and limitations under the
jtulach@8
    12
 * License.  When distributing the software, include this License Header
jtulach@8
    13
 * Notice in each file and include the License file at
jtulach@8
    14
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
jtulach@8
    15
 * particular file as subject to the "Classpath" exception as provided
jtulach@8
    16
 * by Sun in the GPL Version 2 section of the License file that
jtulach@8
    17
 * accompanied this code. If applicable, add the following below the
jtulach@8
    18
 * License Header, with the fields enclosed by brackets [] replaced by
jtulach@8
    19
 * your own identifying information:
jtulach@8
    20
 * "Portions Copyrighted [year] [name of copyright owner]"
jtulach@8
    21
 *
jtulach@8
    22
 * Contributor(s):
jtulach@8
    23
 *
jtulach@8
    24
 * Portions Copyrighted 2009 Jaroslav Tulach
jtulach@3
    25
 */
jtulach@3
    26
jtulach@3
    27
package cz.xelfi.quoridor;
jtulach@3
    28
jtulach@15
    29
import cz.xelfi.quoridor.Player.Direction;
jtulach@30
    30
import java.util.Arrays;
jtulach@3
    31
jtulach@16
    32
/** Encapsulates one possible move that can be applied to existing {@link Board}
jtulach@16
    33
 * by calling its {@link Board#apply} method.
jtulach@3
    34
 *
jtulach@3
    35
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jtulach@3
    36
 */
jtulach@3
    37
public final class Move extends Object {
jtulach@3
    38
    final Direction[] direction;
jtulach@3
    39
    final Fence fence;
jtulach@3
    40
jtulach@3
    41
    private Move(Direction... arr) {
jtulach@3
    42
        direction = arr;
jtulach@3
    43
        fence = null;
jtulach@3
    44
    }
jtulach@3
    45
    private Move(Fence f) {
jtulach@3
    46
        fence = f;
jtulach@3
    47
        direction = null;
jtulach@3
    48
    }
jtulach@75
    49
    private Move() {
jtulach@75
    50
        fence = null;
jtulach@75
    51
        direction = null;
jtulach@75
    52
    }
jtulach@3
    53
jtulach@4
    54
    /** Moves the player's figure to north */
jtulach@3
    55
    public static final Move NORTH = new Move(Direction.NORTH);
jtulach@4
    56
    /** Moves the player's figure to east */
jtulach@3
    57
    public static final Move EAST = new Move(Direction.EAST);
jtulach@4
    58
    /** Moves the player's figure to south */
jtulach@3
    59
    public static final Move SOUTH = new Move(Direction.SOUTH);
jtulach@4
    60
    /** Moves the player's figure to west */
jtulach@3
    61
    public static final Move WEST = new Move(Direction.WEST);
jtulach@75
    62
    /** Allows the player to resign the game */
jtulach@75
    63
    public static final Move RESIGN = new Move();
jtulach@3
    64
jtulach@4
    65
    /** Places a fence into given position with specified orientation.
jtulach@4
    66
     * The faces postions are numbered 1-8 and A-H according to following
jtulach@4
    67
     * graph: <pre>
jtulach@4
    68
            H   G   F   E   D   C   B   A
jtulach@4
    69
            |   |   |   |   |   |   |   |
jtulach@4
    70
        +-----------------------------------+
jtulach@4
    71
        |                                   |
jtulach@4
    72
     1--|   +   +   +   +   +   +   +   +   |--1
jtulach@4
    73
        |                                   |
jtulach@4
    74
     2--|   +   +   +   +   +   +   +   +   |--2
jtulach@4
    75
        |                                   |
jtulach@4
    76
     3--|   +   +   +   +   +   +   +   +   |--3
jtulach@4
    77
        |                                   |
jtulach@4
    78
     4--|   +   +   +   +   +   +   +   +   |--4
jtulach@4
    79
[E]     |                                   |     [W]
jtulach@4
    80
     5--|   +   +   +   +   +   +   +   +   |--5
jtulach@4
    81
        |                                   |
jtulach@4
    82
     6--|   +   +   +   +   +   +   +   +   |--6
jtulach@4
    83
        |                                   |
jtulach@4
    84
     7--|   +   +   +   +   +   +   +   +   |--7
jtulach@4
    85
        |                                   |
jtulach@4
    86
     8--|   +   +   +   +   +   +   +   +   |--8
jtulach@4
    87
        |                                   |
jtulach@4
    88
        +-----------------------------------+
jtulach@4
    89
            |   |   |   |   |   |   |   |
jtulach@4
    90
            H   G   F   E   D   C   B   A
jtulach@4
    91
     * </pre>
jtulach@4
    92
     *
jtulach@4
    93
     *
jtulach@21
    94
     * @param column x-coordinate of the middle of the fence from 'A' to 'B'
jtulach@21
    95
     * @param row y-coordinate of the middle of the fence
jtulach@4
    96
     * @param orientation place the fence horizontally or vertically
jtulach@4
    97
     * @return the new board
jtulach@4
    98
     * @exception IllegalPositionException if the move is not possible
jtulach@4
    99
     */
jtulach@21
   100
    public static Move fence(char column, int row, Fence.Orientation orientation) throws IllegalPositionException {
jtulach@21
   101
        if (column < 'A' || 'H' < column) {
jtulach@3
   102
            throw new IllegalPositionException ("x coordinate has to be from A to H"); // NOI18N
jtulach@3
   103
        }
jtulach@31
   104
        if (row < 1 || row > 8) {
jtulach@31
   105
            throw new IllegalPositionException ("y coordinate has to be from 1 to 8"); // NOI18N
jtulach@31
   106
        }
jtulach@21
   107
        return new Move(new Fence ((column - 'A') * 2 + 1, row * 2 - 1, orientation));
jtulach@3
   108
    }
jtulach@3
   109
jtulach@4
   110
    /** Moves the player in given directions. After applying
jtulach@4
   111
     * the first direction, the pawn has to get on a position
jtulach@4
   112
     * that is occupied by other player's pawn.
jtulach@4
   113
     *
jtulach@4
   114
     * @param where one or two directions saying where
jtulach@4
   115
     * @return the new board
jtulach@4
   116
     * @exception IllegalPositionException if the move is not possible
jtulach@4
   117
     */
jtulach@3
   118
    public static Move jump(Direction first, Direction second) {
jtulach@3
   119
        return new Move(first, second);
jtulach@3
   120
    }
jtulach@30
   121
jtulach@34
   122
    /** Converts the value of the move string into valid move, if possible.
jtulach@34
   123
     *
jtulach@34
   124
     * @param move the string in format used by {@link #toString()}
jtulach@34
   125
     * @return the move which's toString() returns the move parameter
jtulach@34
   126
     * @throws IllegalPositionException raised in case the parameter does not
jtulach@34
   127
     *      represent a valid move
jtulach@34
   128
     */
jtulach@34
   129
    public static Move valueOf(String move) throws IllegalPositionException {
jtulach@34
   130
        switch (move.length()) {
jtulach@34
   131
            case 3:
jtulach@34
   132
            if (move.startsWith("H")) {
jtulach@34
   133
                return Move.fence(move.charAt(1), move.charAt(2) - '0', Fence.Orientation.HORIZONTAL);
jtulach@34
   134
            }
jtulach@34
   135
            if (move.startsWith("V")) {
jtulach@34
   136
                return Move.fence(move.charAt(1), move.charAt(2) - '0', Fence.Orientation.VERTICAL);
jtulach@34
   137
            }
jtulach@34
   138
            break;
jtulach@34
   139
            case 2:
jtulach@34
   140
                return Move.jump(Direction.valueOf(move.charAt(0)), Direction.valueOf(move.charAt(1)));
jtulach@34
   141
            case 1:
jtulach@34
   142
                switch (move.charAt(0)) {
jtulach@34
   143
                    case 'N': return Move.NORTH;
jtulach@34
   144
                    case 'S': return Move.SOUTH;
jtulach@34
   145
                    case 'E': return Move.EAST;
jtulach@34
   146
                    case 'W': return Move.WEST;
jtulach@34
   147
                }
jtulach@75
   148
            case 6:
jtulach@75
   149
                if ("RESIGN".equals(move)) {
jtulach@75
   150
                    return Move.RESIGN;
jtulach@75
   151
                }
jtulach@34
   152
        }
jtulach@34
   153
        throw new IllegalPositionException(move);
jtulach@34
   154
    }
jtulach@34
   155
jtulach@30
   156
    @Override
jtulach@30
   157
    public String toString() {
jtulach@30
   158
        if (fence != null) {
jtulach@34
   159
            switch (fence.getOrientation()) {
jtulach@34
   160
                case HORIZONTAL: return "H" + fence.getColumn() + fence.getRow();
jtulach@34
   161
                case VERTICAL: return "V" + fence.getColumn() + fence.getRow();
jtulach@34
   162
            }
jtulach@34
   163
            throw new IllegalStateException();
jtulach@30
   164
        } else {
jtulach@75
   165
            if (direction == null) {
jtulach@75
   166
                return "RESIGN"; // NOI18N
jtulach@75
   167
            }
jtulach@34
   168
            StringBuilder sb = new StringBuilder();
jtulach@34
   169
            for (Direction d : direction) {
jtulach@34
   170
                sb.append(d.name().charAt(0));
jtulach@34
   171
            }
jtulach@34
   172
            return sb.toString();
jtulach@30
   173
        }
jtulach@30
   174
    }
jtulach@30
   175
jtulach@30
   176
    @Override
jtulach@30
   177
    public boolean equals(Object obj) {
jtulach@30
   178
        if (obj == null) {
jtulach@30
   179
            return false;
jtulach@30
   180
        }
jtulach@30
   181
        if (getClass() != obj.getClass()) {
jtulach@30
   182
            return false;
jtulach@30
   183
        }
jtulach@30
   184
        final Move other = (Move) obj;
jtulach@30
   185
        if (!Arrays.deepEquals(this.direction, other.direction)) {
jtulach@30
   186
            return false;
jtulach@30
   187
        }
jtulach@30
   188
        if (this.fence != other.fence && (this.fence == null || !this.fence.equals(other.fence))) {
jtulach@30
   189
            return false;
jtulach@30
   190
        }
jtulach@30
   191
        return true;
jtulach@30
   192
    }
jtulach@30
   193
jtulach@30
   194
    @Override
jtulach@30
   195
    public int hashCode() {
jtulach@30
   196
        int hash = 3;
jtulach@30
   197
        hash = 47 * hash + Arrays.deepHashCode(this.direction);
jtulach@30
   198
        hash = 47 * hash + (this.fence != null ? this.fence.hashCode() : 0);
jtulach@30
   199
        return hash;
jtulach@30
   200
    }
jtulach@30
   201
jtulach@30
   202
jtulach@3
   203
}