1.1 --- a/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/UI.java Thu Sep 10 22:48:21 2009 +0200
1.2 +++ b/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/UI.java Thu Sep 10 23:19:40 2009 +0200
1.3 @@ -148,6 +148,10 @@
1.4 }
1.5 WebResource wr = base.path("games").path(id).queryParam("player", user);
1.6 try {
1.7 + if (type.equals("resign")) {
1.8 + wr.queryParam("move", "RESIGN").put();
1.9 + return board(id);
1.10 + }
1.11 if (type.equals("fence")) {
1.12 wr.queryParam("move", direction.charAt(0) + column + row).put();
1.13 return board(id);
2.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.fmt Thu Sep 10 22:48:21 2009 +0200
2.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.fmt Thu Sep 10 23:19:40 2009 +0200
2.3 @@ -80,6 +80,10 @@
2.4 </select>
2.5 <input type="submit" value="${bundle.MOVE}" />
2.6 </form>
2.7 + <form action="/games/${doc.game.id.@id}/move">
2.8 + <input type="hidden" name="type" value="resign" readonly="readonly"/>
2.9 + <input type="submit" value="${bundle.RESIGN}" />
2.10 + </form>
2.11 </#if>
2.12 <pre>${doc.game.board}</pre>
2.13
3.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.properties Thu Sep 10 22:48:21 2009 +0200
3.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.properties Thu Sep 10 23:19:40 2009 +0200
3.3 @@ -1,6 +1,7 @@
3.4 players={0} vs. {1}
3.5 PLACE=Place!
3.6 MOVE=Move!
3.7 +RESIGN=Resign!
3.8 H=Horizontal
3.9 V=Vertical
3.10 RELOAD=Reload
4.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game_cs.properties Thu Sep 10 22:48:21 2009 +0200
4.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game_cs.properties Thu Sep 10 23:19:40 2009 +0200
4.3 @@ -1,6 +1,7 @@
4.4 players={0} proti {1}
4.5 PLACE=Um\u00EDstit
4.6 MOVE=T\u00E1hnout
4.7 +RESIGN=Vzd\u00E1t
4.8 H=Horizont\u00E1ln\u011B
4.9 V=Vertik\u00E1ln\u011B
4.10 RELOAD=Obnovit
5.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Thu Sep 10 22:48:21 2009 +0200
5.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Thu Sep 10 23:19:40 2009 +0200
5.3 @@ -64,6 +64,8 @@
5.4 * @author Jaroslav Tulach
5.5 */
5.6 public final class Board {
5.7 + /** winner, if any */
5.8 + private final Player winner;
5.9 /** players */
5.10 private final List<Player> players;
5.11 /** fences placed on board */
5.12 @@ -117,6 +119,7 @@
5.13 throw new IllegalStateException (ex.getMessage ());
5.14 }
5.15 this.turn = 0;
5.16 + this.winner = null;
5.17 }
5.18
5.19 /** Copy constructor that provides players and fences.
5.20 @@ -133,6 +136,16 @@
5.21 }
5.22 }
5.23 this.turn = turn % players.size();
5.24 + this.winner = null;
5.25 + }
5.26 +
5.27 + /** Copy constructor for resigning the game */
5.28 + private Board(Board previous, int winner) {
5.29 + this.players = previous.players;
5.30 + this.turn = winner % players.size();
5.31 + this.fences = previous.fences;
5.32 + this.occupied = previous.occupied;
5.33 + this.winner = players.get(this.turn);
5.34 }
5.35
5.36 /** Returns empty board with default starting position.
5.37 @@ -158,9 +171,12 @@
5.38 }
5.39
5.40 /** The player that is supposed to play now.
5.41 - * @return the player to do next move
5.42 + * @return the player to do next move, null if the game is over
5.43 */
5.44 public Player getCurrentPlayer() {
5.45 + if (getWinner() != null) {
5.46 + return null;
5.47 + }
5.48 return players.get(turn);
5.49 }
5.50
5.51 @@ -169,6 +185,9 @@
5.52 * @return the winning player or <code>null</code>
5.53 */
5.54 public Player getWinner() {
5.55 + if (winner != null) {
5.56 + return winner;
5.57 + }
5.58 for (Player p : players) {
5.59 if (p.endDirection.reached(p)) {
5.60 return p;
5.61 @@ -192,7 +211,11 @@
5.62 if (move.direction != null) {
5.63 return move(getCurrentPlayer(), move.direction);
5.64 } else {
5.65 - return fence(getCurrentPlayer(), move.fence);
5.66 + if (move.fence != null) {
5.67 + return fence(getCurrentPlayer(), move.fence);
5.68 + } else {
5.69 + return new Board(this, turn + 1);
5.70 + }
5.71 }
5.72 }
5.73
6.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Move.java Thu Sep 10 22:48:21 2009 +0200
6.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Move.java Thu Sep 10 23:19:40 2009 +0200
6.3 @@ -46,6 +46,10 @@
6.4 fence = f;
6.5 direction = null;
6.6 }
6.7 + private Move() {
6.8 + fence = null;
6.9 + direction = null;
6.10 + }
6.11
6.12 /** Moves the player's figure to north */
6.13 public static final Move NORTH = new Move(Direction.NORTH);
6.14 @@ -55,6 +59,8 @@
6.15 public static final Move SOUTH = new Move(Direction.SOUTH);
6.16 /** Moves the player's figure to west */
6.17 public static final Move WEST = new Move(Direction.WEST);
6.18 + /** Allows the player to resign the game */
6.19 + public static final Move RESIGN = new Move();
6.20
6.21 /** Places a fence into given position with specified orientation.
6.22 * The faces postions are numbered 1-8 and A-H according to following
6.23 @@ -139,6 +145,10 @@
6.24 case 'E': return Move.EAST;
6.25 case 'W': return Move.WEST;
6.26 }
6.27 + case 6:
6.28 + if ("RESIGN".equals(move)) {
6.29 + return Move.RESIGN;
6.30 + }
6.31 }
6.32 throw new IllegalPositionException(move);
6.33 }
6.34 @@ -152,6 +162,9 @@
6.35 }
6.36 throw new IllegalStateException();
6.37 } else {
6.38 + if (direction == null) {
6.39 + return "RESIGN"; // NOI18N
6.40 + }
6.41 StringBuilder sb = new StringBuilder();
6.42 for (Direction d : direction) {
6.43 sb.append(d.name().charAt(0));
7.1 --- a/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Thu Sep 10 22:48:21 2009 +0200
7.2 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Thu Sep 10 23:19:40 2009 +0200
7.3 @@ -51,6 +51,32 @@
7.4 protected abstract Board apply(Board b, Move move) throws IllegalPositionException;
7.5
7.6
7.7 + public void testResignWhite() throws IllegalPositionException {
7.8 + List<Player> list = board.getPlayers();
7.9 + assertEquals ("Two", 2, list.size ());
7.10 + Board b = board.apply(Move.RESIGN);
7.11 + assertEquals(b.getPlayers().get(1), b.getWinner());
7.12 + try {
7.13 + b.apply(Move.EAST);
7.14 + fail("No more moves allowed, the player resigned");
7.15 + } catch (IllegalPositionException ex) {
7.16 + // OK
7.17 + }
7.18 + assertNull("No player", b.getCurrentPlayer());
7.19 + }
7.20 + public void testResignBlack() throws IllegalPositionException {
7.21 + List<Player> list = board.getPlayers();
7.22 + assertEquals ("Two", 2, list.size ());
7.23 + Board b = board.apply(Move.NORTH).apply(Move.RESIGN);
7.24 + assertEquals(b.getPlayers().get(0), b.getWinner());
7.25 + try {
7.26 + b.apply(Move.EAST);
7.27 + fail("No more moves allowed, the player resigned");
7.28 + } catch (IllegalPositionException ex) {
7.29 + // OK
7.30 + }
7.31 + assertNull("No player", b.getCurrentPlayer());
7.32 + }
7.33 public void testTwoPlayers () {
7.34 List<Player> list = board.getPlayers();
7.35 assertEquals ("Two", 2, list.size ());
8.1 --- a/quoridor/src/test/java/cz/xelfi/quoridor/MoveTest.java Thu Sep 10 22:48:21 2009 +0200
8.2 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/MoveTest.java Thu Sep 10 23:19:40 2009 +0200
8.3 @@ -28,10 +28,6 @@
8.4
8.5 import cz.xelfi.quoridor.Fence.Orientation;
8.6 import cz.xelfi.quoridor.Player.Direction;
8.7 -import org.junit.After;
8.8 -import org.junit.AfterClass;
8.9 -import org.junit.Before;
8.10 -import org.junit.BeforeClass;
8.11 import org.junit.Test;
8.12 import static org.junit.Assert.*;
8.13
8.14 @@ -61,6 +57,10 @@
8.15 checkValueOf("W", Move.WEST);
8.16 }
8.17 @Test
8.18 + public void testRegisn() throws Exception {
8.19 + checkValueOf("RESIGN", Move.RESIGN);
8.20 + }
8.21 + @Test
8.22 public void testJumps() throws Exception {
8.23 for (Direction d1 : Direction.values()) {
8.24 for (Direction d2 : Direction.values()) {
9.1 --- a/webidor/src/test/java/cz/xelfi/quoridor/webidor/FinishedGameTest.java Thu Sep 10 22:48:21 2009 +0200
9.2 +++ b/webidor/src/test/java/cz/xelfi/quoridor/webidor/FinishedGameTest.java Thu Sep 10 23:19:40 2009 +0200
9.3 @@ -26,21 +26,11 @@
9.4
9.5 package cz.xelfi.quoridor.webidor;
9.6
9.7 -import com.sun.jersey.api.client.GenericType;
9.8 -import com.sun.jersey.api.client.UniformInterfaceException;
9.9 -import com.sun.jersey.core.header.MediaTypes;
9.10 import com.sun.jersey.test.framework.JerseyTest;
9.11 -import cz.xelfi.quoridor.Board;
9.12 -import cz.xelfi.quoridor.Move;
9.13 -import cz.xelfi.quoridor.webidor.resources.Games;
9.14 import java.io.File;
9.15 -import java.io.FileReader;
9.16 import java.io.IOException;
9.17 -import java.util.List;
9.18 -import java.util.Map;
9.19 import javax.ws.rs.core.MediaType;
9.20 import org.junit.Test;
9.21 -import org.w3c.dom.Document;
9.22 import static org.junit.Assert.*;
9.23
9.24 /**
9.25 @@ -103,4 +93,14 @@
9.26 assertEquals("BlackWins", GameResult.BLACK_WON, end.getId().getResult());
9.27 }
9.28
9.29 + @Test public void testResignAGame() throws Exception {
9.30 + webResource = webResource.path("api");
9.31 + GameId s = webResource.path("games").queryParam("white", "Jarda")
9.32 + .queryParam("black", "Jirka").post(GameId.class);
9.33 +
9.34 + webResource.path("games/" + s.getId()).queryParam("player", "Jarda").queryParam("move", "RESIGN").put(GameId.class);
9.35 + Game end = webResource.path("games/" + s.getId()).accept(MediaType.TEXT_XML).get(Game.class);
9.36 + assertEquals("BlackWins", GameResult.BLACK_WON, end.getId().getResult());
9.37 + }
9.38 +
9.39 }