Introducing the Move class
authorJaroslav Tulach <jtulach@netbeans.org>
Sun, 10 May 2009 22:05:31 +0200
changeset 3fd265fb9764c
parent 2 465c119a7434
child 4 fcf9dd2a8aed
Introducing the Move class
quoridor/src/main/java/cz/xelfi/quoridor/Board.java
quoridor/src/main/java/cz/xelfi/quoridor/Move.java
quoridor/src/main/java/cz/xelfi/quoridor/View.java
     1.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Board.java	Sun May 10 21:20:30 2009 +0200
     1.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Board.java	Sun May 10 22:05:31 2009 +0200
     1.3 @@ -3,6 +3,14 @@
     1.4  
     1.5  package cz.xelfi.quoridor;
     1.6  
     1.7 +import java.util.Arrays;
     1.8 +import java.util.BitSet;
     1.9 +import java.util.Collection;
    1.10 +import java.util.Collections;
    1.11 +import java.util.HashSet;
    1.12 +import java.util.List;
    1.13 +import java.util.Set;
    1.14 +
    1.15  /**
    1.16   * This is a class that represents a snapshot of the game position,
    1.17   * with all the placed and not-yet placed fences and player positions.
    1.18 @@ -15,9 +23,9 @@
    1.19   */
    1.20  public final class Board {
    1.21      /** players */
    1.22 -    private final java.util.List<Player> players;
    1.23 +    private final List<Player> players;
    1.24      /** fences placed on board */
    1.25 -    private final java.util.Set<Fence> fences;
    1.26 +    private final Set<Fence> fences;
    1.27      /** occurpied bits (coordinates encoded by toIndex methods) 
    1.28                           [N]
    1.29                 
    1.30 @@ -48,37 +56,41 @@
    1.31       * even x odd   == side of a fence
    1.32       * odd x even   == side of a fence
    1.33       */
    1.34 -    private final java.util.BitSet occupied;
    1.35 +    private final BitSet occupied;
    1.36 +    /** which player's turn is next? */
    1.37 +    private final int turn;
    1.38      
    1.39      /**
    1.40       * Creates a new instance of Board 
    1.41       */
    1.42      private Board (int x1, int y1, int f1, int x2, int y2, int f2) {
    1.43 -        this.players = java.util.Collections.unmodifiableList (java.util.Arrays.asList (new Player[] {
    1.44 +        this.players = Collections.unmodifiableList (Arrays.asList (new Player[] {
    1.45              new Player (x1, y1, f1, Player.Direction.NORTH),
    1.46              new Player (x2, y2, f2, Player.Direction.SOUTH),
    1.47          }));
    1.48 -        this.fences = java.util.Collections.emptySet ();
    1.49 +        this.fences = Collections.emptySet ();
    1.50          try {
    1.51              this.occupied = computeOccupied (players, fences);
    1.52          } catch (IllegalPositionException ex) {
    1.53              throw new IllegalStateException (ex.getMessage ());
    1.54          }
    1.55 +        this.turn = 0;
    1.56      }
    1.57      
    1.58      /** Copy constructor that provides players and fences.
    1.59       */
    1.60 -    private Board (java.util.List<Player> players, java.util.Set<Fence> fences) 
    1.61 +    private Board (int turn, List<Player> players, Set<Fence> fences)
    1.62      throws IllegalPositionException {
    1.63 -        this.players = java.util.Collections.unmodifiableList (players);
    1.64 -        this.fences = java.util.Collections.unmodifiableSet (fences);
    1.65 +        this.players = Collections.unmodifiableList (players);
    1.66 +        this.fences = Collections.unmodifiableSet (fences);
    1.67          this.occupied = computeOccupied (players, fences);
    1.68          
    1.69          for (Player p : players) {
    1.70 -            if (!accessibleFinalLine (p, p.endDirection, occupied, new java.util.BitSet ())) {
    1.71 +            if (!accessibleFinalLine (p, p.endDirection, occupied, new BitSet ())) {
    1.72                  throw new IllegalPositionException ("Player " + p + " cannot reach " + p.endDirection + " side"); // NOI18N
    1.73              }
    1.74          }
    1.75 +        this.turn = turn % players.size();
    1.76      }
    1.77      
    1.78      /** Creates initial empty board with default positions of 
    1.79 @@ -91,7 +103,7 @@
    1.80      /** Returns players in the game.
    1.81       * @return player object
    1.82       */
    1.83 -    public java.util.List<Player> getPlayers () {
    1.84 +    public List<Player> getPlayers () {
    1.85          return players;
    1.86      }
    1.87      
    1.88 @@ -99,14 +111,24 @@
    1.89       * 
    1.90       * @return immutable set of Fences
    1.91       */
    1.92 -    public java.util.Set<Fence> getFences () {
    1.93 +    public Set<Fence> getFences () {
    1.94          return fences;
    1.95      }
    1.96 +
    1.97 +    /** The player that is supposed to play now.
    1.98 +     * @return the player to do next move
    1.99 +     */
   1.100 +    public Player getCurrentPlayer() {
   1.101 +        return players.get(turn);
   1.102 +    }
   1.103      
   1.104 -    //
   1.105 -    // Moves
   1.106 -    // 
   1.107 -    
   1.108 +    public Board apply(Move move) throws IllegalPositionException {
   1.109 +        if (move.direction != null) {
   1.110 +            return move(getCurrentPlayer(), move.direction);
   1.111 +        } else {
   1.112 +            return fence(getCurrentPlayer(), move.fence);
   1.113 +        }
   1.114 +    }
   1.115  
   1.116      /** Moves the player in given direction. The direction usually
   1.117       * is one of Player.Direction constants, but in case the move
   1.118 @@ -118,7 +140,7 @@
   1.119       * @return the new board
   1.120       * @exception IllegalPositionException if the move is not possible
   1.121       */
   1.122 -    public Board move (Player player, Player.Direction... where) throws IllegalPositionException {
   1.123 +    final Board move (Player player, Player.Direction... where) throws IllegalPositionException {
   1.124          if (where.length != 1 && where.length != 2) {
   1.125              throw new IllegalPositionException ("Move over one or two Directions"); // NOI18N
   1.126          }
   1.127 @@ -130,7 +152,7 @@
   1.128          
   1.129          if (where.length == 1) {
   1.130              arr[index] = oneStep;
   1.131 -            return new Board (java.util.Arrays.asList (arr), fences);
   1.132 +            return new Board(turn + 1, Arrays.asList (arr), fences);
   1.133          }
   1.134  
   1.135          // straight jump over
   1.136 @@ -148,7 +170,7 @@
   1.137                      throw new IllegalPositionException ("You have to jump straight if there is no wall"); // NOI18N
   1.138                  }
   1.139                  arr[index] = newPosition (oneStep, where[1]);
   1.140 -                return new Board (java.util.Arrays.asList (arr), fences);
   1.141 +                return new Board (turn + 1, Arrays.asList (arr), fences);
   1.142              }
   1.143          }
   1.144          throw new IllegalPositionException ("Cannot use multi direction when there is not oponent pawn"); // NOI18N
   1.145 @@ -190,23 +212,23 @@
   1.146       * @return the new board
   1.147       * @exception IllegalPositionException if the move is not possible
   1.148       */
   1.149 -    public Board fence (Player player, char x, int y, Fence.Orientation orientation) throws IllegalPositionException {
   1.150 +    final Board fence (Player player, char x, int y, Fence.Orientation orientation) throws IllegalPositionException {
   1.151 +        return fence(player, new Fence ((x - 'A') * 2 + 1, y * 2 - 1, orientation));
   1.152 +    }
   1.153 +
   1.154 +    private Board fence(Player player, Fence fence) throws IllegalPositionException {
   1.155          if (player.getFences () == 0) {
   1.156              throw new IllegalPositionException ("Not enough fences: " + player); // NOI18N
   1.157          }
   1.158          
   1.159 -        if (x < 'A' || 'H' < x) {
   1.160 -            throw new IllegalPositionException ("x coordinate has to be from A to H"); // NOI18N
   1.161 -        }
   1.162 -        
   1.163          int index = players.indexOf (player);
   1.164          Player[] arr = players.toArray (new Player[0]);
   1.165          arr[index] = new Player (arr[index].getX (), arr[index].getY (), arr[index].getFences () - 1, arr[index].endDirection);
   1.166          
   1.167 -        java.util.HashSet<Fence> fen = new java.util.HashSet<Fence> (this.fences);
   1.168 -        fen.add (new Fence ((x - 'A') * 2 + 1, y * 2 - 1, orientation));
   1.169 +        HashSet<Fence> fen = new HashSet<Fence> (this.fences);
   1.170 +        fen.add (fence);
   1.171          
   1.172 -        return new Board (java.util.Arrays.asList (arr), fen);
   1.173 +        return new Board (turn + 1, Arrays.asList (arr), fen);
   1.174      }
   1.175      
   1.176      /** Writes the board to the provided writer. 
   1.177 @@ -329,7 +351,7 @@
   1.178      }
   1.179      
   1.180      
   1.181 -    private static Player newPosition (Player old, Player.Direction direction, java.util.BitSet occupied) throws IllegalPositionException {
   1.182 +    private static Player newPosition (Player old, Player.Direction direction, BitSet occupied) throws IllegalPositionException {
   1.183          int nx = old.x;
   1.184          int ny = old.y;
   1.185          int fx = old.x;
   1.186 @@ -372,7 +394,7 @@
   1.187       * @param reached bits on squares that were already reached (modified during run)
   1.188       * @return true if the end line can be reached
   1.189       */
   1.190 -    private static boolean accessibleFinalLine (Player position, Player.Direction endDir, java.util.BitSet fences, java.util.BitSet reached) {
   1.191 +    private static boolean accessibleFinalLine (Player position, Player.Direction endDir, BitSet fences, BitSet reached) {
   1.192          int index = toIndex (position);
   1.193          if (reached.get (index)) {
   1.194              // already visited without success
   1.195 @@ -413,10 +435,10 @@
   1.196      
   1.197      /** Computes mask of the occupried bits.
   1.198       */
   1.199 -    private static java.util.BitSet computeOccupied (
   1.200 -        java.util.Collection<Player> players, java.util.Collection<Fence> fences
   1.201 +    private static BitSet computeOccupied (
   1.202 +        Collection<Player> players, Collection<Fence> fences
   1.203      ) throws IllegalPositionException {
   1.204 -        java.util.BitSet occupied = new java.util.BitSet (17 * 17);
   1.205 +        BitSet occupied = new BitSet (17 * 17);
   1.206          
   1.207          for (Player p : players) {
   1.208              if (p.getX () % 2 == 1) throw new IllegalPositionException ("Wrong player position: " + p); // NOI18N
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Move.java	Sun May 10 22:05:31 2009 +0200
     2.3 @@ -0,0 +1,43 @@
     2.4 +/*
     2.5 + * To change this template, choose Tools | Templates
     2.6 + * and open the template in the editor.
     2.7 + */
     2.8 +
     2.9 +package cz.xelfi.quoridor;
    2.10 +
    2.11 +import cz.xelfi.quoridor.Board.Fence;
    2.12 +import cz.xelfi.quoridor.Board.Player.Direction;
    2.13 +
    2.14 +/**
    2.15 + *
    2.16 + * @author Jaroslav Tulach <jtulach@netbeans.org>
    2.17 + */
    2.18 +public final class Move extends Object {
    2.19 +    final Direction[] direction;
    2.20 +    final Fence fence;
    2.21 +
    2.22 +    private Move(Direction... arr) {
    2.23 +        direction = arr;
    2.24 +        fence = null;
    2.25 +    }
    2.26 +    private Move(Fence f) {
    2.27 +        fence = f;
    2.28 +        direction = null;
    2.29 +    }
    2.30 +
    2.31 +    public static final Move NORTH = new Move(Direction.NORTH);
    2.32 +    public static final Move EAST = new Move(Direction.EAST);
    2.33 +    public static final Move SOUTH = new Move(Direction.SOUTH);
    2.34 +    public static final Move WEST = new Move(Direction.WEST);
    2.35 +
    2.36 +    public static Move fence(char x, int y, Fence.Orientation orientation) throws IllegalPositionException {
    2.37 +        if (x < 'A' || 'H' < x) {
    2.38 +            throw new IllegalPositionException ("x coordinate has to be from A to H"); // NOI18N
    2.39 +        }
    2.40 +        return new Move(new Fence ((x - 'A') * 2 + 1, y * 2 - 1, orientation));
    2.41 +    }
    2.42 +
    2.43 +    public static Move jump(Direction first, Direction second) {
    2.44 +        return new Move(first, second);
    2.45 +    }
    2.46 +}
     3.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/View.java	Sun May 10 21:20:30 2009 +0200
     3.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/View.java	Sun May 10 22:05:31 2009 +0200
     3.3 @@ -18,7 +18,7 @@
     3.4   *
     3.5   * @author Jaroslav Tulach
     3.6   */
     3.7 -public class View extends JComponent {
     3.8 +class View extends JComponent {
     3.9      /** fence size */
    3.10      private final static int SIZE_FENCE = 20;
    3.11      private final static int SIZE_FIELD = 50;