Showing x when a move to certain position is impossible, showing o when it is fine. Adding Board.findMove method to keep the allowed move logic.
authorJaroslav Tulach <jaroslav.tulach@apidesign.org>
Sun, 05 Sep 2010 11:04:26 +0200
changeset 253ee02205edf13
parent 252 2769784e86da
child 254 1273bfb0e2e7
Showing x when a move to certain position is impossible, showing o when it is fine. Adding Board.findMove method to keep the allowed move logic.
pom.xml
quoridor/pom.xml
quoridor/src/main/java/cz/xelfi/quoridor/Board.java
quoridor/src/main/java/cz/xelfi/quoridor/Move.java
quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java
visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java
     1.1 --- a/pom.xml	Sun Sep 05 07:07:35 2010 +0200
     1.2 +++ b/pom.xml	Sun Sep 05 11:04:26 2010 +0200
     1.3 @@ -29,7 +29,7 @@
     1.4        <url>http://apidesign.org</url>
     1.5    </organization>
     1.6    <properties>
     1.7 -      <quoridorVersion>1.3</quoridorVersion>
     1.8 +      <quoridorVersion>1.4</quoridorVersion>
     1.9        <webidorVersion>1.17</webidorVersion>
    1.10        <visidorVersion>1.0-SNAPSHOT</visidorVersion>
    1.11        <freemarkerVersion>1.60</freemarkerVersion>
     2.1 --- a/quoridor/pom.xml	Sun Sep 05 07:07:35 2010 +0200
     2.2 +++ b/quoridor/pom.xml	Sun Sep 05 11:04:26 2010 +0200
     2.3 @@ -35,6 +35,12 @@
     2.4                  <artifactId>maven-bundle-plugin</artifactId>
     2.5                  <version>2.0.1</version>
     2.6                  <extensions>true</extensions>
     2.7 +                <configuration>
     2.8 +                    <instructions>
     2.9 +                        <Export-Package>cz.xelfi.quoridor</Export-Package>
    2.10 +                        <Private-Package>cz.xelfi.quoridor.*</Private-Package>
    2.11 +                    </instructions>
    2.12 +                </configuration>
    2.13              </plugin>
    2.14              <plugin>
    2.15                  <groupId>org.apache.maven.plugins</groupId>
     3.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Board.java	Sun Sep 05 07:07:35 2010 +0200
     3.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Board.java	Sun Sep 05 11:04:26 2010 +0200
     3.3 @@ -41,6 +41,8 @@
     3.4  import java.util.List;
     3.5  import java.util.Set;
     3.6  import java.util.TreeSet;
     3.7 +import java.util.logging.Level;
     3.8 +import java.util.logging.Logger;
     3.9  import java.util.regex.Matcher;
    3.10  import java.util.regex.Pattern;
    3.11  
    3.12 @@ -207,17 +209,53 @@
    3.13          if (getWinner() != null) {
    3.14              throw new IllegalPositionException("Game finished!"); // NOI18N
    3.15          }
    3.16 +        return apply(move, getCurrentPlayer());
    3.17 +    }
    3.18  
    3.19 +    private Board apply(Move move, Player p) throws IllegalPositionException {
    3.20          if (move.direction != null) {
    3.21 -            return move(getCurrentPlayer(), move.direction);
    3.22 +            return move(p, move.direction);
    3.23          } else {
    3.24              if (move.fence != null) {
    3.25 -                return fence(getCurrentPlayer(), move.fence);
    3.26 +                return fence(p, move.fence);
    3.27              } else {
    3.28                  return new Board(this, turn + 1);
    3.29              }
    3.30          }
    3.31      }
    3.32 +    
    3.33 +    /** Is there a move that would take the player onto given position while
    3.34 +     * respecting situation on board?
    3.35 +     * 
    3.36 +     * @param p the player to try to move
    3.37 +     * @param column desired x-coordinate. Between 0-8. See {@link Player#getColumn()}.
    3.38 +     * @param row desired y-coordinate. Between 0-8. See {@link Player#getRow()}.
    3.39 +     * @return the move that can be {@link #apply applied} to the position and
    3.40 +     *   that would move the player p into desired position or null, if such 
    3.41 +     *   move does not exist
    3.42 +     * @since 1.4
    3.43 +     */
    3.44 +    public Move findMove(Player p, int column, int row) {
    3.45 +        int idx = getPlayers().indexOf(p);
    3.46 +        if (idx < 0) {
    3.47 +            return null;
    3.48 +        }
    3.49 +        for (Move m : Move.allMovements()) {
    3.50 +            Board b;
    3.51 +            try {
    3.52 +                b = apply(m, p);
    3.53 +            } catch (IllegalPositionException ex) {
    3.54 +                continue;
    3.55 +            }
    3.56 +            if (
    3.57 +                b.getPlayers().get(idx).getColumn() == column &&
    3.58 +                b.getPlayers().get(idx).getRow() == row
    3.59 +            ) {
    3.60 +                return m;
    3.61 +            }
    3.62 +        }
    3.63 +        return null;
    3.64 +    }
    3.65  
    3.66      /** Can the move be applied to current board position?
    3.67       * 
     4.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Move.java	Sun Sep 05 07:07:35 2010 +0200
     4.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Move.java	Sun Sep 05 11:04:26 2010 +0200
     4.3 @@ -27,7 +27,9 @@
     4.4  package cz.xelfi.quoridor;
     4.5  
     4.6  import cz.xelfi.quoridor.Player.Direction;
     4.7 +import java.util.ArrayList;
     4.8  import java.util.Arrays;
     4.9 +import java.util.List;
    4.10  
    4.11  /** Encapsulates one possible move that can be applied to existing {@link Board}
    4.12   * by calling its {@link Board#apply} method.
    4.13 @@ -221,4 +223,19 @@
    4.14      }
    4.15  
    4.16  
    4.17 +    static List<Move> allMovements() {
    4.18 +        List<Move> arr = new ArrayList<Move>();
    4.19 +        
    4.20 +        arr.add(Move.EAST);
    4.21 +        arr.add(Move.WEST);
    4.22 +        arr.add(Move.NORTH);
    4.23 +        arr.add(Move.SOUTH);
    4.24 +        
    4.25 +        for (Direction d1 : Player.Direction.values()) {
    4.26 +            for (Direction d2 : Player.Direction.values()) {
    4.27 +                arr.add(Move.jump(d1, d2));
    4.28 +            }
    4.29 +        }
    4.30 +        return arr;
    4.31 +    }
    4.32  }
     5.1 --- a/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java	Sun Sep 05 07:07:35 2010 +0200
     5.2 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java	Sun Sep 05 11:04:26 2010 +0200
     5.3 @@ -230,6 +230,50 @@
     5.4          }
     5.5          
     5.6      }
     5.7 +    public void testCanNorth() {
     5.8 +        Move m = board.findMove(board.getCurrentPlayer(), 4, 1);
     5.9 +        assertEquals("Go north", Move.NORTH, m);
    5.10 +    }
    5.11 +    public void testCanEast() {
    5.12 +        Move m = board.findMove(board.getCurrentPlayer(), 5, 0);
    5.13 +        assertEquals("Go east", Move.EAST, m);
    5.14 +    }
    5.15 +    public void testCanWest() {
    5.16 +        Move m = board.findMove(board.getCurrentPlayer(), 3, 0);
    5.17 +        assertEquals("Go west", Move.WEST, m);
    5.18 +    }
    5.19 +    public void testCannotWestAndNorth() {
    5.20 +        Move m = board.findMove(board.getCurrentPlayer(), 3, 1);
    5.21 +        assertNull("No way", m);
    5.22 +    }
    5.23 +    public void testCanJumpStraight () throws Exception {
    5.24 +        Board b = board;
    5.25 +        
    5.26 +        for (int i = 0; i < 3; i++) {
    5.27 +            b = move(b, 0, Player.Direction.NORTH);
    5.28 +            b = move(b, 1, Player.Direction.SOUTH);
    5.29 +        }
    5.30 +        b = apply(b, Move.NORTH);
    5.31 +        Move m = b.findMove(b.getPlayers().get(0), 4, 6);
    5.32 +        assertEquals("N+N", Move.jump(Direction.NORTH, Direction.NORTH), m);
    5.33 +    }
    5.34 +    public void testCanJumSptraightAndTurn () throws Exception {
    5.35 +        Board b = board;
    5.36 +        
    5.37 +        for (int i = 0; i < 3; i++) {
    5.38 +            b = move(b, 0, Player.Direction.NORTH);
    5.39 +            b = move(b, 1, Player.Direction.SOUTH);
    5.40 +        }
    5.41 +        b = apply(b, Move.fence('A', 1, Orientation.HORIZONTAL));
    5.42 +        b = apply(b, Move.SOUTH);
    5.43 +        b = apply(b, Move.fence('D', 5, Orientation.HORIZONTAL));
    5.44 +        b = apply(b, Move.fence('A', 8, Orientation.HORIZONTAL));
    5.45 +        
    5.46 +        Move m = b.findMove(b.getCurrentPlayer(), 4, 5);
    5.47 +        assertNull("No N+N", m);
    5.48 +        m = b.findMove(b.getCurrentPlayer(), 5, 4);
    5.49 +        assertEquals("N+E is OK", Move.jump(Direction.NORTH, Direction.EAST), m);
    5.50 +    }
    5.51  
    5.52      public void testCrossFences () throws Exception {
    5.53          Board b1 = board.fence (board.getPlayers ().get(0), 'A', 1, Fence.Orientation.HORIZONTAL);
    5.54 @@ -611,11 +655,12 @@
    5.55  /* and now try WS */
    5.56          b = move(b, 1, Direction.WEST, Direction.SOUTH);
    5.57          assertNotNull("Board is OK", b);
    5.58 -        /*
    5.59 +    }
    5.60 +
    5.61 +    static String toPicture(Board b) throws IOException {
    5.62          StringWriter sw = new StringWriter();
    5.63          b.write(sw);
    5.64 -        fail(sw.toString());
    5.65 -         */
    5.66 +        return sw.toString();
    5.67      }
    5.68  
    5.69      static Board picture2board(String text) throws IOException, IllegalPositionException {
     6.1 --- a/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java	Sun Sep 05 07:07:35 2010 +0200
     6.2 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java	Sun Sep 05 11:04:26 2010 +0200
     6.3 @@ -37,12 +37,10 @@
     6.4  import java.awt.Font;
     6.5  import java.awt.Graphics;
     6.6  import java.awt.Graphics2D;
     6.7 -import java.awt.GridLayout;
     6.8  import java.awt.Rectangle;
     6.9  import java.awt.event.MouseEvent;
    6.10  import java.awt.event.MouseMotionListener;
    6.11  import java.awt.image.BufferedImage;
    6.12 -import javax.swing.JComponent;
    6.13  import javax.swing.JFrame;
    6.14  import javax.swing.JPanel;
    6.15  
    6.16 @@ -128,7 +126,7 @@
    6.17              int row = 8 - p.getRow();
    6.18              final boolean isCurrent = p == board.getCurrentPlayer();
    6.19              final Color currentColor = colors[cnt];
    6.20 -            drawPlayer(g, column, row, currentColor, isCurrent);
    6.21 +            drawPlayer(g, column, row, currentColor, isCurrent, false);
    6.22              cnt++;
    6.23          }
    6.24  
    6.25 @@ -145,7 +143,7 @@
    6.26          }
    6.27      }
    6.28  
    6.29 -    private void drawPlayer(Graphics2D g, int column, int row, final Color currentColor, final boolean isCurrent) {
    6.30 +    private void drawPlayer(Graphics2D g, int column, int row, final Color currentColor, final boolean isCurrent, boolean allowedMove) {
    6.31          int fifth = fieldSize / 10;
    6.32          int diametr = fieldSize - fifth * 4;
    6.33          final Rectangle r = new Rectangle(
    6.34 @@ -155,8 +153,13 @@
    6.35              diametr
    6.36          );
    6.37          if (currentColor == null) {
    6.38 -            g.setColor(Color.BLACK);
    6.39 -            g.drawOval(r.x, r.y, r.width, r.height);
    6.40 +            if (allowedMove) {
    6.41 +                g.setColor(Color.BLACK);
    6.42 +                g.drawOval(r.x, r.y, r.width, r.height);
    6.43 +            } else {
    6.44 +                g.drawLine(r.x, r.y, r.x + r.width, r.y + r.height);
    6.45 +                g.drawLine(r.x, r.y + r.height, r.x + r.width, r.y);
    6.46 +            }
    6.47          } else {
    6.48              g.setColor(currentColor);
    6.49              g.fillOval(r.x, r.y, r.width, r.height);
    6.50 @@ -166,7 +169,7 @@
    6.51              }
    6.52          }
    6.53      }
    6.54 -
    6.55 +    
    6.56      private void drawFence(Orientation orient, int column, int row, Graphics2D g, boolean fill) throws IllegalStateException {
    6.57          int fifth = fieldSize / 10;
    6.58          int w, h;
    6.59 @@ -217,7 +220,12 @@
    6.60          if (outOfX && outOfY) {
    6.61              x = (e.getX() - xdelta) / fieldSize;
    6.62              y = (e.getY() - ydelta) / fieldSize;
    6.63 -            drawPlayer(d2, x, y, null, false);
    6.64 +            Move m = board.findMove(board.getCurrentPlayer(), x, 8 - y);
    6.65 +            if (m == null) {
    6.66 +                drawPlayer(d2, x, y, null, false, false);
    6.67 +            } else {
    6.68 +                drawPlayer(d2, x, y, null, false, true);
    6.69 +            }
    6.70              getGraphics().drawImage(img, 0, 0, null);
    6.71              return;
    6.72          }