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.
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 }