Initial version of statistics and ELO rating. Donated by Martin Rexa
1.1 --- a/freemarkerdor/pom.xml Fri Jan 01 20:53:17 2010 +0100
1.2 +++ b/freemarkerdor/pom.xml Thu Jan 07 22:34:17 2010 +0100
1.3 @@ -71,6 +71,12 @@
1.4 <artifactId>freemarker</artifactId>
1.5 <version>2.3.8</version>
1.6 </dependency>
1.7 + <dependency>
1.8 + <groupId>${project.groupId}</groupId>
1.9 + <artifactId>statistics</artifactId>
1.10 + <version>1.0</version>
1.11 + <scope>test</scope>
1.12 + </dependency>
1.13 </dependencies>
1.14 <build>
1.15 <plugins>
1.16 @@ -126,3 +132,4 @@
1.17
1.18
1.19
1.20 +
2.1 --- a/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/UI.java Fri Jan 01 20:53:17 2010 +0100
2.2 +++ b/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/UI.java Thu Jan 07 22:34:17 2010 +0100
2.3 @@ -87,6 +87,7 @@
2.4 version = p.getProperty("version", "unknown"); // NOI18N
2.5 }
2.6 private static WebResource base;
2.7 + private static WebResource stat;
2.8
2.9 @Context
2.10 private HttpHeaders headers;
2.11 @@ -163,6 +164,7 @@
2.12 }
2.13 String txt = wr.accept(MediaType.TEXT_PLAIN).get(String.class);
2.14 Board b = Board.valueOf(txt);
2.15 +// Board b = new Board(txt);
2.16 ResponseBuilder resp = Response.ok();
2.17 CacheControl cc = new CacheControl();
2.18 cc.setNoCache(true);
2.19 @@ -220,13 +222,25 @@
2.20
2.21 Document doc = url.accept(MediaType.TEXT_XML).get(Document.class);
2.22 Board b;
2.23 + String t = doc.getElementsByTagName("board").item(0).getTextContent();
2.24 try {
2.25 b = Board.valueOf(doc.getElementsByTagName("board").item(0).getTextContent());
2.26 - } catch (IllegalPositionException ex) {
2.27 + } catch (Exception ex) {
2.28 +// b = new Board(t);
2.29 +// } catch (IllegalStateException ex) {
2.30 Exceptions.printStackTrace(ex);
2.31 b = Board.empty();
2.32 }
2.33 - v = viewable("game.fmt", doc, "message", msg, "format", format, "board", b);
2.34 + String bCode = null;
2.35 + try{
2.36 + bCode = stat.path("openings").path(Board.board2HashCode(b)+".check").queryParam("loginID", user.getId()).accept(MediaType.TEXT_PLAIN).get(String.class);
2.37 + }catch(Exception e){
2.38 + bCode = null;
2.39 + }
2.40 + if(bCode == null || "".equals(bCode))
2.41 + v = viewable("game.fmt", doc, "message", msg, "format", format, "board", b,"textPicture",b.boardToPicture());
2.42 + else
2.43 + v = viewable("game.fmt", doc, "message", msg, "format", format, "board", b,"textPicture",b.boardToPicture(),"bCode", bCode);
2.44 return resp.entity(v).build();
2.45 }
2.46
2.47 @@ -346,7 +360,72 @@
2.48
2.49 return welcome(10);
2.50 }
2.51 +
2.52 + @GET
2.53 + @Path("elo")
2.54 + @Produces(MediaType.TEXT_HTML)
2.55 + public Response getEloList(){
2.56 + Viewable v = checkLogin();
2.57 + if (v != null) {
2.58 + return Response.status(Response.Status.FORBIDDEN).entity(v).build();
2.59 + }
2.60 + final Document got = stat.path("elo").path("list").accept(MediaType.TEXT_XML).get(Document.class);
2.61 + return Response.ok(viewable("elo.fmt", got)).build();
2.62 + }
2.63
2.64 + @GET
2.65 + @Path("openings")
2.66 + @Produces(MediaType.TEXT_HTML)
2.67 + public Response getOpeningRoot(){
2.68 + return getOpeningNode("ROOT");
2.69 + }
2.70 +
2.71 + @GET
2.72 + @Path("openings/{code}")
2.73 + @Produces(MediaType.TEXT_HTML)
2.74 + public Response getOpeningNode(@PathParam("code") String code){
2.75 + Viewable v = checkLogin();
2.76 + if (v != null) {
2.77 + return Response.status(Response.Status.FORBIDDEN).entity(v).build();
2.78 + }
2.79 + final Document got = stat.path("openings").path(code).queryParam("loginID", user.getId()).accept(MediaType.TEXT_XML).get(Document.class);
2.80 + Board b;
2.81 + try {
2.82 + b = Board.valueOf(got.getElementsByTagName("nodeCode").item(0).getTextContent());
2.83 + } catch (Exception ex) {
2.84 + Exceptions.printStackTrace(ex);
2.85 + b = Board.empty();
2.86 + }
2.87 + return Response.ok(viewable("openings.fmt", got, "whitefences",b.getPlayers().get(0).getFences(),"blackfences",b.getPlayers().get(1).getFences())).build();
2.88 + }
2.89 +
2.90 + @GET
2.91 + @Path("openings/{code}/{status}")
2.92 + @Produces(MediaType.TEXT_HTML)
2.93 + public Response getOpeningNodeGames(@PathParam("code") String code, @PathParam("status") String status){
2.94 + Viewable v = checkLogin();
2.95 + if (v != null) {
2.96 + return Response.status(Response.Status.FORBIDDEN).entity(v).build();
2.97 + }
2.98 + final Document got = stat.path("openings").path(code).path(status).queryParam("loginID", user.getId()).accept(MediaType.TEXT_XML).get(Document.class);
2.99 + return Response.ok(viewable("opening_games.fmt", got,"code",code,"color",status)).build();
2.100 + }
2.101 +
2.102 + @GET
2.103 + @Path("openings/{code}.png")
2.104 + @Produces("image/png")
2.105 + public Response getOpeningBoardImage(
2.106 + @PathParam("code") String code,
2.107 + @QueryParam("fieldSize") @DefaultValue("40") int fieldSize
2.108 + ) throws IllegalPositionException {
2.109 + Board b = new Board(code);
2.110 + ResponseBuilder resp = Response.ok();
2.111 + CacheControl cc = new CacheControl();
2.112 + cc.setNoCache(true);
2.113 + resp.cacheControl(cc);
2.114 + return resp.entity(BoardImage.draw(b, fieldSize)).build();
2.115 + }
2.116 +
2.117 //
2.118 // start the server
2.119 //
2.120 @@ -376,12 +455,14 @@
2.121
2.122 static Callable<Void> startServers(int port, String remoteAPI) throws Exception {
2.123 Client client = new Client();
2.124 + Client client1 = new Client();
2.125
2.126 final HttpServer apiServer;
2.127 if (remoteAPI == null) {
2.128 throw new IllegalArgumentException("Provide URL to API server"); // NOI18N
2.129 } else {
2.130 base = client.resource(new URI(remoteAPI));
2.131 + stat = client1.resource(new URI("http://localhost:9444"));
2.132 apiServer = null;
2.133 }
2.134
3.1 --- a/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/W3CDocumentReader.java Fri Jan 01 20:53:17 2010 +0100
3.2 +++ b/freemarkerdor/src/main/java/cz/xelfi/quoridor/freemarkerdor/W3CDocumentReader.java Thu Jan 07 22:34:17 2010 +0100
3.3 @@ -1,6 +1,27 @@
3.4 /*
3.5 - * To change this template, choose Tools | Templates
3.6 - * and open the template in the editor.
3.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3.8 + *
3.9 + * The contents of this file are subject to the terms of either the GNU
3.10 + * General Public License Version 2 only ("GPL") or the Common
3.11 + * Development and Distribution License("CDDL") (collectively, the
3.12 + * "License"). You may not use this file except in compliance with the
3.13 + * License. You can obtain a copy of the License at
3.14 + * http://www.netbeans.org/cddl-gplv2.html
3.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
3.16 + * specific language governing permissions and limitations under the
3.17 + * License. When distributing the software, include this License Header
3.18 + * Notice in each file and include the License file at
3.19 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
3.20 + * particular file as subject to the "Classpath" exception as provided
3.21 + * by Sun in the GPL Version 2 section of the License file that
3.22 + * accompanied this code. If applicable, add the following below the
3.23 + * License Header, with the fields enclosed by brackets [] replaced by
3.24 + * your own identifying information:
3.25 + * "Portions Copyrighted [year] [name of copyright owner]"
3.26 + *
3.27 + * Contributor(s):
3.28 + *
3.29 + * Portions Copyrighted 2009 Jaroslav Tulach
3.30 */
3.31
3.32 package cz.xelfi.quoridor.freemarkerdor;
4.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/Bundle.properties Fri Jan 01 20:53:17 2010 +0100
4.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/Bundle.properties Thu Jan 07 22:34:17 2010 +0100
4.3 @@ -77,3 +77,10 @@
4.4 cs=\u010Cesky
4.5 LOCALE=en
4.6 CHANGE_LANGUAGE=Change!
4.7 +
4.8 +ELO_LIST=Elo rating
4.9 +ELO=Elo
4.10 +GAMES=Games
4.11 +OPENINGS=Openings
4.12 +WHITE_WON=White won
4.13 +BLACK_WON=Black won
5.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/Bundle_cs.properties Fri Jan 01 20:53:17 2010 +0100
5.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/Bundle_cs.properties Thu Jan 07 22:34:17 2010 +0100
5.3 @@ -89,3 +89,10 @@
5.4 LANGUAGE=Jazyk:
5.5 CHANGE_LANGUAGE=Zm\u011Bnit!
5.6 LOCALE=cs
5.7 +
5.8 +ELO_LIST=Elo rating
5.9 +ELO=Elo
5.10 +GAMES=Hry
5.11 +OPENINGS=Zah\u00E1jen\u00ED
5.12 +WHITE_WON=B\u00EDl\u00FD vyhr\u00E1l
5.13 +BLACK_WON=\u010Cern\u00FD vyhr\u00E1l
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/elo.fmt Thu Jan 07 22:34:17 2010 +0100
6.3 @@ -0,0 +1,43 @@
6.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
6.5 +<html>
6.6 + <head>
6.7 + <title>${bundle.ELO_LIST}</title>
6.8 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
6.9 + </head>
6.10 + <body bgcolor="white">
6.11 + <h3><a href="/">${bundle.TITLE_PLAIN}</a></h3>
6.12 + <h4>${bundle.ELO_LIST}</h4>
6.13 + <table border="1">
6.14 + <thead>
6.15 + <tr>
6.16 + <th>#</th>
6.17 + <th>${bundle.NAME}</th>
6.18 + <th>${bundle.ELO}</th>
6.19 + <th>${bundle.GAMES}</th>
6.20 + </tr>
6.21 + </thead>
6.22 + <tbody>
6.23 + <#assign cElo = 10000>
6.24 + <#assign index = 0>
6.25 + <#assign cIndex = index>
6.26 + <#list doc.eloList.elolist.* as item>
6.27 +
6.28 + <#assign index = index + 1>
6.29 + <#if cElo = item.@elo?number>
6.30 + <#else>
6.31 + <#assign cIndex = index>
6.32 + </#if>
6.33 + <#assign cElo = item.@elo?number>
6.34 +
6.35 + <tr>
6.36 + <td>${cIndex}</td>
6.37 + <td>${item.@player}</td>
6.38 + <td>${item.@elo?number}</td>
6.39 + <td>${item.@games}</td>
6.40 + </tr>
6.41 +
6.42 + </#list>
6.43 + </tbody>
6.44 + </table>
6.45 + </body>
6.46 +</html>
6.47 \ No newline at end of file
7.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.fmt Fri Jan 01 20:53:17 2010 +0100
7.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/game.fmt Thu Jan 07 22:34:17 2010 +0100
7.3 @@ -50,6 +50,7 @@
7.4 if (dir == 'W') r.x = -1;
7.5 return r;
7.6 }
7.7 + <#if board.currentPlayer??>
7.8 function paintPlayer() {
7.9 var fifth = fieldSize / 5;
7.10 var m1 = deltas(document.getElementById("pdir1").value.charAt(0));
7.11 @@ -72,7 +73,11 @@
7.12 var playerPos = {
7.13 x: ${board.currentPlayer.column},
7.14 y: ${board.currentPlayer.row}
7.15 - };
7.16 + };
7.17 + <#else>
7.18 + function paintPlayer() {
7.19 + }
7.20 + </#if>
7.21 </script>
7.22 </head>
7.23 <body bgcolor="white">
7.24 @@ -177,7 +182,7 @@
7.25 </#if>
7.26 <p>
7.27 <#if format?? && format = "text">
7.28 - <pre>${doc.game.board}</pre>
7.29 + <pre>${textPicture}</pre>
7.30 ${bundle.BOARD_VIEW}
7.31 <a href="/games/${doc.game.id.@id}?format=small">${bundle.BOARD_SMALL}</a>
7.32 <a href="/games/${doc.game.id.@id}?format=image">${bundle.BOARD_IMAGE}</a>
7.33 @@ -227,7 +232,9 @@
7.34 <a href="/games/${doc.game.id.@id}?move=${item.@index}">${item.@move}</a>
7.35 </#if>
7.36 </#macro>
7.37 -
7.38 + <#if (bCode??) >
7.39 + <h3><a href="/openings/${bCode}">${bundle.OPENINGS}</a></h3>
7.40 + </#if>
7.41 <h3><a href="/games/${doc.game.id.@id}?move=0">${bundle.MOVES}</a></h3>
7.42
7.43 <table border="0">
8.1 --- a/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/index.fmt Fri Jan 01 20:53:17 2010 +0100
8.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/index.fmt Thu Jan 07 22:34:17 2010 +0100
8.3 @@ -167,6 +167,8 @@
8.4 </p>
8.5 </#if>
8.6
8.7 + <h5><a href="/elo">${bundle.ELO_LIST}</a></h5>
8.8 + <h5><a href="/openings">${bundle.OPENINGS}</a></h5>
8.9 <h5>${bundle.OPTIONS}</h5>
8.10
8.11 <form action="/options">
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/opening_games.fmt Thu Jan 07 22:34:17 2010 +0100
9.3 @@ -0,0 +1,36 @@
9.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
9.5 +<html>
9.6 + <head>
9.7 + <title>${bundle.OPENINGS} - ${bundle.GAMES}</title>
9.8 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
9.9 + </head>
9.10 + <body bgcolor="white">
9.11 + <h3><a href="/">${bundle.TITLE_PLAIN}</a></h3>
9.12 + <h4>${bundle.OPENINGS} - ${bundle.GAMES}</h4>
9.13 +
9.14 + <#macro before t>
9.15 + <#assign seconds = (t / 1000)?long/>
9.16 + <#assign minutes= (seconds / 60)?long/>
9.17 + <#assign hours= (minutes / 60)?long/>
9.18 + <#assign days= (hours / 24)?long/>
9.19 + <!--millis: ${t}, seconds: ${seconds}, minutes: ${minutes} hours: ${hours}, days: ${days} -->
9.20 + ${bundle("LastMove", t?int, seconds?int, minutes?int, hours?int, days?int)}
9.21 + </#macro>
9.22 + <#macro game game>
9.23 + ${bundle("gameWhiteBlack", game.@white?string, game.@black?string)}
9.24 + <a href="/games/${game.@id}/"><@before (now - game.@modified?number)?long/></a>
9.25 + <#if game.@comments?number != 0>
9.26 + ${bundle("comments", game.@comments?number)}
9.27 + </#if>
9.28 + </#macro>
9.29 +
9.30 + <ol>
9.31 + <#list doc.gameIds.* as g>
9.32 + <li>
9.33 + <@game g/>
9.34 + </li>
9.35 + </#list>
9.36 + </ol>
9.37 + <h4><a href="/openings/${code}">${bundle.OPENINGS}</a></h4>
9.38 + </body>
9.39 +</html>
9.40 \ No newline at end of file
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/freemarkerdor/src/main/resources/cz/xelfi/quoridor/freemarkerdor/UI/openings.fmt Thu Jan 07 22:34:17 2010 +0100
10.3 @@ -0,0 +1,97 @@
10.4 +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
10.5 +<html>
10.6 + <head>
10.7 + <title>${bundle.OPENINGS}</title>
10.8 + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
10.9 + </head>
10.10 + <body bgcolor="white">
10.11 + <h3><a href="/">${bundle.TITLE_PLAIN}</a></h3>
10.12 + <h4><a href="/openings">${bundle.OPENINGS}</a></h4>
10.13 + <p>
10.14 + <b>${bundle.WHITE}:</b> ${bundle("FENCES_LEFT", whitefences?number)}<br>
10.15 + <b>${bundle.BLACK}:</b> ${bundle("FENCES_LEFT", blackfences?number)}<br>
10.16 + </p>
10.17 + <div style="position: relative; height:180px;">
10.18 + <img style="position: absolute; left: 0; right: 0;"
10.19 + width="180" height="180 "
10.20 + src="/openings/${doc.openingNodeView.@code}.png?fieldSize=20"
10.21 + alt="${bundle.BOARD_TEXT}"
10.22 + >
10.23 + <div id="fence" style="position: absolute; left: 0; right: 0;"></div>
10.24 + <div id="player" style="position: absolute; left: 0; right: 0;"></div>
10.25 + </div>
10.26 +
10.27 + <#macro move item>
10.28 + <a href="/openings/${item.code}/">${item.move}</a>
10.29 + </#macro>
10.30 + <#macro games cnt gId status code>
10.31 + <#if (cnt?number = 0)>
10.32 + ${cnt?number}
10.33 + </#if>
10.34 + <#if (cnt?number = 1)>
10.35 + <a href="/games/${gId.@id}/">${cnt?number}</a>
10.36 + </#if>
10.37 + <#if (cnt?number > 1)>
10.38 + <a href="/openings/${code}/${status}">${cnt?number}</a>
10.39 + </#if>
10.40 + </#macro>
10.41 + <#if (doc.openingNodeView.children.*?size > 0)>
10.42 + <table border="1">
10.43 + <thead>
10.44 + <tr>
10.45 + <th>${bundle.MOVENUMBER}</th>
10.46 + <th>${bundle.WHITE_WON}</th>
10.47 + <th>${bundle.BLACK_WON}</th>
10.48 + </tr>
10.49 + </thead>
10.50 + <tbody>
10.51 + <#list doc.openingNodeView.children.* as item>
10.52 + <tr>
10.53 + <td><@move item/></td>
10.54 + <td><@games item.whiteWon item.whiteGame 'white' item.code/></td>
10.55 + <td><@games item.blackWon item.blackGame 'black' item.code/></td>
10.56 + </tr>
10.57 + </#list>
10.58 + </tbody>
10.59 + </table>
10.60 + </#if>
10.61 +
10.62 + <#macro before t>
10.63 + <#assign seconds = (t / 1000)?long/>
10.64 + <#assign minutes= (seconds / 60)?long/>
10.65 + <#assign hours= (minutes / 60)?long/>
10.66 + <#assign days= (hours / 24)?long/>
10.67 + <!--millis: ${t}, seconds: ${seconds}, minutes: ${minutes} hours: ${hours}, days: ${days} -->
10.68 + ${bundle("LastMove", t?int, seconds?int, minutes?int, hours?int, days?int)}
10.69 + </#macro>
10.70 + <#macro game game>
10.71 + ${bundle("gameWhiteBlack", game.@white?string, game.@black?string)}
10.72 + <a href="/games/${game.@id}/"><@before (now - game.@modified?number)?long/></a>
10.73 + <#if game.@status = "whiteWon">
10.74 + ${bundle.WHITE_WON}
10.75 + </#if>
10.76 + <#if game.@status = "blackWon">
10.77 + ${bundle.BLACK_WON}
10.78 + </#if>
10.79 + <#if game.@comments?number != 0>
10.80 + ${bundle("comments", game.@comments?number)}
10.81 + </#if>
10.82 + </#macro>
10.83 +
10.84 + <#if (doc.openingNodeView.@whiteCount?number + doc.openingNodeView.@blackCount?number > 0)>
10.85 + <h3>${bundle.GAMES}</h3>
10.86 + <ol>
10.87 + <#list doc.openingNodeView.whiteGames.* as g>
10.88 + <li>
10.89 + <@game g/>
10.90 + </li>
10.91 + </#list>
10.92 + <#list doc.openingNodeView.blackGames.* as g>
10.93 + <li>
10.94 + <@game g/>
10.95 + </li>
10.96 + </#list>
10.97 + </ol>
10.98 + </#if>
10.99 + </body>
10.100 +</html>
10.101 \ No newline at end of file
11.1 --- a/pom.xml Fri Jan 01 20:53:17 2010 +0100
11.2 +++ b/pom.xml Thu Jan 07 22:34:17 2010 +0100
11.3 @@ -37,10 +37,11 @@
11.4 <module>quoridor</module>
11.5 <module>visidor</module>
11.6 <module>webidor</module>
11.7 + <module>statistics</module>
11.8 <module>freemarkerdor</module>
11.9 <module>emailer</module>
11.10 </modules>
11.11 <name>Quoridor related projects</name>
11.12 <description>Master project that agregates all quoridor related functionality.
11.13 </description>
11.14 -</project>
11.15 \ No newline at end of file
11.16 +</project>
12.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Fri Jan 01 20:53:17 2010 +0100
12.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Board.java Thu Jan 07 22:34:17 2010 +0100
12.3 @@ -42,6 +42,7 @@
12.4 import java.util.HashSet;
12.5 import java.util.List;
12.6 import java.util.Set;
12.7 +import java.util.TreeSet;
12.8 import java.util.regex.Matcher;
12.9 import java.util.regex.Pattern;
12.10
12.11 @@ -352,7 +353,11 @@
12.12 * @return board object, if the string can be read
12.13 * @throws IllegalPositionException if the string does not represent the board
12.14 */
12.15 - public static Board valueOf(String board) throws IllegalPositionException {
12.16 + public static Board valueOf(String board) {
12.17 + return new Board(board);
12.18 + }
12.19 +
12.20 + public static Board picture2board(String board) throws IllegalPositionException {
12.21 try {
12.22 return read(new StringReader(board));
12.23 } catch (IOException ex) {
12.24 @@ -697,6 +702,10 @@
12.25 */
12.26 @Override
12.27 public String toString() {
12.28 + return Board.board2HashCode(this);
12.29 + }
12.30 +
12.31 + public String boardToPicture() {
12.32 StringWriter w = new StringWriter();
12.33 try {
12.34 write(w);
12.35 @@ -863,4 +872,91 @@
12.36 return 17 * y + x;
12.37 }
12.38
12.39 + public Board(String hashCode) throws IllegalStateException{
12.40 + this.fences = new HashSet<Fence>();
12.41 + if((hashCode != null) && (hashCode.length() > 6)){
12.42 + char[]c = hashCode.toCharArray();
12.43 + this.players = Collections.unmodifiableList (Arrays.asList (new Player[] {
12.44 + new Player ((c[0]-'A')*2, (c[1]-'0')*2, c[2]-'a', Player.Direction.NORTH),
12.45 + new Player ((c[3]-'A')*2, (c[4]-'0')*2, c[5]-'a', Player.Direction.SOUTH),
12.46 + }));
12.47 + if(c[6]=='w'){
12.48 + this.turn = 0;
12.49 + this.winner = null;
12.50 + }else if(c[6]=='b'){
12.51 + this.turn = 1;
12.52 + this.winner = null;
12.53 + }else if(c[6]=='W'){
12.54 + this.turn = 0;
12.55 + this.winner = this.players.get(0);
12.56 + }else if(c[6]=='B'){
12.57 + this.turn = 1;
12.58 + this.winner = this.players.get(1);
12.59 + }else{
12.60 + this.turn = 0;
12.61 + this.winner = null;
12.62 + }
12.63 + for(int i=7; i<c.length;i+=2){
12.64 + int f = Integer.parseInt(hashCode.substring(i, i+2),16);
12.65 + Fence.Orientation o = Fence.Orientation.HORIZONTAL;
12.66 + if(f > 64){
12.67 + o = Fence.Orientation.VERTICAL;
12.68 + f -= 64;
12.69 + }
12.70 + fences.add(new Fence((f/8)*2+1, (f%8)*2+1,o));
12.71 + }
12.72 + }else{
12.73 + this.players = Collections.unmodifiableList (Arrays.asList (new Player[] {
12.74 + new Player (8,0,10,Player.Direction.NORTH),
12.75 + new Player (8,16,10,Player.Direction.SOUTH),
12.76 + }));
12.77 + this.winner = null;
12.78 + this.turn = 0;
12.79 + }
12.80 + try {
12.81 + this.occupied = computeOccupied (players, fences);
12.82 + } catch (IllegalPositionException ex) {
12.83 + throw new IllegalStateException (ex.getMessage ());
12.84 + }
12.85 + }
12.86 +
12.87 + public static String board2HashCode(Board b){
12.88 + StringBuilder sb = new StringBuilder();
12.89 + for(Player p: b.getPlayers()){
12.90 + sb.append((char)(p.getColumn() + 'A'));
12.91 + sb.append((char)(p.getRow() + '0'));
12.92 + sb.append((char)(p.getFences() + 'a'));
12.93 + }
12.94 + Player winner = b.getWinner();
12.95 + if(winner == null){
12.96 + if(b.players.indexOf(b.getCurrentPlayer())==0)
12.97 + sb.append('w');
12.98 + else if(b.players.indexOf(b.getCurrentPlayer())==1)
12.99 + sb.append('b');
12.100 + else
12.101 + sb.append('n');
12.102 + }else{
12.103 + if(b.players.indexOf(winner)==0)
12.104 + sb.append('W');
12.105 + else if(b.players.indexOf(winner)==1)
12.106 + sb.append('B');
12.107 + else
12.108 + sb.append('N');
12.109 + }
12.110 +
12.111 + TreeSet<Integer> fences = new TreeSet<Integer>();
12.112 + for(Fence f: b.getFences()){
12.113 + int a = (f.getColumn() - 'A')*8 + (f.getRow()-1);
12.114 + if(f.getOrientation().equals(Fence.Orientation.VERTICAL))
12.115 + a+=64;
12.116 + fences.add(a);
12.117 + }
12.118 + for(int f: fences){
12.119 + if(f<16)
12.120 + sb.append('0');
12.121 + sb.append(Integer.toHexString(f));
12.122 + }
12.123 + return sb.toString();
12.124 + }
12.125 +
12.126 }
13.1 --- a/quoridor/src/main/java/cz/xelfi/quoridor/Move.java Fri Jan 01 20:53:17 2010 +0100
13.2 +++ b/quoridor/src/main/java/cz/xelfi/quoridor/Move.java Thu Jan 07 22:34:17 2010 +0100
13.3 @@ -199,5 +199,26 @@
13.4 return hash;
13.5 }
13.6
13.7 + public Move getMirrorMove(){
13.8 + if(fence != null){
13.9 + return new Move(new Fence(16-fence.getX(), fence.getY(), fence.getOrientation()));
13.10 + }
13.11 + if(direction == null)
13.12 + return new Move();
13.13 + int dirSize = direction.length;
13.14 + Direction[] mirrorDirection = new Direction[dirSize];
13.15 + for(int i = 0; i < dirSize; i++){
13.16 + if(direction[i].equals(Direction.NORTH))
13.17 + mirrorDirection[i] = Direction.NORTH;
13.18 + else if(direction[i].equals(Direction.SOUTH))
13.19 + mirrorDirection[i] = Direction.SOUTH;
13.20 + else if(direction[i].equals(Direction.EAST))
13.21 + mirrorDirection[i] = Direction.WEST;
13.22 + else if(direction[i].equals(Direction.WEST))
13.23 + mirrorDirection[i] = Direction.EAST;
13.24 + }
13.25 + return new Move(mirrorDirection);
13.26 + }
13.27 +
13.28
13.29 }
14.1 --- a/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Fri Jan 01 20:53:17 2010 +0100
14.2 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/BoardCase.java Thu Jan 07 22:34:17 2010 +0100
14.3 @@ -200,6 +200,7 @@
14.4 "\n" +
14.5 " [S] \n";
14.6
14.7 + b = Board.picture2board(b).toString();
14.8 Board begin = Board.valueOf(b);
14.9
14.10 try {
15.1 --- a/quoridor/src/test/java/cz/xelfi/quoridor/SerializeTest.java Fri Jan 01 20:53:17 2010 +0100
15.2 +++ b/quoridor/src/test/java/cz/xelfi/quoridor/SerializeTest.java Thu Jan 07 22:34:17 2010 +0100
15.3 @@ -72,7 +72,8 @@
15.4 StringWriter w = new StringWriter();
15.5 b.write(w);
15.6 w.close();
15.7 - return Board.valueOf(w.toString());
15.8 + return Board.picture2board(w.toString());
15.9 + //return Board.valueOf(w.toString());
15.10 }
15.11
15.12 }
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
16.2 +++ b/statistics/all-zip.xml Thu Jan 07 22:34:17 2010 +0100
16.3 @@ -0,0 +1,19 @@
16.4 +<?xml version="1.0" encoding="UTF-8"?>
16.5 +<assembly>
16.6 + <id>all</id>
16.7 + <formats>
16.8 + <format>zip</format>
16.9 + </formats>
16.10 + <dependencySets>
16.11 + <dependencySet>
16.12 + <useProjectArtifact>false</useProjectArtifact>
16.13 + <outputDirectory>lib</outputDirectory>
16.14 + </dependencySet>
16.15 + </dependencySets>
16.16 + <files>
16.17 + <file>
16.18 + <source>target/statistics-${version}.jar</source>
16.19 + <outputDirectory>/</outputDirectory>
16.20 + </file>
16.21 + </files>
16.22 +</assembly>
17.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
17.2 +++ b/statistics/pom.xml Thu Jan 07 22:34:17 2010 +0100
17.3 @@ -0,0 +1,141 @@
17.4 +<?xml version="1.0" encoding="UTF-8"?>
17.5 +<project xmlns="http://maven.apache.org/POM/4.0.0"
17.6 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
17.7 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
17.8 + <modelVersion>4.0.0</modelVersion>
17.9 + <parent>
17.10 + <artifactId>all-quoridor</artifactId>
17.11 + <groupId>org.apidesign</groupId>
17.12 + <version>1.0</version>
17.13 + </parent>
17.14 + <groupId>org.apidesign</groupId>
17.15 + <artifactId>statistics</artifactId>
17.16 + <packaging>jar</packaging>
17.17 + <version>1.0</version>
17.18 + <name>Game Statistics</name>
17.19 + <url>http://maven.apache.org</url>
17.20 + <repositories>
17.21 + <repository>
17.22 + <id>maven2-repository.dev.java.net</id>
17.23 + <name>Java.net Repository for Maven</name>
17.24 + <url>http://download.java.net/maven/2/</url>
17.25 + <layout>default</layout>
17.26 + </repository>
17.27 + <repository>
17.28 + <id>maven-repository.dev.java.net</id>
17.29 + <name>Java.net Maven 1 Repository (legacy)</name>
17.30 + <url>http://download.java.net/maven/1</url>
17.31 + <layout>legacy</layout>
17.32 + </repository>
17.33 + </repositories>
17.34 + <dependencies>
17.35 +
17.36 + <dependency>
17.37 + <groupId>junit</groupId>
17.38 + <artifactId>junit</artifactId>
17.39 + <version>4.5</version>
17.40 + <scope>test</scope>
17.41 + </dependency>
17.42 + <dependency>
17.43 + <groupId>com.sun.jersey</groupId>
17.44 + <artifactId>jersey-core</artifactId>
17.45 + <version>1.1.0-ea</version>
17.46 + </dependency>
17.47 + <dependency>
17.48 + <groupId>com.sun.jersey</groupId>
17.49 + <artifactId>jersey-server</artifactId>
17.50 + <version>1.1.0-ea</version>
17.51 + </dependency>
17.52 + <dependency>
17.53 + <groupId>com.sun.jersey</groupId>
17.54 + <artifactId>jersey-json</artifactId>
17.55 + <version>1.1.0-ea</version>
17.56 + <type>jar</type>
17.57 + <exclusions>
17.58 + <exclusion>
17.59 + <artifactId>jaxb-api</artifactId>
17.60 + <groupId>javax.xml.bind</groupId>
17.61 + </exclusion>
17.62 + <exclusion>
17.63 + <artifactId>stax-api</artifactId>
17.64 + <groupId>stax</groupId>
17.65 + </exclusion>
17.66 + </exclusions>
17.67 + </dependency>
17.68 + <dependency>
17.69 + <groupId>com.sun.jersey.test.framework</groupId>
17.70 + <artifactId>jersey-test-framework</artifactId>
17.71 + <version>1.1.0-ea</version>
17.72 + <scope>test</scope>
17.73 + </dependency>
17.74 + <dependency>
17.75 + <groupId>org.apidesign</groupId>
17.76 + <artifactId>quoridor</artifactId>
17.77 + <version>1.0</version>
17.78 + <type>jar</type>
17.79 + </dependency>
17.80 + <dependency>
17.81 + <groupId>${project.groupId}</groupId>
17.82 + <artifactId>webidor</artifactId>
17.83 + <version>1.11</version>
17.84 + </dependency>
17.85 + </dependencies>
17.86 + <build>
17.87 + <plugins>
17.88 + <plugin>
17.89 + <groupId>org.apache.maven.plugins</groupId>
17.90 + <artifactId>maven-compiler-plugin</artifactId>
17.91 + <version>2.0.2</version>
17.92 + <configuration>
17.93 + <source>1.6</source>
17.94 + <target>1.6</target>
17.95 + </configuration>
17.96 + </plugin>
17.97 + <plugin>
17.98 + <groupId>org.codehaus.mojo</groupId>
17.99 + <artifactId>exec-maven-plugin</artifactId>
17.100 + <configuration>
17.101 + <mainClass>cz.xelfi.quoridor.statistics.resources.Statistics</mainClass>
17.102 + </configuration>
17.103 + </plugin>
17.104 + <plugin>
17.105 + <artifactId>maven-assembly-plugin</artifactId>
17.106 + <version>2.2-beta-2</version>
17.107 + <executions>
17.108 + <execution>
17.109 + <id>create-executable-jar</id>
17.110 + <phase>package</phase>
17.111 + <goals>
17.112 + <goal>single</goal>
17.113 + </goals>
17.114 + <configuration>
17.115 + <descriptors>
17.116 + <descriptor>all-zip.xml</descriptor>
17.117 + </descriptors>
17.118 + <finalName>statistics-${version}</finalName>
17.119 + </configuration>
17.120 + </execution>
17.121 + </executions>
17.122 + </plugin>
17.123 + <plugin>
17.124 + <groupId>org.apache.maven.plugins</groupId>
17.125 + <artifactId>maven-jar-plugin</artifactId>
17.126 + <configuration>
17.127 + <archive>
17.128 + <manifest>
17.129 + <addClasspath>true</addClasspath>
17.130 + <classpathPrefix>lib/</classpathPrefix>
17.131 + <mainClass>cz.xelfi.quoridor.statistics.resources.Statistics</mainClass>
17.132 + </manifest>
17.133 + </archive>
17.134 + </configuration>
17.135 + </plugin>
17.136 + </plugins>
17.137 + </build>
17.138 + <description>Server with API for games statistics</description>
17.139 +</project>
17.140 +
17.141 +
17.142 +
17.143 +
17.144 +
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/EloEntry.java Thu Jan 07 22:34:17 2010 +0100
18.3 @@ -0,0 +1,82 @@
18.4 +/*
18.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
18.6 + *
18.7 + * The contents of this file are subject to the terms of either the GNU
18.8 + * General Public License Version 2 only ("GPL") or the Common
18.9 + * Development and Distribution License("CDDL") (collectively, the
18.10 + * "License"). You may not use this file except in compliance with the
18.11 + * License. You can obtain a copy of the License at
18.12 + * http://www.netbeans.org/cddl-gplv2.html
18.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
18.14 + * specific language governing permissions and limitations under the
18.15 + * License. When distributing the software, include this License Header
18.16 + * Notice in each file and include the License file at
18.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
18.18 + * particular file as subject to the "Classpath" exception as provided
18.19 + * by Sun in the GPL Version 2 section of the License file that
18.20 + * accompanied this code. If applicable, add the following below the
18.21 + * License Header, with the fields enclosed by brackets [] replaced by
18.22 + * your own identifying information:
18.23 + * "Portions Copyrighted [year] [name of copyright owner]"
18.24 + *
18.25 + * Contributor(s):
18.26 + *
18.27 + * Portions Copyrighted 2010 Martin Rexa
18.28 + */
18.29 +
18.30 +package cz.xelfi.quoridor.statistics;
18.31 +
18.32 +import javax.xml.bind.annotation.XmlAttribute;
18.33 +import java.util.Comparator;
18.34 +/**
18.35 + *
18.36 + * @author Martin Rexa
18.37 + */
18.38 +public class EloEntry {
18.39 + String player;
18.40 + double elo;
18.41 + int games;
18.42 +
18.43 + public static final Comparator<EloEntry> BEST_FIRST = new BestFirst();
18.44 +
18.45 + EloEntry(){
18.46 + super();
18.47 + }
18.48 +
18.49 + EloEntry(String player, double elo, int games){
18.50 + super();
18.51 + this.player = player;
18.52 + this.elo = elo;
18.53 + this.games = games;
18.54 + }
18.55 +
18.56 + @XmlAttribute
18.57 + public String getPlayer(){
18.58 + return player;
18.59 + }
18.60 +
18.61 + @XmlAttribute
18.62 + public Double getElo(){
18.63 + return elo;
18.64 + }
18.65 +
18.66 + @XmlAttribute
18.67 + public Integer getGames(){
18.68 + return games;
18.69 + }
18.70 +
18.71 + public String toString(){
18.72 + return "Player: " + player + ", ELO: " + elo + ", Games: " + games;
18.73 + }
18.74 +
18.75 + private static final class BestFirst implements Comparator<EloEntry> {
18.76 + public int compare(EloEntry e1, EloEntry e2) {
18.77 + if(e1.elo > e2.elo)
18.78 + return -1;
18.79 + else if(e1.elo < e2.elo)
18.80 + return 1;
18.81 + else return e1.player.compareTo(e2.player);
18.82 + }
18.83 + }
18.84 +
18.85 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/EloList.java Thu Jan 07 22:34:17 2010 +0100
19.3 @@ -0,0 +1,104 @@
19.4 +/*
19.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
19.6 + *
19.7 + * The contents of this file are subject to the terms of either the GNU
19.8 + * General Public License Version 2 only ("GPL") or the Common
19.9 + * Development and Distribution License("CDDL") (collectively, the
19.10 + * "License"). You may not use this file except in compliance with the
19.11 + * License. You can obtain a copy of the License at
19.12 + * http://www.netbeans.org/cddl-gplv2.html
19.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
19.14 + * specific language governing permissions and limitations under the
19.15 + * License. When distributing the software, include this License Header
19.16 + * Notice in each file and include the License file at
19.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
19.18 + * particular file as subject to the "Classpath" exception as provided
19.19 + * by Sun in the GPL Version 2 section of the License file that
19.20 + * accompanied this code. If applicable, add the following below the
19.21 + * License Header, with the fields enclosed by brackets [] replaced by
19.22 + * your own identifying information:
19.23 + * "Portions Copyrighted [year] [name of copyright owner]"
19.24 + *
19.25 + * Contributor(s):
19.26 + *
19.27 + * Portions Copyrighted 2010 Martin Rexa
19.28 + */
19.29 +
19.30 +package cz.xelfi.quoridor.statistics;
19.31 +
19.32 +import java.util.Map;
19.33 +import java.util.HashMap;
19.34 +import java.util.List;
19.35 +import java.util.Collections;
19.36 +import java.util.ArrayList;
19.37 +import javax.xml.bind.annotation.XmlElement;
19.38 +import javax.xml.bind.annotation.XmlElementWrapper;
19.39 +import javax.xml.bind.annotation.XmlRootElement;
19.40 +import javax.xml.bind.annotation.XmlAccessType;
19.41 +import javax.xml.bind.annotation.XmlAccessorType;
19.42 +/**
19.43 + *
19.44 + * @author Martin Rexa
19.45 + */
19.46 +@XmlRootElement
19.47 +@XmlAccessorType(XmlAccessType.FIELD)
19.48 +public class EloList {
19.49 + static int INITIAL_ELO = 1250;
19.50 + static int MAX_ELO_DIFF = 400;
19.51 + static int KVAL_START = 25;
19.52 + static int KVAL_FOLLOW = 10;
19.53 + static int KVAL_LIMIT = 30;
19.54 +
19.55 + private Map<String, Double> players;
19.56 + private Map<String, Integer> playerGames;
19.57 +
19.58 + public EloList () {
19.59 + players = new HashMap<String, Double>();
19.60 + playerGames = new HashMap<String, Integer>();
19.61 + }
19.62 +
19.63 + @XmlElementWrapper(name="elolist")
19.64 + @XmlElement(name="item")
19.65 + public List<EloEntry> getFinalList(){
19.66 + List<EloEntry> finalList = new ArrayList<EloEntry>();
19.67 + for (Map.Entry<String, Double> player : players.entrySet()){
19.68 + finalList.add(new EloEntry(player.getKey(), player.getValue(), playerGames.get(player.getKey())));
19.69 + }
19.70 + Collections.sort(finalList, EloEntry.BEST_FIRST);
19.71 + return finalList;
19.72 + }
19.73 +
19.74 + public EloList putResult(String winner, String looser){
19.75 + double wElo = getElo(winner);
19.76 + double lElo = getElo(looser);
19.77 +
19.78 + double eloDiff = wElo - lElo;
19.79 + if(eloDiff < - MAX_ELO_DIFF)
19.80 + eloDiff = - MAX_ELO_DIFF;
19.81 + if(eloDiff > MAX_ELO_DIFF)
19.82 + eloDiff = MAX_ELO_DIFF;
19.83 +
19.84 + double wDiff = Math.round(100 * getKVal(winner) * (1 - (1 / (1 + Math.pow(10, -eloDiff / MAX_ELO_DIFF)))));
19.85 + wDiff /= 100.0;
19.86 + double lDiff = Math.round(100 * getKVal(looser) * (0 - (1 / (1 + Math.pow(10, eloDiff / MAX_ELO_DIFF)))));
19.87 + lDiff /= 100.0;
19.88 +
19.89 + players.put(winner, wElo + wDiff);
19.90 + players.put(looser, lElo + lDiff);
19.91 + return this;
19.92 + }
19.93 +
19.94 + public double getElo(String player){
19.95 + Double elo = players.get(player);
19.96 + return (elo == null) ? INITIAL_ELO : elo;
19.97 + }
19.98 +
19.99 + private int getKVal(String player){
19.100 + Integer games = playerGames.get(player);
19.101 + int g = (games == null) ? 0 : games;
19.102 + // Side effect, method should not be called more times for the same game/player
19.103 + playerGames.put(player, g + 1);
19.104 + return g < KVAL_LIMIT ? KVAL_START : KVAL_FOLLOW;
19.105 + }
19.106 +
19.107 +}
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/JAXBContextResolver.java Thu Jan 07 22:34:17 2010 +0100
20.3 @@ -0,0 +1,58 @@
20.4 +/*
20.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
20.6 + *
20.7 + * The contents of this file are subject to the terms of either the GNU
20.8 + * General Public License Version 2 only ("GPL") or the Common
20.9 + * Development and Distribution License("CDDL") (collectively, the
20.10 + * "License"). You may not use this file except in compliance with the
20.11 + * License. You can obtain a copy of the License at
20.12 + * http://www.netbeans.org/cddl-gplv2.html
20.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
20.14 + * specific language governing permissions and limitations under the
20.15 + * License. When distributing the software, include this License Header
20.16 + * Notice in each file and include the License file at
20.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
20.18 + * particular file as subject to the "Classpath" exception as provided
20.19 + * by Sun in the GPL Version 2 section of the License file that
20.20 + * accompanied this code. If applicable, add the following below the
20.21 + * License Header, with the fields enclosed by brackets [] replaced by
20.22 + * your own identifying information:
20.23 + * "Portions Copyrighted [year] [name of copyright owner]"
20.24 + *
20.25 + * Contributor(s):
20.26 + *
20.27 + * Portions Copyrighted 2010 Martin Rexa
20.28 + */
20.29 +package cz.xelfi.quoridor.statistics;
20.30 +
20.31 +import com.sun.jersey.api.json.JSONConfiguration;
20.32 +import com.sun.jersey.api.json.JSONJAXBContext;
20.33 +import java.util.Arrays;
20.34 +import java.util.HashSet;
20.35 +import java.util.Set;
20.36 +import javax.ws.rs.ext.ContextResolver;
20.37 +import javax.ws.rs.ext.Provider;
20.38 +import javax.xml.bind.JAXBContext;
20.39 +
20.40 +/**
20.41 + *
20.42 + * @author Martin Rexa
20.43 + */
20.44 +@Provider
20.45 +public final class JAXBContextResolver implements ContextResolver<JAXBContext> {
20.46 +
20.47 + private final JAXBContext context;
20.48 +
20.49 + private final Set<Class> types;
20.50 +
20.51 + private final Class[] cTypes = {EloList.class, EloEntry.class, OpeningNodeView.class, OpeningNodeViewEntry.class};
20.52 +
20.53 + public JAXBContextResolver() throws Exception {
20.54 + this.types = new HashSet(Arrays.asList(cTypes));
20.55 + this.context = new JSONJAXBContext(JSONConfiguration.natural().build(), cTypes);
20.56 + }
20.57 +
20.58 + public JAXBContext getContext(Class<?> objectType) {
20.59 + return (types.contains(objectType)) ? context : null;
20.60 + }
20.61 +}
20.62 \ No newline at end of file
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/OpeningNodeView.java Thu Jan 07 22:34:17 2010 +0100
21.3 @@ -0,0 +1,129 @@
21.4 +/*
21.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
21.6 + *
21.7 + * The contents of this file are subject to the terms of either the GNU
21.8 + * General Public License Version 2 only ("GPL") or the Common
21.9 + * Development and Distribution License("CDDL") (collectively, the
21.10 + * "License"). You may not use this file except in compliance with the
21.11 + * License. You can obtain a copy of the License at
21.12 + * http://www.netbeans.org/cddl-gplv2.html
21.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
21.14 + * specific language governing permissions and limitations under the
21.15 + * License. When distributing the software, include this License Header
21.16 + * Notice in each file and include the License file at
21.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
21.18 + * particular file as subject to the "Classpath" exception as provided
21.19 + * by Sun in the GPL Version 2 section of the License file that
21.20 + * accompanied this code. If applicable, add the following below the
21.21 + * License Header, with the fields enclosed by brackets [] replaced by
21.22 + * your own identifying information:
21.23 + * "Portions Copyrighted [year] [name of copyright owner]"
21.24 + *
21.25 + * Contributor(s):
21.26 + *
21.27 + * Portions Copyrighted 2010 Martin Rexa
21.28 + */
21.29 +
21.30 +package cz.xelfi.quoridor.statistics;
21.31 +
21.32 +import cz.xelfi.quoridor.webidor.GameId;
21.33 +import cz.xelfi.quoridor.webidor.GameStatus;
21.34 +import cz.xelfi.quoridor.Move;
21.35 +import java.util.Set;
21.36 +import java.util.HashSet;
21.37 +import java.util.Map;
21.38 +import java.util.HashMap;
21.39 +import java.util.List;
21.40 +import java.util.ArrayList;
21.41 +import javax.xml.bind.annotation.XmlElement;
21.42 +import javax.xml.bind.annotation.XmlElementWrapper;
21.43 +import javax.xml.bind.annotation.XmlRootElement;
21.44 +//import javax.xml.bind.annotation.XmlAccessType;
21.45 +//import javax.xml.bind.annotation.XmlAccessorType;
21.46 +import javax.xml.bind.annotation.XmlAttribute;
21.47 +
21.48 +/**
21.49 + *
21.50 + * @author Martin Rexa
21.51 + */
21.52 +
21.53 +@XmlRootElement
21.54 +//@XmlAccessorType(XmlAccessType.FIELD)
21.55 +public class OpeningNodeView {
21.56 + @XmlAttribute
21.57 + String code;
21.58 + @XmlElementWrapper(name="whiteGames")
21.59 + @XmlElement(name="gameId")
21.60 + List<GameId> whiteGames;
21.61 + @XmlElementWrapper(name="blackGames")
21.62 + @XmlElement(name="gameId")
21.63 + List<GameId> blackGames;
21.64 + Map<Move, OpeningNodeViewEntry> entries;
21.65 + boolean empty;
21.66 +
21.67 + public OpeningNodeView(){
21.68 + }
21.69 +
21.70 + public OpeningNodeView(String code){
21.71 + this.code = code;
21.72 + entries = new HashMap<Move, OpeningNodeViewEntry>();
21.73 + whiteGames = new ArrayList<GameId>();
21.74 + blackGames = new ArrayList<GameId>();
21.75 + empty = true;
21.76 + }
21.77 +
21.78 + @XmlElement
21.79 + public String getNodeCode(){
21.80 + return code;
21.81 + }
21.82 +
21.83 + public void processGame(Move m, String code, GameId gId){
21.84 + OpeningNodeViewEntry e = entries.get(m);
21.85 + if(e == null){
21.86 + e = new OpeningNodeViewEntry(m,code);
21.87 + entries.put(m, e);
21.88 + }
21.89 + e.processGame(gId);
21.90 + empty = false;
21.91 + }
21.92 +
21.93 + @XmlElementWrapper(name="children")
21.94 + @XmlElement(name="item")
21.95 + public Set<OpeningNodeViewEntry> getChildren(){
21.96 + Set<OpeningNodeViewEntry> result = new HashSet<OpeningNodeViewEntry>();
21.97 + for(Map.Entry<Move, OpeningNodeViewEntry> e: entries.entrySet()){
21.98 + result.add(e.getValue());
21.99 + }
21.100 + return result;
21.101 + }
21.102 +
21.103 +
21.104 + public void addFinishedGame(GameId gId){
21.105 + if(gId.getStatus().equals(GameStatus.whiteWon))
21.106 + whiteGames.add(gId);
21.107 + if(gId.getStatus().equals(GameStatus.blackWon))
21.108 + blackGames.add(gId);
21.109 + empty = false;
21.110 + }
21.111 +
21.112 + @XmlAttribute
21.113 + public int getWhiteCount(){
21.114 + return whiteGames.size();
21.115 + }
21.116 +
21.117 + @XmlAttribute
21.118 + public int getBlackCount(){
21.119 + return blackGames.size();
21.120 + }
21.121 +
21.122 +
21.123 + @XmlAttribute
21.124 + public boolean getChildrenNotEmpty(){
21.125 + return !entries.isEmpty();
21.126 + }
21.127 +
21.128 + public boolean isEmpty(){
21.129 + return this.empty;
21.130 + }
21.131 +
21.132 +}
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
22.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/OpeningNodeViewEntry.java Thu Jan 07 22:34:17 2010 +0100
22.3 @@ -0,0 +1,86 @@
22.4 +/*
22.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
22.6 + *
22.7 + * The contents of this file are subject to the terms of either the GNU
22.8 + * General Public License Version 2 only ("GPL") or the Common
22.9 + * Development and Distribution License("CDDL") (collectively, the
22.10 + * "License"). You may not use this file except in compliance with the
22.11 + * License. You can obtain a copy of the License at
22.12 + * http://www.netbeans.org/cddl-gplv2.html
22.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
22.14 + * specific language governing permissions and limitations under the
22.15 + * License. When distributing the software, include this License Header
22.16 + * Notice in each file and include the License file at
22.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
22.18 + * particular file as subject to the "Classpath" exception as provided
22.19 + * by Sun in the GPL Version 2 section of the License file that
22.20 + * accompanied this code. If applicable, add the following below the
22.21 + * License Header, with the fields enclosed by brackets [] replaced by
22.22 + * your own identifying information:
22.23 + * "Portions Copyrighted [year] [name of copyright owner]"
22.24 + *
22.25 + * Contributor(s):
22.26 + *
22.27 + * Portions Copyrighted 2010 Martin Rexa
22.28 + */
22.29 +
22.30 +package cz.xelfi.quoridor.statistics;
22.31 +
22.32 +import cz.xelfi.quoridor.Move;
22.33 +import cz.xelfi.quoridor.webidor.GameId;
22.34 +import cz.xelfi.quoridor.webidor.GameStatus;
22.35 +import javax.xml.bind.annotation.XmlAccessType;
22.36 +import javax.xml.bind.annotation.XmlAccessorType;
22.37 +
22.38 +/**
22.39 + *
22.40 + * @author Martin Rexa
22.41 + */
22.42 +@XmlAccessorType(XmlAccessType.FIELD)
22.43 +public class OpeningNodeViewEntry extends Object{
22.44 + String move;
22.45 + String code;
22.46 + GameId gameId;
22.47 + GameId whiteGame;
22.48 + GameId blackGame;
22.49 + int whiteWon;
22.50 + int blackWon;
22.51 +
22.52 + public OpeningNodeViewEntry(){
22.53 + }
22.54 +
22.55 + public OpeningNodeViewEntry(Move m, String code){
22.56 + move = m.toString();
22.57 + this.code = code;
22.58 + }
22.59 +
22.60 + public void processGame(GameId gId){
22.61 + gameId = gId;
22.62 + if(gId.getStatus().equals(GameStatus.whiteWon)){
22.63 + whiteWon++;
22.64 + whiteGame = gId;
22.65 + }
22.66 + if(gId.getStatus().equals(GameStatus.blackWon)){
22.67 + blackWon++;
22.68 + blackGame = gId;
22.69 + }
22.70 + }
22.71 +
22.72 + @Override
22.73 + public boolean equals(Object obj){
22.74 + if (obj == null) {
22.75 + return false;
22.76 + }
22.77 + if (getClass() != obj.getClass()) {
22.78 + return false;
22.79 + }
22.80 + final OpeningNodeViewEntry other = (OpeningNodeViewEntry) obj;
22.81 + return this.move.equals(other.move);
22.82 + }
22.83 +
22.84 + @Override
22.85 + public String toString(){
22.86 + return move+": "+whiteWon+"/"+blackWon;
22.87 + }
22.88 +
22.89 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/OpeningTree.java Thu Jan 07 22:34:17 2010 +0100
23.3 @@ -0,0 +1,107 @@
23.4 +/*
23.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
23.6 + *
23.7 + * The contents of this file are subject to the terms of either the GNU
23.8 + * General Public License Version 2 only ("GPL") or the Common
23.9 + * Development and Distribution License("CDDL") (collectively, the
23.10 + * "License"). You may not use this file except in compliance with the
23.11 + * License. You can obtain a copy of the License at
23.12 + * http://www.netbeans.org/cddl-gplv2.html
23.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
23.14 + * specific language governing permissions and limitations under the
23.15 + * License. When distributing the software, include this License Header
23.16 + * Notice in each file and include the License file at
23.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
23.18 + * particular file as subject to the "Classpath" exception as provided
23.19 + * by Sun in the GPL Version 2 section of the License file that
23.20 + * accompanied this code. If applicable, add the following below the
23.21 + * License Header, with the fields enclosed by brackets [] replaced by
23.22 + * your own identifying information:
23.23 + * "Portions Copyrighted [year] [name of copyright owner]"
23.24 + *
23.25 + * Contributor(s):
23.26 + *
23.27 + * Portions Copyrighted 2010 Martin Rexa
23.28 + */
23.29 +
23.30 +package cz.xelfi.quoridor.statistics;
23.31 +
23.32 +import cz.xelfi.quoridor.Board;
23.33 +import cz.xelfi.quoridor.Move;
23.34 +import cz.xelfi.quoridor.webidor.Game;
23.35 +import cz.xelfi.quoridor.webidor.CommentedMove;
23.36 +import cz.xelfi.quoridor.IllegalPositionException;
23.37 +import java.util.Map;
23.38 +import java.util.HashMap;
23.39 +
23.40 +/**
23.41 + *
23.42 + * @author Martin Rexa
23.43 + */
23.44 +public class OpeningTree {
23.45 + Map<String, OpeningTreeNode> nodes = new HashMap<String, OpeningTreeNode>();
23.46 + OpeningTreeNode root;
23.47 +
23.48 + public OpeningTree(){
23.49 + root = new OpeningTreeNode("ROOT");
23.50 + nodes.put("ROOT", root);
23.51 + }
23.52 +
23.53 + public OpeningTreeNode getRoot(){
23.54 + return root;
23.55 + }
23.56 +
23.57 + public OpeningTreeNode getNode(String hashCode){
23.58 + return nodes.get(hashCode);
23.59 + }
23.60 +
23.61 + public void processGame(Game game) throws IllegalPositionException{
23.62 + OpeningTreeNode node = root;
23.63 + OpeningTreeNode parentNode;
23.64 + OpeningTreeNode mirrorNode = root;
23.65 + OpeningTreeNode mirrorParentNode;
23.66 + Board board = Board.empty();
23.67 + Board mirrorBoard = Board.empty();
23.68 + root.addGame(game);
23.69 + for(CommentedMove move: game.getMoves()){
23.70 + if(!move.getMove().equals(Move.RESIGN)){
23.71 + parentNode = node;
23.72 + mirrorParentNode = mirrorNode;
23.73 + board = board.apply(move.getMove());
23.74 + mirrorBoard = mirrorBoard.apply(move.getMove().getMirrorMove());
23.75 + String hashCode = Board.board2HashCode(board);
23.76 + String mirrorHashCode = Board.board2HashCode(mirrorBoard);
23.77 + node = nodes.get(hashCode);
23.78 + if(node == null){
23.79 + node = new OpeningTreeNode(hashCode);
23.80 + nodes.put(hashCode, node);
23.81 + }
23.82 + node.addGame(game);
23.83 + mirrorNode = nodes.get(mirrorHashCode);
23.84 + if(mirrorHashCode.equals(hashCode)){
23.85 + if(mirrorNode == null){
23.86 + mirrorNode = node;
23.87 + }
23.88 + }else{
23.89 + if(mirrorNode == null){
23.90 + mirrorNode = new OpeningTreeNode(mirrorHashCode);
23.91 + nodes.put(mirrorHashCode, mirrorNode);
23.92 + }
23.93 + mirrorNode.addGame(game);
23.94 + }
23.95 + if(parentNode != null)
23.96 + parentNode.addChild(move.getMove(),node);
23.97 + if(mirrorParentNode != null){
23.98 + if(parentNode.equals(mirrorParentNode) && node.equals(mirrorNode))
23.99 + ;
23.100 + else
23.101 + mirrorParentNode.addChild(move.getMove().getMirrorMove(),mirrorNode);
23.102 + }
23.103 + }
23.104 + }
23.105 + node.addFinishedGame(game);
23.106 + if(!node.equals(mirrorNode))
23.107 + mirrorNode.addFinishedGame(game);
23.108 + }
23.109 +
23.110 +}
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
24.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/OpeningTreeNode.java Thu Jan 07 22:34:17 2010 +0100
24.3 @@ -0,0 +1,138 @@
24.4 +/*
24.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
24.6 + *
24.7 + * The contents of this file are subject to the terms of either the GNU
24.8 + * General Public License Version 2 only ("GPL") or the Common
24.9 + * Development and Distribution License("CDDL") (collectively, the
24.10 + * "License"). You may not use this file except in compliance with the
24.11 + * License. You can obtain a copy of the License at
24.12 + * http://www.netbeans.org/cddl-gplv2.html
24.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
24.14 + * specific language governing permissions and limitations under the
24.15 + * License. When distributing the software, include this License Header
24.16 + * Notice in each file and include the License file at
24.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
24.18 + * particular file as subject to the "Classpath" exception as provided
24.19 + * by Sun in the GPL Version 2 section of the License file that
24.20 + * accompanied this code. If applicable, add the following below the
24.21 + * License Header, with the fields enclosed by brackets [] replaced by
24.22 + * your own identifying information:
24.23 + * "Portions Copyrighted [year] [name of copyright owner]"
24.24 + *
24.25 + * Contributor(s):
24.26 + *
24.27 + * Portions Copyrighted 2010 Martin Rexa
24.28 + */
24.29 +
24.30 +package cz.xelfi.quoridor.statistics;
24.31 +
24.32 +import cz.xelfi.quoridor.webidor.Game;
24.33 +import cz.xelfi.quoridor.webidor.GameId;
24.34 +import cz.xelfi.quoridor.webidor.GameStatus;
24.35 +import cz.xelfi.quoridor.webidor.User;
24.36 +import cz.xelfi.quoridor.Move;
24.37 +import java.util.HashMap;
24.38 +import java.util.Map;
24.39 +import java.util.List;
24.40 +import java.util.ArrayList;
24.41 +import javax.xml.bind.annotation.XmlAttribute;
24.42 +
24.43 +/**
24.44 + *
24.45 + * @author Martin Rexa
24.46 + */
24.47 +public class OpeningTreeNode {
24.48 + @XmlAttribute
24.49 + String hashCode;
24.50 + List<GameId> gameIds;
24.51 + List<GameId> finishedGames;
24.52 + Map<Move, OpeningTreeNode> children;
24.53 +
24.54 + public OpeningTreeNode(){
24.55 + }
24.56 +
24.57 + public OpeningTreeNode(String hashCode){
24.58 + this.hashCode = hashCode;
24.59 + gameIds = new ArrayList<GameId>();
24.60 + finishedGames = new ArrayList<GameId>();
24.61 + children = new HashMap<Move,OpeningTreeNode>();
24.62 + }
24.63 +
24.64 + public OpeningTreeNode addGame(Game game){
24.65 + gameIds.add(game.getId());
24.66 + return this;
24.67 + }
24.68 +
24.69 + public OpeningTreeNode addFinishedGame(Game game){
24.70 + finishedGames.add(game.getId());
24.71 + return this;
24.72 + }
24.73 +
24.74 + public OpeningTreeNode addGameId(GameId gameId){
24.75 + gameIds.add(gameId);
24.76 + return this;
24.77 + }
24.78 +
24.79 + public OpeningTreeNode addChild(Move move, OpeningTreeNode child){
24.80 + children.put(move, child);
24.81 + return this;
24.82 + }
24.83 +
24.84 + public OpeningNodeView getView(User user){
24.85 + return getView(user.getId());
24.86 + }
24.87 +
24.88 + public OpeningNodeView getView(String userId){
24.89 + OpeningNodeView view = new OpeningNodeView(hashCode);
24.90 + for(Map.Entry<Move, OpeningTreeNode> e: children.entrySet()){
24.91 + for(GameId gId: e.getValue().gameIds){
24.92 + if(User.canSee(gId, userId)){
24.93 + view.processGame(e.getKey(), e.getValue().hashCode, gId);
24.94 + }
24.95 + }
24.96 + }
24.97 + for(GameId gId: finishedGames){
24.98 + view.addFinishedGame(gId);
24.99 + }
24.100 + return view;
24.101 + }
24.102 +
24.103 + public List<GameId> filterGames(String userId, GameStatus status){
24.104 + List<GameId> result = new ArrayList<GameId>();
24.105 + for(GameId gId: gameIds){
24.106 + if(User.canSee(gId, userId))
24.107 + if(gId.getStatus().equals(status))
24.108 + result.add(gId);
24.109 + }
24.110 + return result;
24.111 + }
24.112 +
24.113 + public List<GameId> getGameIds(){
24.114 + return gameIds;
24.115 + }
24.116 +
24.117 +// @XmlAttribute
24.118 +// @XmlElement
24.119 + public String getHashCode(){
24.120 + return this.hashCode;
24.121 + }
24.122 +
24.123 +
24.124 + @Override
24.125 + public boolean equals(Object obj) {
24.126 + if (obj == null) {
24.127 + return false;
24.128 + }
24.129 + if (getClass() != obj.getClass()) {
24.130 + return false;
24.131 + }
24.132 + OpeningTreeNode other = (OpeningTreeNode)obj;
24.133 + return hashCode.equals(other.hashCode);
24.134 + }
24.135 +
24.136 + @Override
24.137 + public int hashCode() {
24.138 + return hashCode.hashCode();
24.139 + }
24.140 +
24.141 +}
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
25.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/resources/Elo.java Thu Jan 07 22:34:17 2010 +0100
25.3 @@ -0,0 +1,75 @@
25.4 +/*
25.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
25.6 + *
25.7 + * The contents of this file are subject to the terms of either the GNU
25.8 + * General Public License Version 2 only ("GPL") or the Common
25.9 + * Development and Distribution License("CDDL") (collectively, the
25.10 + * "License"). You may not use this file except in compliance with the
25.11 + * License. You can obtain a copy of the License at
25.12 + * http://www.netbeans.org/cddl-gplv2.html
25.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
25.14 + * specific language governing permissions and limitations under the
25.15 + * License. When distributing the software, include this License Header
25.16 + * Notice in each file and include the License file at
25.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
25.18 + * particular file as subject to the "Classpath" exception as provided
25.19 + * by Sun in the GPL Version 2 section of the License file that
25.20 + * accompanied this code. If applicable, add the following below the
25.21 + * License Header, with the fields enclosed by brackets [] replaced by
25.22 + * your own identifying information:
25.23 + * "Portions Copyrighted [year] [name of copyright owner]"
25.24 + *
25.25 + * Contributor(s):
25.26 + *
25.27 + * Portions Copyrighted 2010 Martin Rexa
25.28 + */
25.29 +
25.30 +package cz.xelfi.quoridor.statistics.resources;
25.31 +
25.32 +import cz.xelfi.quoridor.statistics.EloList;
25.33 +import cz.xelfi.quoridor.webidor.Game;
25.34 +import cz.xelfi.quoridor.webidor.GameId;
25.35 +import cz.xelfi.quoridor.webidor.GameStatus;
25.36 +import javax.ws.rs.GET;
25.37 +import javax.ws.rs.Path;
25.38 +import javax.ws.rs.PathParam;
25.39 +import javax.ws.rs.Produces;
25.40 +import javax.ws.rs.core.MediaType;
25.41 +
25.42 +/**
25.43 + *
25.44 + * @author Martin Rexa
25.45 + */
25.46 +public final class Elo {
25.47 + private EloList list;
25.48 +
25.49 + public Elo(){
25.50 + list = new EloList();
25.51 + }
25.52 +
25.53 + public void processGame(Game game){
25.54 + GameId gId = game.getId();
25.55 + GameStatus status = gId.getStatus();
25.56 + if(status.equals(GameStatus.whiteWon)){
25.57 + list.putResult(gId.getWhite(), gId.getBlack());
25.58 + }else if(status.equals(GameStatus.blackWon)){
25.59 + list.putResult(gId.getBlack(), gId.getWhite());
25.60 + }
25.61 + }
25.62 +
25.63 + @GET
25.64 + @Path("list")
25.65 + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
25.66 + public EloList getList(){
25.67 + return list;
25.68 + }
25.69 +
25.70 + @GET
25.71 + @Path("{username}")
25.72 + @Produces(MediaType.TEXT_PLAIN)
25.73 + public String getElo(@PathParam("username") String id){
25.74 + list.getElo(id);
25.75 + return Double.toString(list.getElo(id));
25.76 + }
25.77 +
25.78 +}
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
26.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/resources/Openings.java Thu Jan 07 22:34:17 2010 +0100
26.3 @@ -0,0 +1,107 @@
26.4 +/*
26.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
26.6 + *
26.7 + * The contents of this file are subject to the terms of either the GNU
26.8 + * General Public License Version 2 only ("GPL") or the Common
26.9 + * Development and Distribution License("CDDL") (collectively, the
26.10 + * "License"). You may not use this file except in compliance with the
26.11 + * License. You can obtain a copy of the License at
26.12 + * http://www.netbeans.org/cddl-gplv2.html
26.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
26.14 + * specific language governing permissions and limitations under the
26.15 + * License. When distributing the software, include this License Header
26.16 + * Notice in each file and include the License file at
26.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
26.18 + * particular file as subject to the "Classpath" exception as provided
26.19 + * by Sun in the GPL Version 2 section of the License file that
26.20 + * accompanied this code. If applicable, add the following below the
26.21 + * License Header, with the fields enclosed by brackets [] replaced by
26.22 + * your own identifying information:
26.23 + * "Portions Copyrighted [year] [name of copyright owner]"
26.24 + *
26.25 + * Contributor(s):
26.26 + *
26.27 + * Portions Copyrighted 2010 Martin Rexa
26.28 + */
26.29 +
26.30 +package cz.xelfi.quoridor.statistics.resources;
26.31 +
26.32 +import cz.xelfi.quoridor.IllegalPositionException;
26.33 +import cz.xelfi.quoridor.webidor.Game;
26.34 +import cz.xelfi.quoridor.webidor.GameId;
26.35 +import cz.xelfi.quoridor.statistics.OpeningTree;
26.36 +import cz.xelfi.quoridor.statistics.OpeningTreeNode;
26.37 +import cz.xelfi.quoridor.statistics.OpeningNodeView;
26.38 +import cz.xelfi.quoridor.webidor.GameStatus;
26.39 +import java.util.List;
26.40 +import javax.ws.rs.GET;
26.41 +import javax.ws.rs.Path;
26.42 +import javax.ws.rs.PathParam;
26.43 +import javax.ws.rs.Produces;
26.44 +import javax.ws.rs.QueryParam;
26.45 +import javax.ws.rs.DefaultValue;
26.46 +import javax.ws.rs.core.MediaType;
26.47 +
26.48 +/**
26.49 + *
26.50 + * @author Martin Rexa
26.51 + */
26.52 +public class Openings {
26.53 + OpeningTree tree;
26.54 +
26.55 + public Openings(){
26.56 + tree = new OpeningTree();
26.57 + }
26.58 +
26.59 + public void processGame(Game game) {
26.60 + try{
26.61 + tree.processGame(game);
26.62 + }catch (IllegalPositionException e){
26.63 + e.printStackTrace();
26.64 + }
26.65 + }
26.66 +
26.67 + @GET
26.68 + @Path("{nodeId}")
26.69 + @Produces({ MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
26.70 + public OpeningNodeView getNode(@QueryParam("loginID") @DefaultValue("") String loginId,
26.71 + @PathParam("nodeId") String nodeId){
26.72 + OpeningTreeNode node = tree.getNode(nodeId);
26.73 + if(node == null)
26.74 + node = tree.getRoot();
26.75 + return node.getView(loginId);
26.76 + }
26.77 +
26.78 + @GET
26.79 + @Path("{nodeId}.check")
26.80 + @Produces({ MediaType.TEXT_PLAIN })
26.81 + public String checkNode(@QueryParam("loginID") @DefaultValue("") String loginId,
26.82 + @PathParam("nodeId") String nodeId){
26.83 + OpeningTreeNode node = tree.getNode(nodeId);
26.84 + if(node == null)
26.85 + return "";
26.86 + if(node.getView(loginId).isEmpty())
26.87 + return "";
26.88 + else
26.89 + return nodeId;
26.90 + }
26.91 +
26.92 + @GET
26.93 + @Path("{nodeId}/{status}")
26.94 + @Produces({MediaType.APPLICATION_JSON, MediaType.TEXT_XML })
26.95 + public List<GameId> listGames(
26.96 + @DefaultValue("") @QueryParam("loginID") String loginId,
26.97 + @PathParam("nodeId") String nodeId,
26.98 + @DefaultValue("") @PathParam("status") String status
26.99 + ) {
26.100 + OpeningTreeNode node = tree.getNode(nodeId);
26.101 + if(node == null)
26.102 + return null;
26.103 + if("white".equals(status))
26.104 + return node.filterGames(loginId, GameStatus.whiteWon);
26.105 + else if("black".equals(status))
26.106 + return node.filterGames(loginId, GameStatus.blackWon);
26.107 + else
26.108 + return null;
26.109 + }
26.110 +}
27.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
27.2 +++ b/statistics/src/main/java/cz/xelfi/quoridor/statistics/resources/Statistics.java Thu Jan 07 22:34:17 2010 +0100
27.3 @@ -0,0 +1,156 @@
27.4 +/*
27.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
27.6 + *
27.7 + * The contents of this file are subject to the terms of either the GNU
27.8 + * General Public License Version 2 only ("GPL") or the Common
27.9 + * Development and Distribution License("CDDL") (collectively, the
27.10 + * "License"). You may not use this file except in compliance with the
27.11 + * License. You can obtain a copy of the License at
27.12 + * http://www.netbeans.org/cddl-gplv2.html
27.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
27.14 + * specific language governing permissions and limitations under the
27.15 + * License. When distributing the software, include this License Header
27.16 + * Notice in each file and include the License file at
27.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
27.18 + * particular file as subject to the "Classpath" exception as provided
27.19 + * by Sun in the GPL Version 2 section of the License file that
27.20 + * accompanied this code. If applicable, add the following below the
27.21 + * License Header, with the fields enclosed by brackets [] replaced by
27.22 + * your own identifying information:
27.23 + * "Portions Copyrighted [year] [name of copyright owner]"
27.24 + *
27.25 + * Contributor(s):
27.26 + *
27.27 + * Portions Copyrighted 2010 Martin Rexa
27.28 + */
27.29 +
27.30 +package cz.xelfi.quoridor.statistics.resources;
27.31 +
27.32 +import com.sun.jersey.api.container.httpserver.HttpServerFactory;
27.33 +import com.sun.jersey.api.core.PackagesResourceConfig;
27.34 +import com.sun.jersey.api.core.ResourceConfig;
27.35 +import com.sun.jersey.spi.resource.Singleton;
27.36 +import com.sun.net.httpserver.HttpServer;
27.37 +import java.io.File;
27.38 +import java.io.IOException;
27.39 +import java.util.Comparator;
27.40 +import java.util.List;
27.41 +import java.util.Collections;
27.42 +import java.net.ServerSocket;
27.43 +import javax.ws.rs.Path;
27.44 +import cz.xelfi.quoridor.webidor.resources.Games;
27.45 +import cz.xelfi.quoridor.webidor.Game;
27.46 +
27.47 +/**
27.48 + *
27.49 + * @author Martin Rexa
27.50 + */
27.51 +@Path("/")
27.52 +@Singleton
27.53 +public class Statistics {
27.54 + static final Comparator<Game> OLDEST_FIRST = new OldestFirst();
27.55 + static Elo elo;
27.56 + static Openings openings;
27.57 +
27.58 + @Path("elo")
27.59 + public Elo getElo() {
27.60 + return elo;
27.61 + }
27.62 +
27.63 + @Path("openings")
27.64 + public Openings getOpenings() {
27.65 + return openings;
27.66 + }
27.67 +
27.68 + public static void main( String[] args ) throws IOException, InterruptedException
27.69 + {
27.70 + int port = 9444;
27.71 + // timeout between reprocessing games in miliseconds
27.72 +// long timeout = 1000 * 60 * 60;
27.73 + long timeout = 1000 * 10;
27.74 +
27.75 + try {
27.76 + port = Integer.parseInt(args[0]);
27.77 + } catch (Exception ex) {
27.78 + // OK
27.79 + }
27.80 +
27.81 + if (System.getProperty("quoridor.dir") == null) {
27.82 + File home = new File(System.getProperty("user.home"));
27.83 + File quoridor = new File(home, ".quoridor");
27.84 + System.setProperty("quoridor.dir", quoridor.getPath());
27.85 + }
27.86 +
27.87 + processGames();
27.88 + HttpServer s = start(port);
27.89 + System.out.println("Statistics started at port " + port);
27.90 + Object monitor = new Object();
27.91 + for(;;){
27.92 + synchronized (monitor) {
27.93 + monitor.wait(timeout);
27.94 + }
27.95 + processGames();
27.96 + }
27.97 + }
27.98 +
27.99 + public static HttpServer start(int port) throws IOException {
27.100 + if (port == -1) {
27.101 + ServerSocket ss = new ServerSocket(0);
27.102 + port =ss.getLocalPort();
27.103 + ss.close();
27.104 + }
27.105 + final String baseUri = "http://localhost:" + port + "/";
27.106 +
27.107 + if (System.getProperty("quoridor.dir") == null) {
27.108 + File home = new File(System.getProperty("user.home"));
27.109 + File quoridor = new File(home, ".quoridor");
27.110 + System.setProperty("quoridor.dir", quoridor.getPath());
27.111 + }
27.112 +
27.113 + ResourceConfig rc = new PackagesResourceConfig("cz.xelfi.quoridor.statistics");
27.114 + HttpServer server = HttpServerFactory.create(baseUri, rc);
27.115 + server.start();
27.116 + return server;
27.117 + }
27.118 +
27.119 + public static void processGames(){
27.120 + Elo eloTmp = new Elo();
27.121 + Openings openingsTmp = new Openings();
27.122 +
27.123 + final String prop = System.getProperty("quoridor.dir"); // NOI18N
27.124 + if (prop == null) {
27.125 + throw new IllegalStateException("quoridor.dir property must be specified"); // NOI18N
27.126 + }
27.127 + File path = new File(prop);
27.128 + path.mkdirs();
27.129 + File fGames = new File(path, "games");
27.130 + //fGames.mkdirs();
27.131 + Games games = new Games(fGames, null);
27.132 + List<Game> lGames = games.getGames();
27.133 + Collections.sort(lGames, OLDEST_FIRST);
27.134 +
27.135 + // process games
27.136 + for(Game g: lGames){
27.137 + if(g.getId().isFinished()){
27.138 + eloTmp.processGame(g);
27.139 + openingsTmp.processGame(g);
27.140 + }
27.141 + }
27.142 +
27.143 + elo = eloTmp;
27.144 + openings = openingsTmp;
27.145 + }
27.146 +
27.147 + private static final class OldestFirst implements Comparator<Game> {
27.148 + public int compare(Game g1, Game g2) {
27.149 + if(g1.getId() == g2.getId())
27.150 + return 0;
27.151 + long diff = g2.getId().getModified() - g1.getId().getModified();
27.152 + if (diff != 0) {
27.153 + return diff < 0 ? -1 : 1;
27.154 + }
27.155 + return g1.getId().getId().compareTo(g2.getId().getId());
27.156 + }
27.157 + }
27.158 +
27.159 +}
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/statistics/src/test/java/cz/xelfi/quoridor/statistics/EloTest.java Thu Jan 07 22:34:17 2010 +0100
28.3 @@ -0,0 +1,53 @@
28.4 +/*
28.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
28.6 + *
28.7 + * The contents of this file are subject to the terms of either the GNU
28.8 + * General Public License Version 2 only ("GPL") or the Common
28.9 + * Development and Distribution License("CDDL") (collectively, the
28.10 + * "License"). You may not use this file except in compliance with the
28.11 + * License. You can obtain a copy of the License at
28.12 + * http://www.netbeans.org/cddl-gplv2.html
28.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
28.14 + * specific language governing permissions and limitations under the
28.15 + * License. When distributing the software, include this License Header
28.16 + * Notice in each file and include the License file at
28.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
28.18 + * particular file as subject to the "Classpath" exception as provided
28.19 + * by Sun in the GPL Version 2 section of the License file that
28.20 + * accompanied this code. If applicable, add the following below the
28.21 + * License Header, with the fields enclosed by brackets [] replaced by
28.22 + * your own identifying information:
28.23 + * "Portions Copyrighted [year] [name of copyright owner]"
28.24 + *
28.25 + * Contributor(s):
28.26 + *
28.27 + * Portions Copyrighted 2010 Martin Rexa
28.28 + */
28.29 +
28.30 +package cz.xelfi.quoridor.statistics;
28.31 +
28.32 +import org.junit.Test;
28.33 +import static org.junit.Assert.*;
28.34 +
28.35 +/**
28.36 + *
28.37 + * @author Martin Rexa
28.38 + */
28.39 +public class EloTest extends Object {
28.40 +
28.41 + public EloTest() throws Exception {
28.42 + }
28.43 +
28.44 + @Test public void testEloList() throws Exception {
28.45 + EloList eloList = new EloList();
28.46 + eloList.putResult("p1", "p2");
28.47 + assertFalse("empty list", eloList.getFinalList().isEmpty());
28.48 + eloList.putResult("p3", "p4");
28.49 + assertTrue("wrong list", eloList.getFinalList().get(0).getElo().equals(eloList.getFinalList().get(1).getElo()));
28.50 + eloList.putResult("p2", "p1");
28.51 + eloList.putResult("p2", "p1");
28.52 + eloList.putResult("p2", "p1");
28.53 + assertTrue("wrong list", eloList.getFinalList().get(0).player.equals("p2"));
28.54 + }
28.55 +
28.56 +}
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
29.2 +++ b/statistics/src/test/java/cz/xelfi/quoridor/statistics/OpeningsTest.java Thu Jan 07 22:34:17 2010 +0100
29.3 @@ -0,0 +1,129 @@
29.4 +/*
29.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
29.6 + *
29.7 + * The contents of this file are subject to the terms of either the GNU
29.8 + * General Public License Version 2 only ("GPL") or the Common
29.9 + * Development and Distribution License("CDDL") (collectively, the
29.10 + * "License"). You may not use this file except in compliance with the
29.11 + * License. You can obtain a copy of the License at
29.12 + * http://www.netbeans.org/cddl-gplv2.html
29.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
29.14 + * specific language governing permissions and limitations under the
29.15 + * License. When distributing the software, include this License Header
29.16 + * Notice in each file and include the License file at
29.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
29.18 + * particular file as subject to the "Classpath" exception as provided
29.19 + * by Sun in the GPL Version 2 section of the License file that
29.20 + * accompanied this code. If applicable, add the following below the
29.21 + * License Header, with the fields enclosed by brackets [] replaced by
29.22 + * your own identifying information:
29.23 + * "Portions Copyrighted [year] [name of copyright owner]"
29.24 + *
29.25 + * Contributor(s):
29.26 + *
29.27 + * Portions Copyrighted 2010 Martin Rexa
29.28 + */
29.29 +
29.30 +package cz.xelfi.quoridor.statistics;
29.31 +
29.32 +import cz.xelfi.quoridor.Fence.Orientation;
29.33 +import org.junit.Test;
29.34 +import static org.junit.Assert.*;
29.35 +import cz.xelfi.quoridor.Move;
29.36 +import cz.xelfi.quoridor.webidor.Game;
29.37 +import java.util.Map;
29.38 +
29.39 +/**
29.40 + *
29.41 + * @author Martin Rexa
29.42 + */
29.43 +public class OpeningsTest extends Object {
29.44 +
29.45 + public OpeningsTest() throws Exception {
29.46 + }
29.47 +
29.48 + @Test public void testMirrorMoves() throws Exception {
29.49 + assertEquals("bad symetric move", Move.NORTH.getMirrorMove(), Move.NORTH);
29.50 + assertEquals("bad symetric move", Move.SOUTH.getMirrorMove(), Move.SOUTH);
29.51 + assertEquals("bad symetric move", Move.WEST.getMirrorMove(), Move.EAST);
29.52 + assertEquals("bad symetric move", Move.EAST.getMirrorMove(), Move.WEST);
29.53 + assertEquals("bad symetric move", Move.fence('A', 1, Orientation.HORIZONTAL).getMirrorMove(), Move.fence('H', 1, Orientation.HORIZONTAL));
29.54 + assertEquals("bad symetric move", Move.fence('D', 3, Orientation.VERTICAL).getMirrorMove(), Move.fence('E', 3, Orientation.VERTICAL));
29.55 + }
29.56 +
29.57 + @Test public void testMirrorJump() throws Exception {
29.58 + Game g = new Game("w","b");
29.59 + g.apply("w", Move.NORTH, new java.util.Date());
29.60 + g.apply("b", Move.SOUTH, new java.util.Date());
29.61 + g.apply("w", Move.NORTH, new java.util.Date());
29.62 + g.apply("b", Move.SOUTH, new java.util.Date());
29.63 + g.apply("w", Move.NORTH, new java.util.Date());
29.64 + g.apply("b", Move.SOUTH, new java.util.Date());
29.65 + g.apply("w", Move.NORTH, new java.util.Date());
29.66 + g.apply("b", Move.EAST, new java.util.Date());
29.67 + g.apply("w", Move.NORTH, new java.util.Date());
29.68 + g.apply("b", Move.valueOf("WW"), new java.util.Date());
29.69 + g.apply("w", Move.RESIGN, new java.util.Date());
29.70 + OpeningTree t = new OpeningTree();
29.71 + t.processGame(g);
29.72 + OpeningTreeNode n = t.root;
29.73 + n = n.children.get(Move.NORTH);
29.74 + n = n.children.get(Move.SOUTH);
29.75 + n = n.children.get(Move.NORTH);
29.76 + n = n.children.get(Move.SOUTH);
29.77 + n = n.children.get(Move.NORTH);
29.78 + n = n.children.get(Move.SOUTH);
29.79 + n = n.children.get(Move.NORTH);
29.80 + n = n.children.get(Move.WEST);
29.81 + n = n.children.get(Move.NORTH);
29.82 + n = n.children.get(Move.valueOf("EE"));
29.83 + assertEquals("bad number of children", n.children.size(), 0);
29.84 + for(Map.Entry e: n.children.entrySet()){
29.85 + System.out.println(e.getKey());
29.86 + }
29.87 + }
29.88 +
29.89 + @Test public void testOpeningTreeNodes() throws Exception {
29.90 + OpeningTree t = new OpeningTree();
29.91 + assertEquals("bad number of nodes", t.nodes.size(), 1);
29.92 + Game g = new Game("w","b");
29.93 + g.apply("w", Move.NORTH, new java.util.Date());
29.94 + g.apply("b", Move.SOUTH, new java.util.Date());
29.95 + g.apply("w", Move.EAST, new java.util.Date());
29.96 + g.apply("b", Move.EAST, new java.util.Date());
29.97 + g.apply("w", Move.WEST, new java.util.Date());
29.98 + g.apply("b", Move.WEST, new java.util.Date());
29.99 + g.apply("w", Move.RESIGN, new java.util.Date());
29.100 + t.processGame(g);
29.101 + assertEquals("bad number of nodes", t.nodes.size(), 9);
29.102 + g = new Game("w","b");
29.103 + g.apply("w", Move.NORTH, new java.util.Date());
29.104 + g.apply("b", Move.SOUTH, new java.util.Date());
29.105 + g.apply("w", Move.fence('A', 1, Orientation.HORIZONTAL), new java.util.Date());
29.106 + g.apply("b", Move.fence('C', 1, Orientation.VERTICAL), new java.util.Date());
29.107 + g.apply("w", Move.RESIGN, new java.util.Date());
29.108 + t.processGame(g);
29.109 + assertEquals("bad number of nodes", t.nodes.size(), 13);
29.110 + g = new Game("w","b");
29.111 + g.apply("w", Move.NORTH, new java.util.Date());
29.112 + g.apply("b", Move.SOUTH, new java.util.Date());
29.113 + g.apply("w", Move.fence('C', 1, Orientation.VERTICAL), new java.util.Date());
29.114 + g.apply("b", Move.fence('A', 1, Orientation.HORIZONTAL), new java.util.Date());
29.115 + g.apply("w", Move.RESIGN, new java.util.Date());
29.116 + t.processGame(g);
29.117 + assertEquals("bad number of nodes", t.nodes.size(), 15);
29.118 + OpeningTreeNode n = t.root;
29.119 + n = n.children.get(Move.NORTH);
29.120 + n = n.children.get(Move.SOUTH);
29.121 + OpeningTreeNode n1 = n;
29.122 + n = n.children.get(Move.WEST);
29.123 + n = n.children.get(Move.WEST);
29.124 + n = n.children.get(Move.EAST);
29.125 + n = n.children.get(Move.EAST);
29.126 + assertEquals("different nodes", n.hashCode, n1.hashCode);
29.127 + n = n.children.get(Move.fence('F', 1, Orientation.VERTICAL));
29.128 + n = n.children.get(Move.fence('H', 1, Orientation.HORIZONTAL));
29.129 + assertEquals("bad number of children", n.children.size(), 0);
29.130 + }
29.131 +
29.132 +}
30.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
30.2 +++ b/statistics/src/test/java/cz/xelfi/quoridor/statistics/resources/StatisticsTest.java Thu Jan 07 22:34:17 2010 +0100
30.3 @@ -0,0 +1,131 @@
30.4 +/*
30.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
30.6 + *
30.7 + * The contents of this file are subject to the terms of either the GNU
30.8 + * General Public License Version 2 only ("GPL") or the Common
30.9 + * Development and Distribution License("CDDL") (collectively, the
30.10 + * "License"). You may not use this file except in compliance with the
30.11 + * License. You can obtain a copy of the License at
30.12 + * http://www.netbeans.org/cddl-gplv2.html
30.13 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
30.14 + * specific language governing permissions and limitations under the
30.15 + * License. When distributing the software, include this License Header
30.16 + * Notice in each file and include the License file at
30.17 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
30.18 + * particular file as subject to the "Classpath" exception as provided
30.19 + * by Sun in the GPL Version 2 section of the License file that
30.20 + * accompanied this code. If applicable, add the following below the
30.21 + * License Header, with the fields enclosed by brackets [] replaced by
30.22 + * your own identifying information:
30.23 + * "Portions Copyrighted [year] [name of copyright owner]"
30.24 + *
30.25 + * Contributor(s):
30.26 + *
30.27 + * Portions Copyrighted 2010 Martin Rexa
30.28 + */
30.29 +
30.30 +package cz.xelfi.quoridor.statistics.resources;
30.31 +
30.32 +import com.sun.jersey.api.client.Client;
30.33 +import com.sun.jersey.api.client.WebResource;
30.34 +import com.sun.jersey.core.header.MediaTypes;
30.35 +import com.sun.net.httpserver.HttpServer;
30.36 +import java.io.File;
30.37 +import java.io.FileOutputStream;
30.38 +import java.io.IOException;
30.39 +import java.net.URI;
30.40 +import java.util.Locale;
30.41 +import javax.ws.rs.core.MediaType;
30.42 +import org.junit.AfterClass;
30.43 +import org.junit.Before;
30.44 +import org.junit.BeforeClass;
30.45 +import org.junit.Test;
30.46 +import static org.junit.Assert.*;
30.47 +import cz.xelfi.quoridor.statistics.EloList;
30.48 +/**
30.49 + *
30.50 + * @author Martin Rexa
30.51 + */
30.52 +public class StatisticsTest {
30.53 + private static File dir;
30.54 + private static File fGames;
30.55 + private static HttpServer stopAPI;
30.56 + private WebResource apiResource;
30.57 +
30.58 + public StatisticsTest() throws Exception {
30.59 + }
30.60 +
30.61 + @BeforeClass
30.62 + public static void localeEnglish() throws Exception {
30.63 + Locale.setDefault(Locale.ENGLISH);
30.64 + dir = File.createTempFile("quoridor", ".dir");
30.65 + dir.delete();
30.66 + dir.mkdirs();
30.67 + fGames = new File(dir, "games");
30.68 + fGames.mkdirs();
30.69 +
30.70 + System.setProperty("quoridor.dir", dir.getPath());
30.71 + stopAPI = Statistics.start(9990);
30.72 +
30.73 + File passwd = new File(dir, "passwd");
30.74 + FileOutputStream os = new FileOutputStream(passwd);
30.75 + os.write("test=pes\nJarda=darda\n".getBytes("UTF-8"));
30.76 + os.close();
30.77 + }
30.78 +
30.79 + @Before
30.80 + public void setUp() throws Exception {
30.81 + Client client = new Client();
30.82 + apiResource = client.resource(new URI("http://localhost:9990/"));
30.83 + }
30.84 +
30.85 + @AfterClass
30.86 + public static void cleanUpAll() throws Exception {
30.87 + deleteRec(dir);
30.88 + if (stopAPI != null) {
30.89 + stopAPI.stop(0);
30.90 + }
30.91 + }
30.92 +
30.93 + static void deleteRec(File dir) throws IOException {
30.94 + if (dir == null) {
30.95 + return;
30.96 + }
30.97 + File[] arr = dir.listFiles();
30.98 + if (arr != null) {
30.99 + for (File f : arr) {
30.100 + deleteRec(f);
30.101 + }
30.102 + }
30.103 + dir.delete();
30.104 + }
30.105 +
30.106 + @Test public void testApplicationWadl() {
30.107 + String serviceWadl = apiResource.path("application.wadl").
30.108 + accept(MediaTypes.WADL).get(String.class);
30.109 + assertTrue(serviceWadl.length() > 0);
30.110 + }
30.111 +
30.112 + @Test public void testEloList() throws Exception {
30.113 + createFile(fGames, "g1", "# white: W\n# black: B\n# status: IN_PROGRESS\nN S\n\n");
30.114 + createFile(fGames, "g2", "# white: W\n# black: B\n# status: blackWon\nRESIGN\n\n");
30.115 + createFile(fGames, "g3", "# white: W\n# black: B\n# status: blackWon\nRESIGN\n\n");
30.116 + createFile(fGames, "g4", "# white: W\n# black: B\n# status: blackWon\nRESIGN\n\n");
30.117 + Statistics.processGames();
30.118 +
30.119 + EloList eloList = apiResource.path("elo").path("list").accept(MediaType.TEXT_XML).get(EloList.class);
30.120 +// assertFalse(eloList.getFinalList().isEmpty());
30.121 +// System.out.println("ELO LIST");
30.122 +// for (EloEntry entry : eloList.getFinalList()){
30.123 +// System.out.println(entry);
30.124 +// }
30.125 + }
30.126 +
30.127 + private void createFile(File dir, String filename, String content) throws Exception{
30.128 + File f = new File(dir, filename);
30.129 + FileOutputStream os = new FileOutputStream(f);
30.130 + os.write(content.getBytes("UTF-8"));
30.131 + os.close();
30.132 + }
30.133 +
30.134 +}
31.1 --- a/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java Fri Jan 01 20:53:17 2010 +0100
31.2 +++ b/visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java Thu Jan 07 22:34:17 2010 +0100
31.3 @@ -1,8 +1,28 @@
31.4 /*
31.5 - * To change this template, choose Tools | Templates
31.6 - * and open the template in the editor.
31.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
31.8 + *
31.9 + * The contents of this file are subject to the terms of either the GNU
31.10 + * General Public License Version 2 only ("GPL") or the Common
31.11 + * Development and Distribution License("CDDL") (collectively, the
31.12 + * "License"). You may not use this file except in compliance with the
31.13 + * License. You can obtain a copy of the License at
31.14 + * http://www.netbeans.org/cddl-gplv2.html
31.15 + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
31.16 + * specific language governing permissions and limitations under the
31.17 + * License. When distributing the software, include this License Header
31.18 + * Notice in each file and include the License file at
31.19 + * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
31.20 + * particular file as subject to the "Classpath" exception as provided
31.21 + * by Sun in the GPL Version 2 section of the License file that
31.22 + * accompanied this code. If applicable, add the following below the
31.23 + * License Header, with the fields enclosed by brackets [] replaced by
31.24 + * your own identifying information:
31.25 + * "Portions Copyrighted [year] [name of copyright owner]"
31.26 + *
31.27 + * Contributor(s):
31.28 + *
31.29 + * Portions Copyrighted 2009 Jaroslav Tulach
31.30 */
31.31 -
31.32 package cz.xelfi.quoridor.visidor;
31.33
31.34 import cz.xelfi.quoridor.Board;
32.1 --- a/webidor/pom.xml Fri Jan 01 20:53:17 2010 +0100
32.2 +++ b/webidor/pom.xml Thu Jan 07 22:34:17 2010 +0100
32.3 @@ -1,5 +1,7 @@
32.4 <?xml version="1.0" encoding="UTF-8"?>
32.5 -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
32.6 +<project xmlns="http://maven.apache.org/POM/4.0.0"
32.7 + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
32.8 + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
32.9 <modelVersion>4.0.0</modelVersion>
32.10 <parent>
32.11 <artifactId>all-quoridor</artifactId>
33.1 --- a/webidor/src/main/java/cz/xelfi/quoridor/webidor/Game.java Fri Jan 01 20:53:17 2010 +0100
33.2 +++ b/webidor/src/main/java/cz/xelfi/quoridor/webidor/Game.java Thu Jan 07 22:34:17 2010 +0100
33.3 @@ -82,10 +82,19 @@
33.4
33.5 @XmlAttribute
33.6 final String getCurrentPlayer() {
33.7 - if (board.getCurrentPlayer() == board.getPlayers().get(0)) {
33.8 - return id.getWhite();
33.9 - } else {
33.10 - return id.getBlack();
33.11 + Player w = board.getWinner();
33.12 + if(w==null){
33.13 + if (board.getCurrentPlayer() == board.getPlayers().get(0)) {
33.14 + return id.getWhite();
33.15 + } else {
33.16 + return id.getBlack();
33.17 + }
33.18 + }else{
33.19 + if (w == board.getPlayers().get(0)) {
33.20 + return id.getWhite();
33.21 + } else {
33.22 + return id.getBlack();
33.23 + }
33.24 }
33.25 }
33.26
33.27 @@ -191,11 +200,13 @@
33.28 @Override
33.29 public Board unmarshal(String v) throws Exception {
33.30 return v == null ? null : Board.valueOf(v);
33.31 +// return v == null ? null : new Board(v);
33.32 }
33.33
33.34 @Override
33.35 public String marshal(Board v) throws Exception {
33.36 return v == null ? null : v.toString();
33.37 +// return v == null ? null : Board.board2HashCode(v);
33.38 }
33.39
33.40 }
34.1 --- a/webidor/src/main/java/cz/xelfi/quoridor/webidor/User.java Fri Jan 01 20:53:17 2010 +0100
34.2 +++ b/webidor/src/main/java/cz/xelfi/quoridor/webidor/User.java Thu Jan 07 22:34:17 2010 +0100
34.3 @@ -90,6 +90,23 @@
34.4 return permissions.contains(permission);
34.5 }
34.6
34.7 + public static boolean canSee(GameId gId, String userId) {
34.8 + if (!gId.isFinished()) {
34.9 + return true;
34.10 + }
34.11 + if (userId.equals(gId.getWhite())) {
34.12 + return true;
34.13 + }
34.14 + if (userId.equals(gId.getBlack())) {
34.15 + return true;
34.16 + }
34.17 + return false;
34.18 + }
34.19 +
34.20 + public boolean canSee(GameId gId){
34.21 + return canSee(gId, id);
34.22 + }
34.23 +
34.24 public String getId() {
34.25 return id;
34.26 }
35.1 --- a/webidor/src/test/java/cz/xelfi/quoridor/webidor/FinishedGameTest.java Fri Jan 01 20:53:17 2010 +0100
35.2 +++ b/webidor/src/test/java/cz/xelfi/quoridor/webidor/FinishedGameTest.java Thu Jan 07 22:34:17 2010 +0100
35.3 @@ -184,4 +184,45 @@
35.4 assertFalse("is finished", end.getId().getStatus().isInProgress());
35.5 }
35.6
35.7 + @Test public void testResignBGame() throws Exception {
35.8 + String logJarda = webResource.path("login").
35.9 + queryParam("name", "Jarda").
35.10 + queryParam("password", "heslo").
35.11 + accept(MediaType.TEXT_PLAIN).
35.12 + put(String.class);
35.13 + String logJirka = webResource.path("login").
35.14 + queryParam("name", "Jirka").
35.15 + queryParam("password", "pesko").
35.16 + accept(MediaType.TEXT_PLAIN).
35.17 + put(String.class);
35.18 +
35.19 + GameId s = webResource.path("games").queryParam("white", "Jarda")
35.20 + .queryParam("loginID", logJarda)
35.21 + .queryParam("black", "Jirka").post(GameId.class);
35.22 +
35.23 + assertTrue("In progress", s.getStatus().isInProgress());
35.24 +
35.25 + webResource.path("games/" + s.getId()).
35.26 + queryParam("loginID", logJarda).
35.27 + queryParam("player", "Jarda").
35.28 + queryParam("move", "N").put(GameId.class);
35.29 + webResource.path("games/" + s.getId()).
35.30 + queryParam("loginID", logJirka).
35.31 + queryParam("player", "Jirka").
35.32 + queryParam("move", "RESIGN").put(GameId.class);
35.33 +
35.34 +
35.35 + try {
35.36 + Game end = webResource.path("games/" + s.getId()).accept(MediaType.TEXT_XML).get(Game.class);
35.37 + fail("Should not be able to get game when finished");
35.38 + } catch (UniformInterfaceException ex) {
35.39 + // OK
35.40 + }
35.41 + Game end = webResource.path("games/" + s.getId()).queryParam("loginID", logJarda).accept(MediaType.TEXT_XML).get(Game.class);
35.42 + assertEquals("WhiteWins", GameStatus.whiteWon, end.getId().getStatus());
35.43 + assertEquals("Jarda wins", "Jarda", end.getCurrentPlayer());
35.44 +
35.45 + assertFalse("is finished", end.getId().getStatus().isInProgress());
35.46 + }
35.47 +
35.48 }
36.1 --- a/webidor/src/test/java/cz/xelfi/quoridor/webidor/QuoridorTest.java Fri Jan 01 20:53:17 2010 +0100
36.2 +++ b/webidor/src/test/java/cz/xelfi/quoridor/webidor/QuoridorTest.java Thu Jan 07 22:34:17 2010 +0100
36.3 @@ -201,14 +201,17 @@
36.4
36.5 class GMap extends GenericType<Map<String,Object>>{}
36.6 String text = webResource.path("games").path(s.getId()).accept(MediaType.TEXT_PLAIN).get(String.class);
36.7 + text = (new Board(text)).boardToPicture();
36.8 if (text.indexOf("-----") == -1) {
36.9 fail("Expecting board:\n" + text);
36.10 }
36.11 Game readGame = webResource.path("games").path(s.getId()).accept(MediaType.TEXT_XML).get(Game.class);
36.12 String sGame = webResource.path("games").path(s.getId()).accept(MediaType.TEXT_XML).get(String.class);
36.13 assertNotNull("Game really returned", readGame);
36.14 - assertEquals("Same game as in text representation", readGame.getBoard(), Board.valueOf(text));
36.15 - assertEquals("It is same as text of our game", readGame.getBoard().toString(), text);
36.16 +// assertEquals("Same game as in text representation", readGame.getBoard(), Board.valueOf(text));
36.17 + assertEquals("Same game as in text representation", readGame.getBoard(), Board.picture2board(text));
36.18 +// assertEquals("It is same as text of our game", readGame.getBoard().toString(), text);
36.19 + assertEquals("It is same as text of our game", readGame.getBoard().boardToPicture(), text);
36.20
36.21 assertEquals(Move.NORTH, readGame.getMoves().get(0).getMove());
36.22 assertEquals(Move.SOUTH, readGame.getMoves().get(1).getMove());