1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/quoridor/pom.xml Sun May 10 20:15:24 2009 +0200
1.3 @@ -0,0 +1,72 @@
1.4 +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1.5 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
1.6 + <modelVersion>4.0.0</modelVersion>
1.7 + <groupId>org.apidesign</groupId>
1.8 + <artifactId>quoridor</artifactId>
1.9 + <packaging>jar</packaging>
1.10 + <version>7.22.0</version>
1.11 + <url>http://quoridor.xelfi.cz</url>
1.12 + <!--
1.13 + <parent>
1.14 + <groupId>xelfi.cz</groupId>
1.15 + <artifactId>quoridor</artifactId>
1.16 + <relativePath>..</relativePath>
1.17 + <version>2.0</version>
1.18 + </parent>
1.19 + <ciManagement>
1.20 + <system>hudson</system>
1.21 + <url>http://hudson.apidesign.org/hudson/job/lookup</url>
1.22 + </ciManagement>
1.23 + <issueManagement>
1.24 + <system>issuezilla</system>
1.25 + <url>http://platform.netbeans.org/issues/</url>
1.26 + </issueManagement>
1.27 + <mailingLists>
1.28 + <mailingList>
1.29 + <name>Using the NetBeans Platform</name>
1.30 + <archive>http://openide.netbeans.org/servlets/SummarizeList?listName=dev</archive>
1.31 + <post>dev@openide.netbeans.org</post>
1.32 + </mailingList>
1.33 + </mailingLists>
1.34 + -->
1.35 + <build>
1.36 + <plugins>
1.37 + <plugin>
1.38 + <groupId>org.apache.maven.plugins</groupId>
1.39 + <artifactId>maven-compiler-plugin</artifactId>
1.40 + <version>2.0.2</version>
1.41 + <configuration>
1.42 + <source>1.5</source>
1.43 + <target>1.5</target>
1.44 + </configuration>
1.45 + </plugin>
1.46 + <plugin>
1.47 + <groupId>org.apache.maven.plugins</groupId>
1.48 + <artifactId>maven-javadoc-plugin</artifactId>
1.49 + <version>2.5</version>
1.50 + <!--
1.51 + <configuration>
1.52 + <excludePackageNames>org.netbeans.modules.openide.util</excludePackageNames>
1.53 + <overview>${basedir}/src/main/java/org/openide/util/lookup/doc-files/index.html</overview>
1.54 + </configuration>
1.55 + -->
1.56 + </plugin>
1.57 + </plugins>
1.58 + </build>
1.59 + <dependencies>
1.60 + <dependency>
1.61 + <groupId>org.netbeans.api</groupId>
1.62 + <artifactId>org-netbeans-modules-nbjunit</artifactId>
1.63 + <version>RELEASE65</version>
1.64 + <scope>test</scope>
1.65 + </dependency>
1.66 + <dependency>
1.67 + <groupId>org.netbeans.modules</groupId>
1.68 + <artifactId>org-netbeans-insane</artifactId>
1.69 + <version>RELEASE65</version>
1.70 + <scope>test</scope>
1.71 + </dependency>
1.72 + </dependencies>
1.73 + <name>Quoridor Library</name>
1.74 + <description>Quoridor library provides API to play the Quoridor game.</description>
1.75 +</project>
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Sun May 10 20:15:24 2009 +0200
2.3 @@ -0,0 +1,608 @@
2.4 +/*
2.5 + */
2.6 +
2.7 +package cz.xelfi.quoridor;
2.8 +
2.9 +/**
2.10 + * This is a class that represents a snapshot of the game position,
2.11 + * with all the placed and not-yet placed fences and player positions.
2.12 + * It it can print itself to stream following the format defined at
2.13 + * http://www.gamerz.net/pbmserv/quoridor.html
2.14 + * and shall be able to read that format back. There class is immutable
2.15 + * but it contains "move operations" that produce new Board position.
2.16 + *
2.17 + * @author Jaroslav Tulach
2.18 + */
2.19 +public final class Board {
2.20 + /** players */
2.21 + private final java.util.List<Player> players;
2.22 + /** fences placed on board */
2.23 + private final java.util.Set<Fence> fences;
2.24 + /** occurpied bits (coordinates encoded by toIndex methods)
2.25 + [N]
2.26 +
2.27 + +-----------------------------------+
2.28 + 6 | |
2.29 + 5 | + + + + + + + + |
2.30 + 4 | |
2.31 + 3 | + + + + + + + + |
2.32 + 2 | |
2.33 + 1 | + + + + + + + + |
2.34 + 0 | |
2.35 + 9 | + + + + + + + + |
2.36 +[W] 8 | | [E]
2.37 + 7 | + + + + + + + + |
2.38 + 6 | |
2.39 + 5 | + + + + + + + + |
2.40 + 4 | |
2.41 + 3 | + + + + + + + + |
2.42 + 2 | |
2.43 + 1 | + + + + + + + + |
2.44 + 0 | |
2.45 + +-----------------------------------+
2.46 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6
2.47 + [S]
2.48 +
2.49 + * even indexes == position of the pawns
2.50 + * odd indexes == centers of fences
2.51 + * even x odd == side of a fence
2.52 + * odd x even == side of a fence
2.53 + */
2.54 + private final java.util.BitSet occupied;
2.55 +
2.56 + /**
2.57 + * Creates a new instance of Board
2.58 + */
2.59 + private Board (int x1, int y1, int f1, int x2, int y2, int f2) {
2.60 + this.players = java.util.Collections.unmodifiableList (java.util.Arrays.asList (new Player[] {
2.61 + new Player (x1, y1, f1, Player.Direction.NORTH),
2.62 + new Player (x2, y2, f2, Player.Direction.SOUTH),
2.63 + }));
2.64 + this.fences = java.util.Collections.emptySet ();
2.65 + try {
2.66 + this.occupied = computeOccupied (players, fences);
2.67 + } catch (IllegalPositionException ex) {
2.68 + throw new IllegalStateException (ex.getMessage ());
2.69 + }
2.70 + }
2.71 +
2.72 + /** Copy constructor that provides players and fences.
2.73 + */
2.74 + private Board (java.util.List<Player> players, java.util.Set<Fence> fences)
2.75 + throws IllegalPositionException {
2.76 + this.players = java.util.Collections.unmodifiableList (players);
2.77 + this.fences = java.util.Collections.unmodifiableSet (fences);
2.78 + this.occupied = computeOccupied (players, fences);
2.79 +
2.80 + for (Player p : players) {
2.81 + if (!accessibleFinalLine (p, p.endDirection, occupied, new java.util.BitSet ())) {
2.82 + throw new IllegalPositionException ("Player " + p + " cannot reach " + p.endDirection + " side"); // NOI18N
2.83 + }
2.84 + }
2.85 + }
2.86 +
2.87 + /** Creates initial empty board with default positions of
2.88 + * players.
2.89 + */
2.90 + public static Board createEmptyBoard () {
2.91 + return new Board (8, 0, 10, 8, 16, 10);
2.92 + }
2.93 +
2.94 + /** Returns players in the game.
2.95 + * @return player object
2.96 + */
2.97 + public java.util.List<Player> getPlayers () {
2.98 + return players;
2.99 + }
2.100 +
2.101 + /** The fences currently on board.
2.102 + *
2.103 + * @return immutable set of Fences
2.104 + */
2.105 + public java.util.Set<Fence> getFences () {
2.106 + return fences;
2.107 + }
2.108 +
2.109 + //
2.110 + // Moves
2.111 + //
2.112 +
2.113 +
2.114 + /** Moves the player in given direction. The direction usually
2.115 + * is one of Player.Direction constants, but in case the move
2.116 + * is a jump over another players pawn it can be followed by
2.117 + * another (usually, if there is no fence the same) direction.
2.118 + *
2.119 + * @param player the player to move
2.120 + * @param where one or two directions saying where
2.121 + * @return the new board
2.122 + * @exception IllegalPositionException if the move is not possible
2.123 + */
2.124 + public Board move (Player player, Player.Direction... where) throws IllegalPositionException {
2.125 + if (where.length != 1 && where.length != 2) {
2.126 + throw new IllegalPositionException ("Move over one or two Directions"); // NOI18N
2.127 + }
2.128 +
2.129 + int index = players.indexOf (player);
2.130 + Player[] arr = players.toArray (new Player[0]);
2.131 +
2.132 + Player oneStep = newPosition (player, where[0]);
2.133 +
2.134 + if (where.length == 1) {
2.135 + arr[index] = oneStep;
2.136 + return new Board (java.util.Arrays.asList (arr), fences);
2.137 + }
2.138 +
2.139 + // straight jump over
2.140 + for (Player p : players) {
2.141 + if (p.getX () == oneStep.getX () && p.getY() == oneStep.getY ()) {
2.142 + // ok, we are jumping over this one
2.143 + GO_ON: if (where[0] != where[1]) {
2.144 + // first of all ensure that we cannot go straight
2.145 + try {
2.146 + newPosition (oneStep, where[0]);
2.147 + } catch (IllegalPositionException ex) {
2.148 + // ok
2.149 + break GO_ON;
2.150 + }
2.151 + throw new IllegalPositionException ("You have to jump straight if there is no wall"); // NOI18N
2.152 + }
2.153 + arr[index] = newPosition (oneStep, where[1]);
2.154 + return new Board (java.util.Arrays.asList (arr), fences);
2.155 + }
2.156 + }
2.157 + throw new IllegalPositionException ("Cannot use multi direction when there is not oponent pawn"); // NOI18N
2.158 + }
2.159 +
2.160 + /** Places a fence into given position with specified orientation.
2.161 + * The faces postions are numbered 1-8 and A-H according to following
2.162 + * graph: <pre>
2.163 + H G F E D C B A
2.164 + | | | | | | | |
2.165 + +-----------------------------------+
2.166 + | |
2.167 + 1--| + + + + + + + + |--1
2.168 + | |
2.169 + 2--| + + + + + + + + |--2
2.170 + | |
2.171 + 3--| + + + + + + + + |--3
2.172 + | |
2.173 + 4--| + + + + + + + + |--4
2.174 +[E] | | [W]
2.175 + 5--| + + + + + + + + |--5
2.176 + | |
2.177 + 6--| + + + + + + + + |--6
2.178 + | |
2.179 + 7--| + + + + + + + + |--7
2.180 + | |
2.181 + 8--| + + + + + + + + |--8
2.182 + | |
2.183 + +-----------------------------------+
2.184 + | | | | | | | |
2.185 + H G F E D C B A
2.186 + * </pre>
2.187 + *
2.188 + *
2.189 + * @param player the player that wishes to place the position
2.190 + * @param x x-coordinate of the middle of the fence from 'A' to 'B'
2.191 + * @param y y-coordinate of the middle of the fence
2.192 + * @param orientation place the fence horizontally or vertically
2.193 + * @return the new board
2.194 + * @exception IllegalPositionException if the move is not possible
2.195 + */
2.196 + public Board fence (Player player, char x, int y, Fence.Orientation orientation) throws IllegalPositionException {
2.197 + if (player.getFences () == 0) {
2.198 + throw new IllegalPositionException ("Not enough fences: " + player); // NOI18N
2.199 + }
2.200 +
2.201 + if (x < 'A' || 'H' < x) {
2.202 + throw new IllegalPositionException ("x coordinate has to be from A to H"); // NOI18N
2.203 + }
2.204 +
2.205 + int index = players.indexOf (player);
2.206 + Player[] arr = players.toArray (new Player[0]);
2.207 + arr[index] = new Player (arr[index].getX (), arr[index].getY (), arr[index].getFences () - 1, arr[index].endDirection);
2.208 +
2.209 + java.util.HashSet<Fence> fen = new java.util.HashSet<Fence> (this.fences);
2.210 + fen.add (new Fence ((x - 'A') * 2 + 1, y * 2 - 1, orientation));
2.211 +
2.212 + return new Board (java.util.Arrays.asList (arr), fen);
2.213 + }
2.214 +
2.215 + /** Writes the board to the provided writer.
2.216 + *
2.217 + *
2.218 + H G F E D C B A
2.219 + | | | | | | | |
2.220 + +-----------------------------------+
2.221 + | |
2.222 + 1--| + + + + + + + + |--1 playerA (O)
2.223 + | | | Fences - 5
2.224 + 2--| + | + +-------+-------+ |--2 ===========
2.225 + | | | | | | | | |
2.226 + 3--|-------+-------|-------+-------+ |--3
2.227 + | | |
2.228 + 4--| + + + + + + + + |--4
2.229 +[E] | | | [W]
2.230 + 5--| + + + | + + +-------|--5
2.231 + | | y |
2.232 + 6--| + + + +-------+ + + |--6 PlayerB (X)
2.233 + | a O a | Fences - 3
2.234 + 7--| + + + + + + + + |--7 ===========
2.235 + | b X | | | | |
2.236 + 8--| + + + + + | + + |--8
2.237 + | z | |
2.238 + +-----------------------------------+
2.239 + | | | | | | | |
2.240 + H G F E D C B A *
2.241 + * @param w writer to write the board to
2.242 + * @exception IOException if communiction with writer fails
2.243 + */
2.244 + public void write (java.io.Writer w) throws java.io.IOException {
2.245 + }
2.246 +
2.247 + /** This will print the board with provided spacing.
2.248 + * This is example of 3:1 spacing:
2.249 + * <pre>
2.250 + * +---+
2.251 + * |sss|
2.252 + * +---+
2.253 + * </pre>
2.254 + * and this 4:2 spacing:
2.255 + * <pre>
2.256 + * +----+
2.257 + * |ssss|
2.258 + * |ssss|
2.259 + * +----+
2.260 + * </pre>
2.261 + */
2.262 + private void write (StringBuffer sb, int spaceX, int spaceY) {
2.263 +
2.264 + // TODO rethink
2.265 + int cellSizeX = 1 + spaceX;
2.266 + int cellSizeY = 1 + spaceY;
2.267 +
2.268 + StringBuffer[] data = new StringBuffer[1 + cellSizeX * 9];
2.269 + for (int i = 0; i < data.length; i++) {
2.270 + data[i] = new StringBuffer (34);
2.271 +
2.272 + for (int grid = 1; grid < 34; grid += 4) {
2.273 + data[i].setCharAt (grid, '+');
2.274 + }
2.275 + }
2.276 +
2.277 + for (Player p : players) {
2.278 + data[p.getY()].setCharAt(p.getY() * 2, 'P');
2.279 + }
2.280 +
2.281 + for (Fence f : fences) {
2.282 + switch (f.getOrientation()) {
2.283 + case HORIZONTAL:
2.284 + for (int i = -1; i <= 1; i++) {
2.285 + data[f.getY()].setCharAt (f.getX () + i, '-');
2.286 + }
2.287 + break;
2.288 + case VERTICAL:
2.289 + for (int i = -1; i <= 1; i++) {
2.290 + data[f.getY() + i].setCharAt (f.getX (), '|');
2.291 + }
2.292 + break;
2.293 + default:
2.294 + throw new IllegalStateException ("Unkown orientation: " + f.getOrientation ()); // NOI18N
2.295 + }
2.296 + }
2.297 +
2.298 + StringBuffer result = new StringBuffer (20 * 20);
2.299 + /*
2.300 + for (int i = 0; i < )
2.301 + */
2.302 + }
2.303 +
2.304 + //
2.305 + // Standard Methods
2.306 + //
2.307 +
2.308 +
2.309 + public int hashCode () {
2.310 + return occupied.hashCode ();
2.311 + }
2.312 +
2.313 + public boolean equals (Object o) {
2.314 + if (o instanceof Board) {
2.315 + Board b = (Board)o;
2.316 + return occupied.equals (b.occupied) && players.equals (b.players);
2.317 + }
2.318 + return false;
2.319 + }
2.320 +
2.321 + //
2.322 + // Validation methods
2.323 + //
2.324 +
2.325 + /** Computes new position of a player and checks whether there is no
2.326 + * fence between the old and new.
2.327 + */
2.328 + private Player newPosition (Player old, Player.Direction direction) throws IllegalPositionException {
2.329 + return newPosition (old, direction, occupied);
2.330 + }
2.331 +
2.332 +
2.333 + private static Player newPosition (Player old, Player.Direction direction, java.util.BitSet occupied) throws IllegalPositionException {
2.334 + int nx = old.x;
2.335 + int ny = old.y;
2.336 + int fx = old.x;
2.337 + int fy = old.y;
2.338 +
2.339 + switch (direction) {
2.340 + case NORTH:
2.341 + ny = old.y + 2;
2.342 + fy = old.y + 1;
2.343 + break;
2.344 + case SOUTH:
2.345 + ny = old.y - 2;
2.346 + fy = old.y - 1;
2.347 + break;
2.348 + case EAST:
2.349 + nx = old.x + 2;
2.350 + fx = old.x + 1;
2.351 + break;
2.352 + case WEST:
2.353 + nx = old.x - 2;
2.354 + fx = old.x - 1;
2.355 + break;
2.356 + default: throw new IllegalStateException ("Unknown direction: " + direction); // NOI18N
2.357 + }
2.358 +
2.359 + if (nx < 0 || nx > 16) throw new IllegalPositionException ("Wrong player position: " + nx + ":" + ny); // NOI18N
2.360 + if (ny < 0 || ny > 16) throw new IllegalPositionException ("Wrong player position: " + nx + ":" + ny); // NOI18N
2.361 +
2.362 + int fenceIndex = toIndex (fx, fy);
2.363 + if (occupied.get (fenceIndex)) {
2.364 + throw new IllegalPositionException ("You cannot go over fences"); // NOI18N
2.365 + }
2.366 +
2.367 + return new Player (nx, ny, old.getFences (), old.endDirection);
2.368 + }
2.369 +
2.370 + /** @param position the current position of the player
2.371 + * @param endDir the side the player wants to reach
2.372 + * @param fences bits set to 1 when fences are placed
2.373 + * @param reached bits on squares that were already reached (modified during run)
2.374 + * @return true if the end line can be reached
2.375 + */
2.376 + private static boolean accessibleFinalLine (Player position, Player.Direction endDir, java.util.BitSet fences, java.util.BitSet reached) {
2.377 + int index = toIndex (position);
2.378 + if (reached.get (index)) {
2.379 + // already visited without success
2.380 + return false;
2.381 + }
2.382 +
2.383 + switch (endDir) {
2.384 + case NORTH:
2.385 + if (position.getY () == 8) return true;
2.386 + break;
2.387 + case SOUTH:
2.388 + if (position.getY () == 0) return true;
2.389 + break;
2.390 + case EAST:
2.391 + if (position.getX () == 0) return true;
2.392 + break;
2.393 + case WEST:
2.394 + if (position.getX () == 8) return true;
2.395 + break;
2.396 + default:
2.397 + throw new IllegalStateException ("Wrong direction: " + endDir); // NOI18N
2.398 + }
2.399 +
2.400 + reached.set (index);
2.401 +
2.402 + for (Player.Direction oneDirection : Player.Direction.values ()) {
2.403 + try {
2.404 + if (accessibleFinalLine (newPosition (position, oneDirection, fences), endDir, fences, reached)) {
2.405 + return true;
2.406 + }
2.407 + } catch (IllegalPositionException ex) {
2.408 + // ok, try once more
2.409 + }
2.410 + }
2.411 +
2.412 + return false;
2.413 + }
2.414 +
2.415 + /** Computes mask of the occupried bits.
2.416 + */
2.417 + private static java.util.BitSet computeOccupied (
2.418 + java.util.Collection<Player> players, java.util.Collection<Fence> fences
2.419 + ) throws IllegalPositionException {
2.420 + java.util.BitSet occupied = new java.util.BitSet (17 * 17);
2.421 +
2.422 + for (Player p : players) {
2.423 + if (p.getX () % 2 == 1) throw new IllegalPositionException ("Wrong player position: " + p); // NOI18N
2.424 + if (p.getY () % 2 == 1) throw new IllegalPositionException ("Wrong player position: " + p); // NOI18N
2.425 +
2.426 + int index = toIndex (p);
2.427 + if (occupied.get (index)) {
2.428 + throw new IllegalPositionException ("There cannot be two players at " + p); // NOI18N
2.429 + }
2.430 + occupied.set (index);
2.431 + }
2.432 +
2.433 + for (Fence f : fences) {
2.434 +
2.435 + for (int i = -1; i <= 1; i++) {
2.436 + int index = toIndex (f, i);
2.437 + if (index < 0 || index > occupied.size ()) {
2.438 + throw new IllegalPositionException ("Wrong fence position: " + f); // NOI18N
2.439 + }
2.440 + if (occupied.get (index)) {
2.441 + throw new IllegalPositionException ("Fence collition: " + f); // NOI18N
2.442 + }
2.443 +
2.444 + occupied.set (index);
2.445 + }
2.446 +
2.447 + }
2.448 +
2.449 + return occupied;
2.450 + }
2.451 +
2.452 + /** Converts twodimensional coordinates of player to one dimensional index.
2.453 + */
2.454 + private static int toIndex (Player p) {
2.455 + return toIndex (p.getX (), p.getY ());
2.456 + }
2.457 +
2.458 + /** Converts twodimensional coordinates of fence to one dimensional index.
2.459 + * @param f the fence
2.460 + * @param whichPart (-1, 0, 1)
2.461 + */
2.462 + private static int toIndex (Fence f, int whichPart) {
2.463 + int x = f.getX ();
2.464 + int y = f.getY ();
2.465 +
2.466 + switch (f.getOrientation ()) {
2.467 + case HORIZONTAL: x += whichPart; break;
2.468 + case VERTICAL: y += whichPart; break;
2.469 + default: throw new IllegalStateException ("Wrong orientation: " + f.getOrientation ()); // NOI18N
2.470 + }
2.471 +
2.472 + return toIndex (x, y);
2.473 + }
2.474 +
2.475 + /** Diagonal conversion of two positive integers to one integer.
2.476 + * <pre>
2.477 + * y3 9
2.478 + * y2 5 8
2.479 + * y1 2 4 7
2.480 + * y0 0 1 3 6
2.481 + * x0 x1 x2 x3
2.482 + * </pre>
2.483 + */
2.484 + private static int toIndex (int x, int y) {
2.485 + int max = x + y;
2.486 + int baseOnY0 = max * (max + 1) / 2;
2.487 + return baseOnY0 + y;
2.488 + }
2.489 +
2.490 + /** Defines properties (mostly position) of a player.
2.491 + */
2.492 + public static final class Player extends Object {
2.493 + private final int x;
2.494 + private final int y;
2.495 + /** number of fences this player has */
2.496 + private final int f;
2.497 + /** the direction of players end line */
2.498 + private final Direction endDirection;
2.499 +
2.500 + Player (int x, int y, int f, Player.Direction endDir) {
2.501 + this.x = x;
2.502 + this.y = y;
2.503 + this.f = f;
2.504 + this.endDirection = endDir;
2.505 + }
2.506 +
2.507 +
2.508 + /** Returns the x-coordinate of the player.
2.509 + * @return number from 0 to 8
2.510 + */
2.511 + int getX () {
2.512 + return x;
2.513 + }
2.514 +
2.515 + /** Returns the y-coordinate of the player.
2.516 + * @return number from 0 to 8
2.517 + */
2.518 + int getY () {
2.519 + return y;
2.520 + }
2.521 +
2.522 + /** @return number of fences this player still has
2.523 + */
2.524 + int getFences () {
2.525 + return f;
2.526 + }
2.527 +
2.528 + public String toString () {
2.529 + return "Player[" + x + "," + y + "," + f + "," + endDirection + "]"; // NOI18N
2.530 + }
2.531 +
2.532 + public int hashCode () {
2.533 + return 8 * x + 2 * y + 4 * f + 7 + endDirection.hashCode ();
2.534 + }
2.535 +
2.536 + public boolean equals (Object o) {
2.537 + if (o instanceof Player) {
2.538 + Player p = (Player)o;
2.539 + return x == p.x && y == p.y && f == p.f && endDirection.equals (p.endDirection);
2.540 + }
2.541 + return false;
2.542 + }
2.543 +
2.544 + /** Possible directions of player's moves.
2.545 + */
2.546 + public enum Direction {
2.547 + NORTH, WEST, EAST, SOUTH
2.548 + }
2.549 + } // end of Player
2.550 +
2.551 + /** Defines a fence. Its position is defined as position of its
2.552 + * center (index from 0-8 in both directions) and its orientation
2.553 + * either horizontal or vertical.
2.554 + */
2.555 + public static final class Fence extends Object {
2.556 + private final int x, y;
2.557 + private final Orientation o;
2.558 +
2.559 + Fence (int x, int y, Orientation o) {
2.560 + this.x = x;
2.561 + this.y = y;
2.562 + this.o = o;
2.563 + }
2.564 +
2.565 + /** Midle coordinate of the fence.
2.566 + * @return 1-15
2.567 + */
2.568 + int getX () {
2.569 + return x;
2.570 + }
2.571 +
2.572 + /** Midle coordinate of the fence.
2.573 + * @return 1-15
2.574 + */
2.575 + int getY () {
2.576 + return y;
2.577 + }
2.578 +
2.579 + /** The orientation of the fence.
2.580 + */
2.581 + Orientation getOrientation () {
2.582 + return o;
2.583 + }
2.584 +
2.585 + public String toString () {
2.586 + return "Fence[" + x + "," + y + "," + o + "]"; // NOI18N
2.587 + }
2.588 +
2.589 + public int hashCode () {
2.590 + return 8 * x + 4 * y + 13 + o.hashCode ();
2.591 + }
2.592 +
2.593 + public boolean equals (Object o) {
2.594 + if (o instanceof Fence) {
2.595 + Fence f = (Fence)o;
2.596 +
2.597 + return x == f.x && y == f.y && getOrientation ().equals (f.getOrientation ());
2.598 + }
2.599 + return false;
2.600 + }
2.601 +
2.602 + /** The fences orientation. Either horizontal of vertical.
2.603 + */
2.604 + public static enum Orientation {
2.605 + HORIZONTAL, VERTICAL;
2.606 +
2.607 + private Orientation () {
2.608 + }
2.609 + }
2.610 + }
2.611 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/IllegalPositionException.java Sun May 10 20:15:24 2009 +0200
3.3 @@ -0,0 +1,17 @@
3.4 +/*
3.5 + */
3.6 +
3.7 +package cz.xelfi.quoridor;
3.8 +
3.9 +/** Thrown when an illegal position is reached.
3.10 + *
3.11 + * @author Jaroslav Tulach
3.12 + */
3.13 +public final class IllegalPositionException extends java.lang.Exception {
3.14 + /**
3.15 + * @param msg the detail message.
3.16 + */
3.17 + IllegalPositionException (String msg) {
3.18 + super (msg);
3.19 + }
3.20 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/View.java Sun May 10 20:15:24 2009 +0200
4.3 @@ -0,0 +1,244 @@
4.4 +/*
4.5 + */
4.6 +
4.7 +package cz.xelfi.quoridor;
4.8 +
4.9 +import java.awt.BorderLayout;
4.10 +import java.awt.Dimension;
4.11 +import java.awt.Graphics2D;
4.12 +import java.awt.Point;
4.13 +import java.awt.event.MouseEvent;
4.14 +import java.awt.event.MouseListener;
4.15 +import java.awt.event.MouseMotionListener;
4.16 +import java.awt.geom.Rectangle2D;
4.17 +import javax.swing.JComponent;
4.18 +import javax.swing.border.EmptyBorder;
4.19 +
4.20 +/**
4.21 + *
4.22 + * @author Jaroslav Tulach
4.23 + */
4.24 +public class View extends JComponent {
4.25 + /** fence size */
4.26 + private final static int SIZE_FENCE = 20;
4.27 + private final static int SIZE_FIELD = 50;
4.28 +
4.29 + private static final java.awt.Color[] PLAYER_COLORS = {
4.30 + java.awt.Color.WHITE,
4.31 + java.awt.Color.BLACK,
4.32 + java.awt.Color.RED,
4.33 + java.awt.Color.BLUE,
4.34 + };
4.35 +
4.36 + /** board to view */
4.37 + private Board board = Board.createEmptyBoard ();
4.38 + {
4.39 + try {
4.40 + board = board.fence (board.getPlayers ().get (0), 'A', 5, Board.Fence.Orientation.HORIZONTAL);
4.41 + board = board.fence (board.getPlayers ().get (0), 'A', 6, Board.Fence.Orientation.VERTICAL);
4.42 + board = board.fence (board.getPlayers ().get (0), 'C', 5, Board.Fence.Orientation.HORIZONTAL);
4.43 + } catch (IllegalPositionException ex) {
4.44 + ex.printStackTrace();
4.45 + }
4.46 + }
4.47 + /** number of player that can do the move */
4.48 + private int onMove;
4.49 + private Listener listener;
4.50 + /** non-null if we do drag and is the delta of the lefttop corner
4.51 + * from the position of the mouse */
4.52 + private Point dragDelta;
4.53 + /** draw circle */
4.54 + private Point move;
4.55 +
4.56 + /** Creates a new instance of View */
4.57 + public View () {
4.58 + int s = (SIZE_FIELD + SIZE_FENCE) * 9;
4.59 +
4.60 + setPreferredSize (new Dimension (s, s));
4.61 + setBackground (java.awt.Color.GRAY.darker ().darker ());
4.62 +
4.63 + listener = new Listener ();
4.64 + addMouseListener(listener);
4.65 + addMouseMotionListener(listener);
4.66 + }
4.67 +
4.68 + protected void paintComponent (java.awt.Graphics g) {
4.69 + Graphics2D g2 = (Graphics2D)g;
4.70 +
4.71 + g.setColor (getBackground ());
4.72 + g.fillRect (0, 0, getSize ().width, getSize ().height);
4.73 +
4.74 + // draw the empty boards
4.75 + g.setColor (java.awt.Color.GRAY);
4.76 + for (int i = 0; i < 9; i++) {
4.77 + for (int j = 0; j < 9; j++) {
4.78 + g.fillRect (
4.79 + i * (SIZE_FIELD + SIZE_FENCE) + SIZE_FENCE / 2,
4.80 + j * (SIZE_FIELD + SIZE_FENCE) + SIZE_FENCE / 2,
4.81 + SIZE_FIELD,
4.82 + SIZE_FIELD
4.83 + );
4.84 + } }
4.85 +
4.86 + // draw fences
4.87 + g.setColor (java.awt.Color.YELLOW.darker ());
4.88 + for (Board.Fence f : board.getFences ()) {
4.89 + Point b = findFence(f);
4.90 + switch (f.getOrientation ()) {
4.91 + case HORIZONTAL:
4.92 + g.fillRect (b.x - SIZE_FIELD + 1, b.y + 1, SIZE_FIELD * 2 + SIZE_FENCE - 2, SIZE_FENCE - 2);
4.93 + break;
4.94 + case VERTICAL:
4.95 + g.fillRect (b.x + 1, b.y - SIZE_FIELD + 1, SIZE_FENCE - 2, SIZE_FIELD * 2 + SIZE_FENCE - 2);
4.96 + break;
4.97 + }
4.98 + }
4.99 +
4.100 + int pindex = 0;
4.101 + for (Board.Player p : board.getPlayers ()) {
4.102 + Point place = findPlayer (p);
4.103 +
4.104 + g.setColor (PLAYER_COLORS[pindex++]);
4.105 + g.fillArc (place.x, place.y, SIZE_FIELD, SIZE_FIELD, 0, 360);
4.106 +
4.107 + }
4.108 + if (move != null) {
4.109 + g.setColor (PLAYER_COLORS[onMove]);
4.110 + g.drawArc(move.x, move.y, SIZE_FIELD, SIZE_FIELD, 0, 360);
4.111 + }
4.112 + }
4.113 +
4.114 + /** Tries to move a player to given coordinates.
4.115 + */
4.116 + final Board tryMove (int player, int newX, int newY) {
4.117 + Point p = findPlayer (board.getPlayers().get (player));
4.118 +
4.119 + int cmpX = compare (p.x, SIZE_FIELD, newX);
4.120 + int cmpY = compare (p.y, SIZE_FIELD, newY);
4.121 +
4.122 + if (cmpX == 0 && cmpY == 0) {
4.123 + return null;
4.124 + }
4.125 + try {
4.126 + if (cmpX == 0) {
4.127 + if (cmpY < 0 && cmpY > -3) {
4.128 + return board.move (board.getPlayers().get (player), Board.Player.Direction.SOUTH);
4.129 + }
4.130 + if (cmpY > 0 && cmpY < 3) {
4.131 + return board.move (board.getPlayers().get (player), Board.Player.Direction.NORTH);
4.132 + }
4.133 + return null;
4.134 + }
4.135 +
4.136 + if (cmpY == 0) {
4.137 + if (cmpX < 0 && cmpX > -3) {
4.138 + return board.move (board.getPlayers().get (player), Board.Player.Direction.WEST);
4.139 + }
4.140 + if (cmpX > 0 && cmpX < 3) {
4.141 + return board.move (board.getPlayers().get (player), Board.Player.Direction.EAST);
4.142 + }
4.143 + return null;
4.144 + }
4.145 + } catch (IllegalPositionException ex) {
4.146 + return null;
4.147 + }
4.148 +
4.149 + return null;
4.150 + }
4.151 +
4.152 + private static int compare (int from, int length, int where) {
4.153 + return (where - from) / length;
4.154 + }
4.155 +
4.156 + /** computes middle point of a fence.
4.157 + */
4.158 + final Point findFence (Board.Fence f) {
4.159 + int bx = (f.getX () / 2 + 1) * (SIZE_FIELD + SIZE_FENCE) - SIZE_FENCE;
4.160 + int by = (f.getY () / 2 + 1) * (SIZE_FIELD + SIZE_FENCE) - SIZE_FENCE;
4.161 +
4.162 + return new Point (bx + SIZE_FENCE / 2, by + SIZE_FENCE / 2);
4.163 + }
4.164 +
4.165 + /** For a player computes left-top point of its square.
4.166 + */
4.167 + final Point findPlayer (Board.Player p) {
4.168 + int px = (p.getX () / 2 + 0) * (SIZE_FIELD + SIZE_FENCE);
4.169 + int py = (p.getY () / 2 + 0) * (SIZE_FIELD + SIZE_FENCE);
4.170 +
4.171 + return new Point (px + SIZE_FENCE / 2, py + SIZE_FENCE / 2);
4.172 + }
4.173 +
4.174 + /** Finds if the click on the component is activates a player.
4.175 + * @return null if not
4.176 + */
4.177 + final Board.Player findPlayer (int x, int y) {
4.178 + for (Board.Player p : board.getPlayers ()) {
4.179 + Point z = findPlayer(p);
4.180 +
4.181 + if (
4.182 + z.x < x && x < z.x + SIZE_FIELD &&
4.183 + z.y < y && y < z.y + SIZE_FIELD
4.184 + ) {
4.185 + return p;
4.186 + }
4.187 + }
4.188 + return null;
4.189 + }
4.190 +
4.191 + private final class Listener implements MouseListener, MouseMotionListener {
4.192 + public void mouseClicked(java.awt.event.MouseEvent mouseEvent) {
4.193 + }
4.194 +
4.195 + public void mouseEntered(java.awt.event.MouseEvent mouseEvent) {
4.196 + }
4.197 +
4.198 + public void mouseExited(java.awt.event.MouseEvent mouseEvent) {
4.199 + }
4.200 +
4.201 + public void mousePressed(java.awt.event.MouseEvent mouseEvent) {
4.202 + Board.Player p = board.getPlayers ().get (onMove);
4.203 + Board.Player clicked = findPlayer (mouseEvent.getX (), mouseEvent.getY ());
4.204 +
4.205 + if (p.equals (clicked)) {
4.206 + // start drag
4.207 + Point delta = findPlayer (p);
4.208 + delta.x = mouseEvent.getX () - delta.x;
4.209 + delta.y = mouseEvent.getY () - delta.y;
4.210 + dragDelta = delta;
4.211 + repaint();
4.212 + }
4.213 + }
4.214 +
4.215 + public void mouseReleased(java.awt.event.MouseEvent mouseEvent) {
4.216 + Board newBoard = tryMove (onMove, mouseEvent.getX(), mouseEvent.getY());
4.217 + if (newBoard != null) {
4.218 + board = newBoard;
4.219 + onMove = (onMove + 1) % newBoard.getPlayers().size();
4.220 + }
4.221 + dragDelta = null;
4.222 + move = null;
4.223 + repaint();
4.224 + }
4.225 +
4.226 + public void mouseMoved(MouseEvent e) {
4.227 + }
4.228 +
4.229 + public void mouseDragged(MouseEvent e) {
4.230 + if (dragDelta != null) {
4.231 + move = new Point (e.getX () - dragDelta.x, e.getY () - dragDelta.y);
4.232 + repaint ();
4.233 + }
4.234 + }
4.235 +
4.236 + }
4.237 +
4.238 +
4.239 + public static void main (String[] args) {
4.240 + javax.swing.JFrame f = new javax.swing.JFrame ();
4.241 + View v = new View ();
4.242 + f.getContentPane ().add (BorderLayout.CENTER, v);
4.243 + f.setDefaultCloseOperation (f.EXIT_ON_CLOSE);
4.244 + f.pack ();
4.245 + f.setVisible (true);
4.246 + }
4.247 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/BoardTest.java Sun May 10 20:15:24 2009 +0200
5.3 @@ -0,0 +1,259 @@
5.4 +/*
5.5 + * BoardTest.java
5.6 + * JUnit based test
5.7 + *
5.8 + * Created on 19. b�ezen 2005, 20:34
5.9 + */
5.10 +
5.11 +package cz.xelfi.quoridor;
5.12 +
5.13 +import junit.framework.*;
5.14 +
5.15 +import cz.xelfi.quoridor.Board.*;
5.16 +
5.17 +/** Checks default setup of empty board.
5.18 + *
5.19 + * @author Jaroslav Tulach
5.20 + */
5.21 +public class BoardTest extends TestCase {
5.22 +
5.23 + private Board board;
5.24 +
5.25 + public BoardTest (String testName) {
5.26 + super (testName);
5.27 + }
5.28 +
5.29 + @Override
5.30 + protected void setUp () throws Exception {
5.31 + board = Board.createEmptyBoard ();
5.32 + }
5.33 +
5.34 + public void testTwoPlayers () {
5.35 + java.util.List<Player> list = board.getPlayers ();
5.36 + assertEquals ("Two", 2, list.size ());
5.37 + assertFalse ("Both are non-null", list.contains (null));
5.38 + try {
5.39 + list.add (null);
5.40 + fail ("Modifications are not allowed");
5.41 + } catch (UnsupportedOperationException ex) {
5.42 + // ok
5.43 + }
5.44 + try {
5.45 + list.remove (0);
5.46 + fail ("Modifications are not allowed");
5.47 + } catch (UnsupportedOperationException ex) {
5.48 + // ok
5.49 + }
5.50 +
5.51 +
5.52 + assertEquals (8, list.get (0).getX());
5.53 + assertEquals (0, list.get (0).getY());
5.54 + assertEquals (10, list.get (0).getFences ());
5.55 + assertEquals (8, list.get (1).getX());
5.56 + assertEquals (16, list.get (1).getY());
5.57 + assertEquals (10, list.get (1).getFences ());
5.58 + }
5.59 +
5.60 + public void testFences () {
5.61 + assertEquals ("No on board", 0, board.getFences ().size ());
5.62 + try {
5.63 + board.getFences ().add (null);
5.64 + fail ("Should be unmodifiable");
5.65 + } catch (java.lang.UnsupportedOperationException ex) {
5.66 + // ok
5.67 + }
5.68 + }
5.69 +
5.70 + public void testFourTimesInAgainstEachOtherResultsInInvalidPosition () throws Exception {
5.71 + Board b = board;
5.72 +
5.73 + for (int i = 0; i < 3; i++) {
5.74 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.75 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH);
5.76 + }
5.77 +
5.78 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.79 + try {
5.80 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH);
5.81 + fail ("Now the positions of two players are supposed to be the same, this results in exception");
5.82 + } catch (IllegalPositionException ex) {
5.83 + // ok
5.84 + }
5.85 +
5.86 + }
5.87 +
5.88 + public void testCrossFences () throws Exception {
5.89 + Board b1 = board.fence (board.getPlayers ().get(0), 'A', 1, Board.Fence.Orientation.HORIZONTAL);
5.90 +
5.91 + try {
5.92 + b1.fence (b1.getPlayers ().get(1), 'A', 1, Board.Fence.Orientation.VERTICAL);
5.93 + fail ("This must fail, as the fences overlap");
5.94 + } catch (IllegalPositionException ex) {
5.95 + // ok
5.96 + }
5.97 + }
5.98 +
5.99 + public void testPawnsCanJumpOverEachOther () throws Exception {
5.100 + Board b = board;
5.101 +
5.102 + for (int i = 0; i < 3; i++) {
5.103 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.104 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH);
5.105 + }
5.106 +
5.107 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.108 +
5.109 + // jump over
5.110 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH, Board.Player.Direction.SOUTH);
5.111 + }
5.112 +
5.113 + public void testCannotJumpOverFence () throws Exception {
5.114 + Board b = board.fence (board.getPlayers ().get (0), 'D', 8, Board.Fence.Orientation.HORIZONTAL);
5.115 + try {
5.116 + b.move (board.getPlayers ().get (1), Player.Direction.SOUTH);
5.117 + fail ("This shall not be allowed, as there is the fence");
5.118 + } catch (IllegalPositionException ex) {
5.119 + // ok
5.120 + }
5.121 + }
5.122 +
5.123 +
5.124 + public void testSideJumpsNotAllowedWhenThereIsNoFence () throws Exception {
5.125 + Board b = board;
5.126 +
5.127 + for (int i = 0; i < 3; i++) {
5.128 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.129 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH);
5.130 + }
5.131 +
5.132 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.133 +
5.134 + try {
5.135 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH, Board.Player.Direction.WEST);
5.136 + fail ("Cannot just jump aside");
5.137 + } catch (IllegalPositionException ex) {
5.138 + // ok
5.139 + }
5.140 + }
5.141 +
5.142 + public void testSideJumpsAllowedWhenThereAFence () throws Exception {
5.143 + Board b = board;
5.144 +
5.145 + for (int i = 0; i < 3; i++) {
5.146 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.147 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH);
5.148 + }
5.149 +
5.150 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.151 +
5.152 + assertEquals (8, b.getPlayers ().get (0).getX ());
5.153 + assertEquals (8, b.getPlayers ().get (0).getY ());
5.154 +
5.155 + b = b.fence(b.getPlayers ().get (0), 'D', 4, Board.Fence.Orientation.HORIZONTAL);
5.156 +
5.157 + // we can over jump to west
5.158 + b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH, Board.Player.Direction.WEST);
5.159 + // as well as east
5.160 + b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH, Board.Player.Direction.EAST);
5.161 + }
5.162 +
5.163 + public void testAlwaysHasToHaveAccessToEndLine () throws Exception {
5.164 + Board b = board;
5.165 +
5.166 + b = b.fence (b.getPlayers ().get (0), 'E', 1, Board.Fence.Orientation.HORIZONTAL);
5.167 + b = b.fence (b.getPlayers ().get (0), 'F', 1, Board.Fence.Orientation.VERTICAL);
5.168 +
5.169 + try {
5.170 + b = b.fence (b.getPlayers ().get (0), 'D', 1, Board.Fence.Orientation.VERTICAL);
5.171 + fail ("This is not allowed as player 0 cannot now reach the final line");
5.172 + } catch (IllegalPositionException ex) {
5.173 + // ok
5.174 + }
5.175 +
5.176 + }
5.177 +
5.178 + public void testEqualsOfPlayers () throws Exception {
5.179 + Board.Player p1 = new Board.Player (1, 1, 10, Board.Player.Direction.EAST);
5.180 + Board.Player p2 = new Board.Player (1, 1, 10, Board.Player.Direction.EAST);
5.181 + Board.Player p3 = new Board.Player (2, 1, 10, Board.Player.Direction.EAST);
5.182 + Board.Player p4 = new Board.Player (1, 1, 10, Board.Player.Direction.WEST);
5.183 + Board.Player p5 = new Board.Player (1, 2, 10, Board.Player.Direction.EAST);
5.184 + Board.Player p6 = new Board.Player (1, 1, 5, Board.Player.Direction.EAST);
5.185 +
5.186 + assertEquals ("p1 == p2", p1, p2);
5.187 + if (p2.equals (p3)) fail ();
5.188 + if (p2.equals (p4)) fail ();
5.189 + if (p2.equals (p5)) fail ();
5.190 + if (p2.equals (p6)) fail ();
5.191 + if (p3.equals (p6)) fail ();
5.192 + if (p4.equals (p3)) fail ();
5.193 + if (p6.equals (p3)) fail ();
5.194 + if (p5.equals (p3)) fail ();
5.195 + if (p5.equals (p3)) fail ();
5.196 + if (p4.equals (p3)) fail ();
5.197 + if (p3.equals (p4)) fail ();
5.198 + if (p3.equals (p5)) fail ();
5.199 + if (p4.equals (p5)) fail ();
5.200 + if (p5.equals (p4)) fail ();
5.201 + if (p5.equals ("Ahoj")) fail ();
5.202 + }
5.203 +
5.204 + public void testEqualsOfFences () throws Exception {
5.205 + Board.Fence f1 = new Board.Fence (1, 1, Board.Fence.Orientation.HORIZONTAL);
5.206 + Board.Fence f2 = new Board.Fence (1, 1, Board.Fence.Orientation.HORIZONTAL);
5.207 + Board.Fence f3 = new Board.Fence (3, 1, Board.Fence.Orientation.HORIZONTAL);
5.208 + Board.Fence f4 = new Board.Fence (1, 3, Board.Fence.Orientation.HORIZONTAL);
5.209 + Board.Fence f5 = new Board.Fence (1, 1, Board.Fence.Orientation.VERTICAL);
5.210 +
5.211 + assertEquals ("f1 == f2", f1, f2);
5.212 + if (f1.equals (f3)) fail ();
5.213 + if (f3.equals (f1)) fail ();
5.214 + if (f5.equals (f1)) fail ();
5.215 + if (f1.equals (f5)) fail ();
5.216 + if (f4.equals (f1)) fail ();
5.217 + if (f1.equals (f4)) fail ();
5.218 + }
5.219 +
5.220 + public void testEqualsOfBoards1 () throws Exception {
5.221 + Board b1 = board.move (board.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.222 + Board b2 = board.move (board.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.223 + Board b3 = board.move (board.getPlayers ().get (0), Board.Player.Direction.EAST);
5.224 +
5.225 + if (b1.equals (b3)) fail ();
5.226 + if (b3.equals (b1)) fail ();
5.227 +
5.228 + assertEquals ("b1 == b2", b1, b2);
5.229 + }
5.230 + public void testEqualsOfBoards2 () throws Exception {
5.231 + Board b1 = board.fence (board.getPlayers ().get (0), 'E', 3, Board.Fence.Orientation.HORIZONTAL);
5.232 + Board b2 = board.fence (board.getPlayers ().get (0), 'E', 3, Board.Fence.Orientation.HORIZONTAL);
5.233 + Board b3 = board.fence (board.getPlayers ().get (0), 'D', 3, Board.Fence.Orientation.HORIZONTAL);
5.234 + Board b4 = board.fence (board.getPlayers ().get (0), 'E', 4, Board.Fence.Orientation.HORIZONTAL);
5.235 + Board b5 = board.fence (board.getPlayers ().get (0), 'E', 3, Board.Fence.Orientation.VERTICAL);
5.236 +
5.237 + if (b1.equals (b3)) fail ();
5.238 + if (b3.equals (b1)) fail ();
5.239 + if (b1.equals (b4)) fail ();
5.240 + if (b1.equals (b5)) fail ();
5.241 + if (b5.equals (b1)) fail ();
5.242 + if (b4.equals (b1)) fail ();
5.243 +
5.244 + assertEquals ("b1 == b2", b1, b2);
5.245 + }
5.246 + public void testEqualsOfBoardsWhenJumpOver () throws Exception {
5.247 + Board b = board;
5.248 +
5.249 + for (int i = 0; i < 3; i++) {
5.250 + b = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.251 + b = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH);
5.252 + }
5.253 +
5.254 + Board b1 = b.move (b.getPlayers ().get (0), Board.Player.Direction.NORTH);
5.255 +
5.256 + Board b2 = b.move (b.getPlayers ().get (1), Board.Player.Direction.SOUTH);
5.257 + b2 = b2.move (b2.getPlayers ().get (0), Board.Player.Direction.NORTH, Board.Player.Direction.NORTH);
5.258 +
5.259 + if (b1.equals (b2)) fail ("Not the same, pawns are reverted");
5.260 + if (b2.equals (b1)) fail ("Not the same, pawns are reverted");
5.261 + }
5.262 +}