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