# HG changeset patch # User Jaroslav Tulach # Date 1283677466 -7200 # Node ID ee02205edf13b61953252c9107bb7ef200f634c2 # Parent 2769784e86dae1cdc53fe3fc8f24262a12831b9c 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. diff -r 2769784e86da -r ee02205edf13 pom.xml --- a/pom.xml Sun Sep 05 07:07:35 2010 +0200 +++ b/pom.xml Sun Sep 05 11:04:26 2010 +0200 @@ -29,7 +29,7 @@ http://apidesign.org - 1.3 + 1.4 1.17 1.0-SNAPSHOT 1.60 diff -r 2769784e86da -r ee02205edf13 quoridor/pom.xml --- a/quoridor/pom.xml Sun Sep 05 07:07:35 2010 +0200 +++ b/quoridor/pom.xml Sun Sep 05 11:04:26 2010 +0200 @@ -35,6 +35,12 @@ maven-bundle-plugin 2.0.1 true + + + cz.xelfi.quoridor + cz.xelfi.quoridor.* + + org.apache.maven.plugins diff -r 2769784e86da -r ee02205edf13 quoridor/src/main/java/cz/xelfi/quoridor/Board.java --- a/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Sun Sep 05 07:07:35 2010 +0200 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Sun Sep 05 11:04:26 2010 +0200 @@ -41,6 +41,8 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -207,17 +209,53 @@ if (getWinner() != null) { throw new IllegalPositionException("Game finished!"); // NOI18N } + return apply(move, getCurrentPlayer()); + } + private Board apply(Move move, Player p) throws IllegalPositionException { if (move.direction != null) { - return move(getCurrentPlayer(), move.direction); + return move(p, move.direction); } else { if (move.fence != null) { - return fence(getCurrentPlayer(), move.fence); + return fence(p, move.fence); } else { return new Board(this, turn + 1); } } } + + /** Is there a move that would take the player onto given position while + * respecting situation on board? + * + * @param p the player to try to move + * @param column desired x-coordinate. Between 0-8. See {@link Player#getColumn()}. + * @param row desired y-coordinate. Between 0-8. See {@link Player#getRow()}. + * @return the move that can be {@link #apply applied} to the position and + * that would move the player p into desired position or null, if such + * move does not exist + * @since 1.4 + */ + public Move findMove(Player p, int column, int row) { + int idx = getPlayers().indexOf(p); + if (idx < 0) { + return null; + } + for (Move m : Move.allMovements()) { + Board b; + try { + b = apply(m, p); + } catch (IllegalPositionException ex) { + continue; + } + if ( + b.getPlayers().get(idx).getColumn() == column && + b.getPlayers().get(idx).getRow() == row + ) { + return m; + } + } + return null; + } /** Can the move be applied to current board position? * diff -r 2769784e86da -r ee02205edf13 quoridor/src/main/java/cz/xelfi/quoridor/Move.java --- a/quoridor/src/main/java/cz/xelfi/quoridor/Move.java Sun Sep 05 07:07:35 2010 +0200 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Move.java Sun Sep 05 11:04:26 2010 +0200 @@ -27,7 +27,9 @@ package cz.xelfi.quoridor; import cz.xelfi.quoridor.Player.Direction; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; /** Encapsulates one possible move that can be applied to existing {@link Board} * by calling its {@link Board#apply} method. @@ -221,4 +223,19 @@ } + static List allMovements() { + List arr = new ArrayList(); + + arr.add(Move.EAST); + arr.add(Move.WEST); + arr.add(Move.NORTH); + arr.add(Move.SOUTH); + + for (Direction d1 : Player.Direction.values()) { + for (Direction d2 : Player.Direction.values()) { + arr.add(Move.jump(d1, d2)); + } + } + return arr; + } } diff -r 2769784e86da -r ee02205edf13 quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java --- a/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Sun Sep 05 07:07:35 2010 +0200 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Sun Sep 05 11:04:26 2010 +0200 @@ -230,6 +230,50 @@ } } + public void testCanNorth() { + Move m = board.findMove(board.getCurrentPlayer(), 4, 1); + assertEquals("Go north", Move.NORTH, m); + } + public void testCanEast() { + Move m = board.findMove(board.getCurrentPlayer(), 5, 0); + assertEquals("Go east", Move.EAST, m); + } + public void testCanWest() { + Move m = board.findMove(board.getCurrentPlayer(), 3, 0); + assertEquals("Go west", Move.WEST, m); + } + public void testCannotWestAndNorth() { + Move m = board.findMove(board.getCurrentPlayer(), 3, 1); + assertNull("No way", m); + } + public void testCanJumpStraight () throws Exception { + Board b = board; + + for (int i = 0; i < 3; i++) { + b = move(b, 0, Player.Direction.NORTH); + b = move(b, 1, Player.Direction.SOUTH); + } + b = apply(b, Move.NORTH); + Move m = b.findMove(b.getPlayers().get(0), 4, 6); + assertEquals("N+N", Move.jump(Direction.NORTH, Direction.NORTH), m); + } + public void testCanJumSptraightAndTurn () throws Exception { + Board b = board; + + for (int i = 0; i < 3; i++) { + b = move(b, 0, Player.Direction.NORTH); + b = move(b, 1, Player.Direction.SOUTH); + } + b = apply(b, Move.fence('A', 1, Orientation.HORIZONTAL)); + b = apply(b, Move.SOUTH); + b = apply(b, Move.fence('D', 5, Orientation.HORIZONTAL)); + b = apply(b, Move.fence('A', 8, Orientation.HORIZONTAL)); + + Move m = b.findMove(b.getCurrentPlayer(), 4, 5); + assertNull("No N+N", m); + m = b.findMove(b.getCurrentPlayer(), 5, 4); + assertEquals("N+E is OK", Move.jump(Direction.NORTH, Direction.EAST), m); + } public void testCrossFences () throws Exception { Board b1 = board.fence (board.getPlayers ().get(0), 'A', 1, Fence.Orientation.HORIZONTAL); @@ -611,11 +655,12 @@ /* and now try WS */ b = move(b, 1, Direction.WEST, Direction.SOUTH); assertNotNull("Board is OK", b); - /* + } + + static String toPicture(Board b) throws IOException { StringWriter sw = new StringWriter(); b.write(sw); - fail(sw.toString()); - */ + return sw.toString(); } static Board picture2board(String text) throws IOException, IllegalPositionException { diff -r 2769784e86da -r ee02205edf13 visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java --- a/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java Sun Sep 05 07:07:35 2010 +0200 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java Sun Sep 05 11:04:26 2010 +0200 @@ -37,12 +37,10 @@ import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.GridLayout; import java.awt.Rectangle; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; -import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JPanel; @@ -128,7 +126,7 @@ int row = 8 - p.getRow(); final boolean isCurrent = p == board.getCurrentPlayer(); final Color currentColor = colors[cnt]; - drawPlayer(g, column, row, currentColor, isCurrent); + drawPlayer(g, column, row, currentColor, isCurrent, false); cnt++; } @@ -145,7 +143,7 @@ } } - private void drawPlayer(Graphics2D g, int column, int row, final Color currentColor, final boolean isCurrent) { + private void drawPlayer(Graphics2D g, int column, int row, final Color currentColor, final boolean isCurrent, boolean allowedMove) { int fifth = fieldSize / 10; int diametr = fieldSize - fifth * 4; final Rectangle r = new Rectangle( @@ -155,8 +153,13 @@ diametr ); if (currentColor == null) { - g.setColor(Color.BLACK); - g.drawOval(r.x, r.y, r.width, r.height); + if (allowedMove) { + g.setColor(Color.BLACK); + g.drawOval(r.x, r.y, r.width, r.height); + } else { + g.drawLine(r.x, r.y, r.x + r.width, r.y + r.height); + g.drawLine(r.x, r.y + r.height, r.x + r.width, r.y); + } } else { g.setColor(currentColor); g.fillOval(r.x, r.y, r.width, r.height); @@ -166,7 +169,7 @@ } } } - + private void drawFence(Orientation orient, int column, int row, Graphics2D g, boolean fill) throws IllegalStateException { int fifth = fieldSize / 10; int w, h; @@ -217,7 +220,12 @@ if (outOfX && outOfY) { x = (e.getX() - xdelta) / fieldSize; y = (e.getY() - ydelta) / fieldSize; - drawPlayer(d2, x, y, null, false); + Move m = board.findMove(board.getCurrentPlayer(), x, 8 - y); + if (m == null) { + drawPlayer(d2, x, y, null, false, false); + } else { + drawPlayer(d2, x, y, null, false, true); + } getGraphics().drawImage(img, 0, 0, null); return; }