Support for giving up the game
authorJaroslav Tulach <jtulach@netbeans.org>
Thu, 10 Sep 2009 23:19:40 +0200
changeset 756802034b7a6f
parent 74 b2af4da1cbbe
child 76 ff37bdeef2b3
Support for giving up the game
freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/UI.java
freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.fmt
freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.properties
freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game_cs.properties
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
quoridor/src/test/java/cz/xelfi/quoridor/MoveTest.java
webidor/src/test/java/cz/xelfi/quoridor/webidor/FinishedGameTest.java
     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  }