1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/chess/nbactions-bck2brwsr.xml Tue Sep 24 22:20:24 2013 +0200
1.3 @@ -0,0 +1,39 @@
1.4 +<?xml version="1.0" encoding="UTF-8"?>
1.5 +<!--
1.6 +
1.7 + The MIT License (MIT)
1.8 +
1.9 + Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
1.10 +
1.11 + Permission is hereby granted, free of charge, to any person obtaining a copy
1.12 + of this software and associated documentation files (the "Software"), to deal
1.13 + in the Software without restriction, including without limitation the rights
1.14 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1.15 + copies of the Software, and to permit persons to whom the Software is
1.16 + furnished to do so, subject to the following conditions:
1.17 +
1.18 + The above copyright notice and this permission notice shall be included in
1.19 + all copies or substantial portions of the Software.
1.20 +
1.21 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1.22 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1.23 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1.24 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1.25 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1.26 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
1.27 + THE SOFTWARE.
1.28 +
1.29 +-->
1.30 +<actions>
1.31 + <action>
1.32 + <actionName>run</actionName>
1.33 + <goals>
1.34 + <goal>package</goal>
1.35 + <goal>bck2brwsr:brwsr</goal>
1.36 + </goals>
1.37 + <properties>
1.38 + <skipTests>true</skipTests>
1.39 + <bck2brwsr.obfuscationlevel>NONE</bck2brwsr.obfuscationlevel>
1.40 + </properties>
1.41 + </action>
1.42 +</actions>
2.1 --- a/chess/nbactions-iOSDeploy.xml Tue Sep 24 21:08:15 2013 +0200
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,51 +0,0 @@
2.4 -<?xml version="1.0" encoding="UTF-8"?>
2.5 -<!--
2.6 -
2.7 - The MIT License (MIT)
2.8 -
2.9 - Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.10 -
2.11 - Permission is hereby granted, free of charge, to any person obtaining a copy
2.12 - of this software and associated documentation files (the "Software"), to deal
2.13 - in the Software without restriction, including without limitation the rights
2.14 - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2.15 - copies of the Software, and to permit persons to whom the Software is
2.16 - furnished to do so, subject to the following conditions:
2.17 -
2.18 - The above copyright notice and this permission notice shall be included in
2.19 - all copies or substantial portions of the Software.
2.20 -
2.21 - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2.22 - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2.23 - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2.24 - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2.25 - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2.26 - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2.27 - THE SOFTWARE.
2.28 -
2.29 --->
2.30 -<actions>
2.31 - <action>
2.32 - <actionName>run</actionName>
2.33 - <goals>
2.34 - <goal>package</goal>
2.35 - <goal>ios-maven-plugin:0.2:deploy</goal>
2.36 - </goals>
2.37 - <properties>
2.38 - <skipTests>true</skipTests>
2.39 - </properties>
2.40 - </action>
2.41 - <action>
2.42 - <actionName>debug</actionName>
2.43 - <goals>
2.44 - <goal>package</goal>
2.45 - <goal>org.netbeans.ios:ios-maven-plugin:0.2:deploy</goal>
2.46 - </goals>
2.47 - <properties>
2.48 - <skipTests>true</skipTests>
2.49 - <jpda.listen>true</jpda.listen>
2.50 - <jpdaAddress>${jpda.address}</jpdaAddress>
2.51 - <runMode>Debug</runMode>
2.52 - </properties>
2.53 - </action>
2.54 -</actions>
2.55 \ No newline at end of file
3.1 --- a/chess/nbactions.xml Tue Sep 24 21:08:15 2013 +0200
3.2 +++ b/chess/nbactions.xml Tue Sep 24 22:20:24 2013 +0200
3.3 @@ -47,7 +47,7 @@
3.4 <displayName>Build IPA</displayName>
3.5 <goals>
3.6 <goal>package</goal>
3.7 - <goal>org.netbeans.ios:ios-maven-plugin:0.2-SNAPSHOT:build-IPA</goal>
3.8 + <goal>ios:build-IPA</goal>
3.9 </goals>
3.10 <properties>
3.11 <skipTests>true</skipTests>
3.12 @@ -60,8 +60,8 @@
3.13 <displayName>Debug IPA</displayName>
3.14 <goals>
3.15 <goal>package</goal>
3.16 - <goal>org.netbeans.ios:ios-maven-plugin:0.2-SNAPSHOT:ipaddress</goal>
3.17 - <goal>org.netbeans.ios:ios-maven-plugin:0.2-SNAPSHOT:build-IPA</goal>
3.18 + <goal>ios:ipaddress</goal>
3.19 + <goal>ios:build-IPA</goal>
3.20 </goals>
3.21 <properties>
3.22 <skipTests>true</skipTests>
4.1 --- a/chess/pom.xml Tue Sep 24 21:08:15 2013 +0200
4.2 +++ b/chess/pom.xml Tue Sep 24 22:20:24 2013 +0200
4.3 @@ -1,28 +1,21 @@
4.4 <?xml version="1.0" encoding="UTF-8"?>
4.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/xsd/maven-4.0.0.xsd">
4.6 <modelVersion>4.0.0</modelVersion>
4.7 - <parent>
4.8 + <parent>
4.9 <artifactId>demo</artifactId>
4.10 <groupId>org.apidesign.html</groupId>
4.11 - <version>1.0-SNAPSHOT</version>
4.12 - </parent>
4.13 + <version>1.0-SNAPSHOT</version>
4.14 + </parent>
4.15
4.16 - <groupId>org.apidesign.html.demo</groupId>
4.17 - <artifactId>chess</artifactId>
4.18 + <groupId>com.oracle.chess</groupId>
4.19 + <artifactId>ChessHTMLJavaClient</artifactId>
4.20 <version>1.0-SNAPSHOT</version>
4.21 <packaging>jar</packaging>
4.22
4.23 - <name>ChessGame</name>
4.24 + <name>Chess_HTML_Java_Client</name>
4.25
4.26 <repositories>
4.27 <repository>
4.28 - <id>java.net</id>
4.29 - <name>Java.net</name>
4.30 - <url>https://maven.java.net/content/repositories/releases/</url>
4.31 - <snapshots>
4.32 - </snapshots>
4.33 - </repository>
4.34 - <repository>
4.35 <id>netbeans</id>
4.36 <name>NetBeans</name>
4.37 <url>http://bits.netbeans.org/maven2/</url>
4.38 @@ -30,13 +23,6 @@
4.39 </repositories>
4.40 <pluginRepositories>
4.41 <pluginRepository>
4.42 - <id>java.net</id>
4.43 - <name>Java.net</name>
4.44 - <url>https://maven.java.net/content/repositories/releases/</url>
4.45 - <snapshots>
4.46 - </snapshots>
4.47 - </pluginRepository>
4.48 - <pluginRepository>
4.49 <id>ios</id>
4.50 <name>NetBeans iOS Maven Plugin</name>
4.51 <url>http://beetle.cz.oracle.com/~jtulach/maven/</url>
4.52 @@ -47,8 +33,12 @@
4.53
4.54 <properties>
4.55 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
4.56 - <net.java.html.version>0.4</net.java.html.version>
4.57 <netbeans.compile.on.save>none</netbeans.compile.on.save>
4.58 + <net.java.html.version>0.6</net.java.html.version>
4.59 + <bck2brwsr.version>0.8</bck2brwsr.version>
4.60 + <bck2brwsr.launcher.version>0.8</bck2brwsr.launcher.version>
4.61 + <bck2brwsr.obfuscationlevel>MINIMAL</bck2brwsr.obfuscationlevel>
4.62 + <brwsr.startpage>pages/index.html</brwsr.startpage>
4.63 </properties>
4.64 <build>
4.65 <plugins>
4.66 @@ -68,7 +58,7 @@
4.67 <configuration>
4.68 <archive>
4.69 <manifest>
4.70 - <mainClass>org.apidesign.html.demo.chess.Main</mainClass>
4.71 + <mainClass>com.oracle.chess.client.htmljava.Main</mainClass>
4.72 <addClasspath>true</addClasspath>
4.73 <classpathPrefix>lib/</classpathPrefix>
4.74 </manifest>
4.75 @@ -86,7 +76,7 @@
4.76 <value>${basedir}/src/main/webapp/</value>
4.77 </systemProperty>
4.78 </systemProperties>
4.79 - <mainClass>org.apidesign.html.demo.chess.Main</mainClass>
4.80 + <mainClass>com.oracle.chess.client.htmljava.Main</mainClass>
4.81 </configuration>
4.82 </plugin>
4.83 <plugin>
4.84 @@ -106,7 +96,21 @@
4.85 </configuration>
4.86 </execution>
4.87 </executions>
4.88 - </plugin>
4.89 + </plugin>
4.90 + <plugin>
4.91 + <artifactId>ios-maven-plugin</artifactId>
4.92 + <groupId>org.netbeans.ios</groupId>
4.93 + <version>0.4</version>
4.94 + <configuration>
4.95 + <targetDevices>1</targetDevices>
4.96 + <deploymentTarget>6.1</deploymentTarget>
4.97 + <bundleId>JavaOneChess</bundleId>
4.98 + <provisioningProfile></provisioningProfile>
4.99 + <supportedInterfaceOrientations>UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationPortrait,UIInterfaceOrientationLandscapeRight,UIInterfaceOrientationPortraitUpsideDown</supportedInterfaceOrientations>
4.100 + <prerenderedIcons>false</prerenderedIcons>
4.101 + <iPadSupportedInterfaceOrientations>UIInterfaceOrientationLandscapeLeft,UIInterfaceOrientationPortrait,UIInterfaceOrientationLandscapeRight,UIInterfaceOrientationPortraitUpsideDown</iPadSupportedInterfaceOrientations>
4.102 + </configuration>
4.103 + </plugin>
4.104 </plugins>
4.105 </build>
4.106 <dependencies>
4.107 @@ -121,66 +125,132 @@
4.108 <version>${net.java.html.version}</version>
4.109 </dependency>
4.110 <dependency>
4.111 - <groupId>org.apidesign.html</groupId>
4.112 - <artifactId>ko-fx</artifactId>
4.113 - <version>${net.java.html.version}</version>
4.114 - <scope>runtime</scope>
4.115 - </dependency>
4.116 - <dependency>
4.117 - <groupId>org.apidesign.html</groupId>
4.118 - <artifactId>boot-fx</artifactId>
4.119 - <version>${net.java.html.version}</version>
4.120 - <scope>runtime</scope>
4.121 - </dependency>
4.122 - <dependency>
4.123 <groupId>org.testng</groupId>
4.124 <artifactId>testng</artifactId>
4.125 <version>6.7</version>
4.126 <scope>test</scope>
4.127 </dependency>
4.128 + <dependency>
4.129 + <groupId>org.apidesign.html</groupId>
4.130 + <artifactId>net.java.html.sound</artifactId>
4.131 + <version>${net.java.html.version}</version>
4.132 + <type>jar</type>
4.133 + </dependency>
4.134 + <dependency>
4.135 + <groupId>org.apidesign.bck2brwsr</groupId>
4.136 + <artifactId>core</artifactId>
4.137 + <version>${bck2brwsr.version}</version>
4.138 + <scope>provided</scope>
4.139 + <type>jar</type>
4.140 + </dependency>
4.141 </dependencies>
4.142 <profiles>
4.143 <profile>
4.144 - <id>iOSDeploy</id>
4.145 + <id>fxbrwsr</id>
4.146 <activation>
4.147 - <os>
4.148 - <name>Mac OS X</name>
4.149 - </os>
4.150 + <activeByDefault>true</activeByDefault>
4.151 </activation>
4.152 - <build>
4.153 - <plugins>
4.154 - <plugin>
4.155 - <groupId>org.netbeans.ios</groupId>
4.156 - <artifactId>ios-maven-plugin</artifactId>
4.157 - <version>0.2</version>
4.158 - <configuration>
4.159 - <jarfile>${project.build.directory}/${project.build.finalName}.jar</jarfile>
4.160 - <title>${project.name}</title>
4.161 - <mainclass>org.apidesign.html.demo.chess.Main</mainclass>
4.162 - <resourcesDir>src/main/webapp/</resourcesDir>
4.163 - </configuration>
4.164 - </plugin>
4.165 - <plugin>
4.166 - <groupId>org.apache.maven.plugins</groupId>
4.167 - <artifactId>maven-jar-plugin</artifactId>
4.168 - <version>2.4</version>
4.169 - <configuration>
4.170 - <archive>
4.171 - <manifest>
4.172 - <mainClass>org.apidesign.html.demo.chess.Main</mainClass>
4.173 - <addClasspath>true</addClasspath>
4.174 - <classpathPrefix>lib/</classpathPrefix>
4.175 - </manifest>
4.176 - </archive>
4.177 - </configuration>
4.178 - </plugin>
4.179 - </plugins>
4.180 - </build>
4.181 <dependencies>
4.182 <dependency>
4.183 <groupId>org.apidesign.html</groupId>
4.184 <artifactId>ko-fx</artifactId>
4.185 <version>${net.java.html.version}</version>
4.186 + <scope>runtime</scope>
4.187 + </dependency>
4.188 + <dependency>
4.189 + <groupId>org.apidesign.html</groupId>
4.190 + <artifactId>boot-fx</artifactId>
4.191 + <version>${net.java.html.version}</version>
4.192 + <scope>runtime</scope>
4.193 + </dependency>
4.194 + <dependency>
4.195 + <groupId>org.apidesign.html</groupId>
4.196 + <artifactId>ko-ws-tyrus</artifactId>
4.197 + <scope>runtime</scope>
4.198 + <version>${net.java.html.version}</version>
4.199 + </dependency>
4.200 + </dependencies>
4.201 + </profile>
4.202 + <profile>
4.203 + <id>bck2brwsr</id>
4.204 + <activation>
4.205 + <property>
4.206 + <name>brwsr</name>
4.207 + <value>bck2brwsr</value>
4.208 + </property>
4.209 + </activation>
4.210 + <build>
4.211 + <plugins>
4.212 + <plugin>
4.213 + <groupId>org.apidesign.bck2brwsr</groupId>
4.214 + <artifactId>bck2brwsr-maven-plugin</artifactId>
4.215 + <version>${bck2brwsr.launcher.version}</version>
4.216 + <executions>
4.217 + <execution>
4.218 + <goals>
4.219 + <goal>brwsr</goal>
4.220 + </goals>
4.221 + </execution>
4.222 + </executions>
4.223 + <configuration>
4.224 + <directory>${basedir}/src/main/webapp/</directory>
4.225 + <startpage>${brwsr.startpage}</startpage>
4.226 + <launcher>${brwsr}</launcher>
4.227 + <javascript>${project.build.directory}/bck2brwsr.js</javascript>
4.228 + <obfuscation>${bck2brwsr.obfuscationlevel}</obfuscation>
4.229 + </configuration>
4.230 + </plugin>
4.231 + <plugin>
4.232 + <groupId>org.apache.maven.plugins</groupId>
4.233 + <artifactId>maven-compiler-plugin</artifactId>
4.234 + <configuration>
4.235 + <compilerArguments>
4.236 + <!--
4.237 + <bootclasspath>netbeans.ignore.jdk.bootclasspath</bootclasspath>
4.238 + -->
4.239 + </compilerArguments>
4.240 + </configuration>
4.241 + </plugin>
4.242 + <plugin>
4.243 + <artifactId>maven-assembly-plugin</artifactId>
4.244 + <version>2.4</version>
4.245 + <executions>
4.246 + <execution>
4.247 + <id>distro-assembly</id>
4.248 + <phase>package</phase>
4.249 + <goals>
4.250 + <goal>single</goal>
4.251 + </goals>
4.252 + <configuration>
4.253 + <descriptors>
4.254 + <descriptor>src/main/assembly/bck2brwsr.xml</descriptor>
4.255 + </descriptors>
4.256 + </configuration>
4.257 + </execution>
4.258 + </executions>
4.259 + </plugin>
4.260 + </plugins>
4.261 + </build>
4.262 + <dependencies>
4.263 + <dependency>
4.264 + <groupId>org.apidesign.bck2brwsr</groupId>
4.265 + <artifactId>emul</artifactId>
4.266 + <version>${bck2brwsr.version}</version>
4.267 + <classifier>rt</classifier>
4.268 + </dependency>
4.269 + <dependency>
4.270 + <groupId>org.apidesign.bck2brwsr</groupId>
4.271 + <artifactId>ko-bck2brwsr</artifactId>
4.272 + <version>${bck2brwsr.version}</version>
4.273 + <scope>runtime</scope>
4.274 + </dependency>
4.275 + <dependency>
4.276 + <groupId>org.apidesign.bck2brwsr</groupId>
4.277 + <artifactId>vm4brwsr</artifactId>
4.278 + <classifier>js</classifier>
4.279 + <type>zip</type>
4.280 + <version>${bck2brwsr.version}</version>
4.281 + <scope>provided</scope>
4.282 </dependency>
4.283 </dependencies>
4.284 </profile>
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/chess/src/main/assembly/bck2brwsr.xml Tue Sep 24 22:20:24 2013 +0200
5.3 @@ -0,0 +1,79 @@
5.4 +<?xml version="1.0"?>
5.5 +<!--
5.6 +
5.7 + The MIT License (MIT)
5.8 +
5.9 + Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
5.10 +
5.11 + Permission is hereby granted, free of charge, to any person obtaining a copy
5.12 + of this software and associated documentation files (the "Software"), to deal
5.13 + in the Software without restriction, including without limitation the rights
5.14 + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5.15 + copies of the Software, and to permit persons to whom the Software is
5.16 + furnished to do so, subject to the following conditions:
5.17 +
5.18 + The above copyright notice and this permission notice shall be included in
5.19 + all copies or substantial portions of the Software.
5.20 +
5.21 + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5.22 + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5.23 + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5.24 + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5.25 + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5.26 + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5.27 + THE SOFTWARE.
5.28 +
5.29 +-->
5.30 +<assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5.31 + xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
5.32 +
5.33 + <id>bck2brwsr</id>
5.34 + <formats>
5.35 + <format>zip</format>
5.36 + </formats>
5.37 + <baseDirectory>public_html</baseDirectory>
5.38 + <dependencySets>
5.39 + <dependencySet>
5.40 + <useProjectArtifact>false</useProjectArtifact>
5.41 + <scope>runtime</scope>
5.42 + <outputDirectory>lib</outputDirectory>
5.43 + <includes>
5.44 + <include>*:jar</include>
5.45 + <include>*:rt</include>
5.46 + </includes>
5.47 + </dependencySet>
5.48 + <dependencySet>
5.49 + <useProjectArtifact>false</useProjectArtifact>
5.50 + <scope>provided</scope>
5.51 + <includes>
5.52 + <include>*:js</include>
5.53 + </includes>
5.54 + <unpack>true</unpack>
5.55 + <outputDirectory>/</outputDirectory>
5.56 + </dependencySet>
5.57 + </dependencySets>
5.58 + <fileSets>
5.59 + <fileSet>
5.60 + <directory>src/main/webapp/pages</directory>
5.61 + <outputDirectory>/</outputDirectory>
5.62 + <excludes>
5.63 + <exclude>*.png</exclude>
5.64 + </excludes>
5.65 + <filtered>true</filtered>
5.66 + </fileSet>
5.67 + <fileSet>
5.68 + <directory>src/main/webapp/pages</directory>
5.69 + <outputDirectory>/</outputDirectory>
5.70 + <includes>
5.71 + <include>*.png</include>
5.72 + </includes>
5.73 + <filtered>false</filtered>
5.74 + </fileSet>
5.75 + </fileSets>
5.76 + <files>
5.77 + <file>
5.78 + <source>${project.build.directory}/${project.build.finalName}.jar</source>
5.79 + <outputDirectory>/</outputDirectory>
5.80 + </file>
5.81 + </files>
5.82 +</assembly>
5.83 \ No newline at end of file
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/BoardModel.java Tue Sep 24 22:20:24 2013 +0200
6.3 @@ -0,0 +1,451 @@
6.4 +/**
6.5 + * The MIT License (MIT)
6.6 + *
6.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
6.8 + *
6.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
6.10 + * of this software and associated documentation files (the "Software"), to deal
6.11 + * in the Software without restriction, including without limitation the rights
6.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6.13 + * copies of the Software, and to permit persons to whom the Software is
6.14 + * furnished to do so, subject to the following conditions:
6.15 + *
6.16 + * The above copyright notice and this permission notice shall be included in
6.17 + * all copies or substantial portions of the Software.
6.18 + *
6.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
6.25 + * THE SOFTWARE.
6.26 + */
6.27 +package com.oracle.chess.client.htmljava;
6.28 +
6.29 +import com.oracle.chess.client.htmljava.Communication.AlertType;
6.30 +import java.util.Arrays;
6.31 +import java.util.Collections;
6.32 +import java.util.List;
6.33 +import java.util.Timer;
6.34 +import java.util.TimerTask;
6.35 +import net.java.html.json.ComputedProperty;
6.36 +import net.java.html.json.Function;
6.37 +import net.java.html.json.Model;
6.38 +import net.java.html.json.ModelOperation;
6.39 +import net.java.html.json.OnPropertyChange;
6.40 +import net.java.html.json.Property;
6.41 +import net.java.html.sound.AudioClip;
6.42 +
6.43 +@Model(className="Board", properties={
6.44 + @Property(name = "player", type = String.class),
6.45 + @Property(name = "gameId", type = String.class),
6.46 + @Property(name = "whitePlayer", type = String.class),
6.47 + @Property(name = "blackPlayer", type = String.class),
6.48 + @Property(name = "alert", type = Alert.class),
6.49 + @Property(name = "alertMessage", type = String.class),
6.50 + @Property(name = "status", type = String.class),
6.51 + @Property(name = "rows", type = Row.class, array = true),
6.52 + @Property(name = "turn", type = Color.class),
6.53 + @Property(name = "moves", type = Move.class, array = true),
6.54 + @Property(name = "pendingMove", type = Move.class),
6.55 + @Property(name = "active", type = boolean.class),
6.56 +})
6.57 +public class BoardModel {
6.58 + @ComputedProperty static String title(String status, String gameId) {
6.59 + String t = status != null ? status : gameId;
6.60 + if (t != null && t.length() > 10) {
6.61 + return t.substring(0, 10);
6.62 + }
6.63 + return t;
6.64 + }
6.65 +
6.66 + @ModelOperation static void updateSummary(Board b, String summary) {
6.67 + if (summary != null) {
6.68 + b.setStatus(summary);
6.69 + }
6.70 + }
6.71 +
6.72 + @ComputedProperty static boolean myTurn(String player, String whitePlayer, String blackPlayer, Color turn) {
6.73 + if (turn != null && player != null) switch (turn) {
6.74 + case B: return player.equals(blackPlayer);
6.75 + case W: return player.equals(whitePlayer);
6.76 + }
6.77 + return false;
6.78 + }
6.79 +
6.80 + @ComputedProperty static boolean justObserving(String player) {
6.81 + return player == null;
6.82 + }
6.83 +
6.84 + private static final AudioClip MOVE = AudioClip.create("sounds/move.mp3");
6.85 + @OnPropertyChange("moves") static void playMove() {
6.86 + MOVE.play();
6.87 + }
6.88 +
6.89 + private static final AudioClip CHECK = AudioClip.create("sounds/check.mp3");
6.90 + private static final AudioClip CHECKMATE = AudioClip.create("sounds/checkmate.mp3");
6.91 + @OnPropertyChange("alert") static void warnCheckAndMate(Board b) {
6.92 + if (b.getAlert() == null) {
6.93 + return;
6.94 + }
6.95 + if (b.getAlert().getType() == AlertType.CHECK) {
6.96 + CHECK.play();
6.97 + }
6.98 + if (b.getAlert().getType() == AlertType.CHECKMATE) {
6.99 + CHECKMATE.play();
6.100 + }
6.101 + }
6.102 +
6.103 + @Function static void selected(Board b, Square data) {
6.104 + if (!b.isMyTurn()) {
6.105 + b.setAlertMessage("Not your turn!");
6.106 + return;
6.107 + }
6.108 +
6.109 + Square previoslySelected = findSelectedSquare(b);
6.110 + if (previoslySelected == null) {
6.111 + if (data.getPiece() != null && data.getPieceColor() == b.getTurn()) {
6.112 + data.setSelected(true);
6.113 + Rules.computeAccessible(b, data);
6.114 + }
6.115 + } else {
6.116 + if (previoslySelected == data) {
6.117 + data.setSelected(false);
6.118 + Rules.computeAccessible(b, null);
6.119 + return;
6.120 + }
6.121 + if (data.getPiece() != null && data.getPieceColor() == previoslySelected.getPieceColor()) {
6.122 + previoslySelected.setSelected(false);
6.123 + data.setSelected(true);
6.124 + Rules.computeAccessible(b, data);
6.125 + return;
6.126 + }
6.127 + if (data.isAccessible()) {
6.128 + previoslySelected.setSelected(false);
6.129 +
6.130 + Move newMove = new Move();
6.131 + newMove.setFrom(previoslySelected.getPosition());
6.132 + newMove.setTo(data.getPosition());
6.133 + newMove.setRound(b.getMoves().size() / 2 + 1);
6.134 + newMove.setPiece(previoslySelected.getPiece());
6.135 + newMove.setTurn(previoslySelected.getPieceColor());
6.136 + newMove.setTakes(data.getPiece() != null);
6.137 + b.getMoves().add(newMove);
6.138 + b.setPendingMove(newMove);
6.139 +
6.140 + data.setPending(true);
6.141 + data.setPieceColor(previoslySelected.getPieceColor());
6.142 + data.setPiece(previoslySelected.getPiece());
6.143 + b.setTurn(null);
6.144 + previoslySelected.setPiece(null);
6.145 + previoslySelected.setPieceColor(null);
6.146 + Rules.computeAccessible(b, null);
6.147 +
6.148 + Request sm = new Request();
6.149 + sm.setMsg(MsgType.SendMove);
6.150 + sm.setGameId(b.getGameId());
6.151 + sm.setFrom(newMove.getFrom().getLocation());
6.152 + sm.setTo(newMove.getTo().getLocation());
6.153 + sm.setColor(newMove.getTurn());
6.154 + final UI ui = UIModel.findUI(b);
6.155 + if (ui != null) {
6.156 + ui.sendMsg(sm);
6.157 + }
6.158 + }
6.159 + }
6.160 + }
6.161 +
6.162 + static class NextMove extends TimerTask {
6.163 + private static final Timer T = new Timer("Animate moves");
6.164 + private final Board b;
6.165 + private final Move m;
6.166 +
6.167 + public NextMove(Board b, Move m) {
6.168 + this.b = b;
6.169 + this.m = m;
6.170 + T.schedule(this, 1000);
6.171 + }
6.172 +
6.173 +
6.174 + @Override
6.175 + public void run() {
6.176 + b.showPosition(m);
6.177 + }
6.178 + }
6.179 +
6.180 + @ModelOperation @Function static void showPosition(Board b, Move data) {
6.181 + Rules.initBoard(b);
6.182 + boolean found = false;
6.183 + for (Move m : b.getMoves()) {
6.184 + if (found) {
6.185 + b.setTurn(null);
6.186 + new NextMove(b, m);
6.187 + return;
6.188 + }
6.189 + Square from = findSquare(b, (char)m.getFrom().getX(), m.getFrom().getY());
6.190 + Square to = findSquare(b, (char)m.getTo().getX(), m.getTo().getY());
6.191 + to.setPiece(from.getPiece());
6.192 + to.setPieceColor(from.getPieceColor());
6.193 + from.setPiece(null);
6.194 + from.setPieceColor(null);
6.195 + if (m == data) {
6.196 + found = true;
6.197 + }
6.198 + }
6.199 + b.setTurn(b.getMoves().size() % 2 == 0 ? Color.W : Color.B);
6.200 + }
6.201 +
6.202 +
6.203 +
6.204 + @Function static void rotateBoard(Board b) {
6.205 + Collections.reverse(b.getRows());
6.206 + for (Row r : b.getRows()) {
6.207 + Collections.reverse(r.getColumns());
6.208 + }
6.209 + Square sq = findSelectedSquare(b);
6.210 + if (sq != null) {
6.211 + sq.setSelected(false);
6.212 + Rules.computeAccessible(b, null);
6.213 + }
6.214 + }
6.215 +
6.216 + @ComputedProperty static boolean whiteTurn(Color turn) {
6.217 + return turn == Color.W;
6.218 + }
6.219 +
6.220 + @ComputedProperty static boolean blackTurn(Color turn) {
6.221 + return turn == Color.B;
6.222 + }
6.223 +
6.224 + @ComputedProperty static List<String> columnNames(List<Row> rows) {
6.225 + boolean whiteDown = rows.isEmpty() || rows.get(0).getY() == 8;
6.226 + String[] arr = new String[8];
6.227 + for (int i = 0; i < 8; i++) {
6.228 + String s;
6.229 + if (whiteDown) {
6.230 + s = "" + (char)('A' + i);
6.231 + } else {
6.232 + s = "" + (char)('H' - i);
6.233 + }
6.234 + arr[i] = s;
6.235 + }
6.236 + return Arrays.asList(arr);
6.237 + }
6.238 +
6.239 + static Square findSquare(Board b, char column, int row) {
6.240 + for (Row r : b.getRows()) {
6.241 + for (Square square : r.getColumns()) {
6.242 + if (square.getPosition().getX() == column && square.getPosition().getY() == row) {
6.243 + return square;
6.244 + }
6.245 + }
6.246 + }
6.247 + return null;
6.248 + }
6.249 +
6.250 + private static Square findSquare(Board b, Position to) {
6.251 + return findSquare(b, (char)to.getX(), to.getY());
6.252 + }
6.253 +
6.254 + static Square findSelectedSquare(Board b) {
6.255 + for (Row row : b.getRows()) {
6.256 + for (Square square : row.getColumns()) {
6.257 + if (square.isSelected()) {
6.258 + return square;
6.259 + }
6.260 + }
6.261 + }
6.262 + return null;
6.263 + }
6.264 +
6.265 + static void moveResponse(final Board b, final String errMsg, final List<String> whites, final List<String> blacks, final Color turn,
6.266 + Alert alert
6.267 + ) {
6.268 + if (errMsg != null) {
6.269 + b.getMoves().remove(b.getPendingMove());
6.270 + b.setPendingMove(null);
6.271 + b.setAlertMessage(errMsg);
6.272 + } else {
6.273 + b.setTurn(turn);
6.274 + b.setAlertMessage(null);
6.275 + }
6.276 + b.setAlert(alert);
6.277 + Rules.initBoard(b, whites, blacks, turn);
6.278 + }
6.279 +
6.280 + static void moveUpdate(final Board b, final Move move, final List<String> whites, final List<String> blacks, final Color turn, Alert alert) {
6.281 + final Square from = BoardModel.findSquare(b, move.getFrom());
6.282 + final Square to = BoardModel.findSquare(b, move.getTo());
6.283 + move.setPiece(from.getPiece());
6.284 + move.setTurn(from.getPieceColor());
6.285 + if (to.getPiece() != null) {
6.286 + move.setTakes(true);
6.287 + }
6.288 + b.setAlert(alert);
6.289 + b.setAlertMessage(alert == null ? null : alert.getMessage());
6.290 + move.setRound(b.getMoves().size() / 2 + 1);
6.291 + b.getMoves().add(move);
6.292 + Rules.initBoard(b, whites, blacks, turn);
6.293 + }
6.294 +
6.295 + @Model(className="Row", properties = {
6.296 + @Property(name = "columns", type = Square.class, array = true)
6.297 + })
6.298 + static class RowsImpl {
6.299 + @ComputedProperty static int y(List<Square> columns) {
6.300 + return columns.isEmpty() ? 0 : columns.get(0).getY();
6.301 + }
6.302 + }
6.303 +
6.304 + enum PieceType {
6.305 + PAWN(5), ROCK(2), KNIGHT(4), BISHOP(3), QUEEN(1), KING(0);
6.306 +
6.307 + final int entityIndex;
6.308 +
6.309 + PieceType(int ei) {
6.310 + this.entityIndex = ei;
6.311 + }
6.312 +
6.313 + static PieceType fromNotation(char notation) {
6.314 + switch (notation) {
6.315 + case 'R': return ROCK;
6.316 + case 'N': return KNIGHT;
6.317 + case 'B': return BISHOP;
6.318 + case 'Q': return QUEEN;
6.319 + case 'K': return KING;
6.320 + case 'P': return PAWN;
6.321 + }
6.322 + throw new IllegalStateException("Unexpected: " + notation);
6.323 + }
6.324 +
6.325 + String computeEntity(Color color) {
6.326 + if (color == null) {
6.327 + color = Color.W;
6.328 + }
6.329 + int base;
6.330 + switch (color) {
6.331 + case W: base = 12; break;
6.332 + case B: base = 18; break;
6.333 + default:
6.334 + throw new AssertionError();
6.335 + }
6.336 + return "b" + String.valueOf(base + entityIndex) + ";";
6.337 + }
6.338 + }
6.339 +
6.340 + @Model(className="Position", properties = {
6.341 + @Property(name = "x", type = char.class),
6.342 + @Property(name = "y", type = int.class),
6.343 + })
6.344 + static class PositionImpl {
6.345 + @ComputedProperty static String location(int x, int y) {
6.346 + return "" + (char)(x - 'A' + 'a') + y;
6.347 + }
6.348 + }
6.349 +
6.350 + @Model(className="Square", properties = {
6.351 + @Property(name = "position", type = Position.class),
6.352 + @Property(name = "color", type = Color.class),
6.353 + @Property(name = "piece", type = PieceType.class),
6.354 + @Property(name = "pieceColor", type = Color.class),
6.355 + @Property(name = "selected", type = boolean.class),
6.356 + @Property(name = "accessible", type = boolean.class),
6.357 + @Property(name = "pending", type = boolean.class),
6.358 + })
6.359 + static class SquareModel {
6.360 + @ComputedProperty static String pieceEntity(
6.361 + PieceType piece, Color pieceColor
6.362 + ) {
6.363 + if (piece == null) {
6.364 + return "";
6.365 + }
6.366 + return piece.computeEntity(pieceColor);
6.367 + }
6.368 +
6.369 + @ComputedProperty static String squareColor(
6.370 + Color color, boolean selected, boolean accessible, boolean pending
6.371 + ) {
6.372 + if (selected) {
6.373 + return "selected";
6.374 + }
6.375 + if (accessible) {
6.376 + return "accessible";
6.377 + }
6.378 + if (pending) {
6.379 + return "pending";
6.380 + }
6.381 +
6.382 + if (color == null) {
6.383 + return "";
6.384 + } else {
6.385 + if (color == Color.W) {
6.386 + return "white";
6.387 + } else {
6.388 + return "black";
6.389 + }
6.390 + }
6.391 + }
6.392 +
6.393 + @ComputedProperty static char x(Position position) {
6.394 + return position == null ? 'A' : position.getX();
6.395 + }
6.396 +
6.397 + @ComputedProperty static int y(Position position) {
6.398 + return position == null ? 1 : position.getY();
6.399 + }
6.400 + }
6.401 +
6.402 + @Model(className = "Move", properties = {
6.403 + @Property(name = "round", type = int.class),
6.404 + @Property(name = "turn", type = Color.class),
6.405 + @Property(name = "piece", type = PieceType.class),
6.406 + @Property(name = "from", type = Position.class),
6.407 + @Property(name = "to", type = Position.class),
6.408 + @Property(name = "promoted", type = PieceType.class),
6.409 + @Property(name = "takes", type = boolean.class),
6.410 + @Property(name = "check", type = boolean.class),
6.411 + })
6.412 + static class MoveImpl {
6.413 + @ComputedProperty static boolean whiteMove(Color turn) {
6.414 + return turn == Color.W;
6.415 + }
6.416 +
6.417 + @ComputedProperty static String html(
6.418 + Position from, Position to, boolean takes, PieceType piece, Color turn
6.419 + ) {
6.420 + if (from == null || to == null) {
6.421 + return "";
6.422 + }
6.423 + StringBuilder sb = new StringBuilder();
6.424 + if (piece != null && piece != PieceType.PAWN) {
6.425 + sb.append(piece.computeEntity(turn));
6.426 + }
6.427 +
6.428 + sb.append(from.getLocation());
6.429 + if (takes) {
6.430 + sb.append("x");
6.431 + }
6.432 + sb.append(to.getLocation());
6.433 + return sb.toString();
6.434 + }
6.435 +
6.436 + static Move valueOf(String move) {
6.437 + move = move.toUpperCase();
6.438 + Move m = new Move();
6.439 + {
6.440 + Position p = new Position();
6.441 + p.setX(move.charAt(0));
6.442 + p.setY(move.charAt(1) - '0');
6.443 + m.setFrom(p);
6.444 + }
6.445 + {
6.446 + Position p = new Position();
6.447 + p.setX(move.charAt(2));
6.448 + p.setY(move.charAt(3) - '0');
6.449 + m.setTo(p);
6.450 + }
6.451 + return m;
6.452 + }
6.453 + }
6.454 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/Color.java Tue Sep 24 22:20:24 2013 +0200
7.3 @@ -0,0 +1,32 @@
7.4 +/**
7.5 + * The MIT License (MIT)
7.6 + *
7.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
7.8 + *
7.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
7.10 + * of this software and associated documentation files (the "Software"), to deal
7.11 + * in the Software without restriction, including without limitation the rights
7.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7.13 + * copies of the Software, and to permit persons to whom the Software is
7.14 + * furnished to do so, subject to the following conditions:
7.15 + *
7.16 + * The above copyright notice and this permission notice shall be included in
7.17 + * all copies or substantial portions of the Software.
7.18 + *
7.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
7.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
7.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
7.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
7.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
7.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
7.25 + * THE SOFTWARE.
7.26 + */
7.27 +package com.oracle.chess.client.htmljava;
7.28 +
7.29 +/**
7.30 + *
7.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
7.32 + */
7.33 +public enum Color {
7.34 + W, B;
7.35 +}
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/Communication.java Tue Sep 24 22:20:24 2013 +0200
8.3 @@ -0,0 +1,110 @@
8.4 +/**
8.5 + * The MIT License (MIT)
8.6 + *
8.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
8.8 + *
8.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
8.10 + * of this software and associated documentation files (the "Software"), to deal
8.11 + * in the Software without restriction, including without limitation the rights
8.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8.13 + * copies of the Software, and to permit persons to whom the Software is
8.14 + * furnished to do so, subject to the following conditions:
8.15 + *
8.16 + * The above copyright notice and this permission notice shall be included in
8.17 + * all copies or substantial portions of the Software.
8.18 + *
8.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
8.25 + * THE SOFTWARE.
8.26 + */
8.27 +package com.oracle.chess.client.htmljava;
8.28 +
8.29 +import net.java.html.json.ComputedProperty;
8.30 +import net.java.html.json.Model;
8.31 +import net.java.html.json.Property;
8.32 +
8.33 +
8.34 +/** Communication protocols to talk to the server.
8.35 + *
8.36 + * @author Jaroslav Tulach <jtulach@netbeans.org>
8.37 + */
8.38 +final class Communication {
8.39 + @Model(className = "Request", properties = {
8.40 + @Property(name = "msg", type = MsgType.class),
8.41 + @Property(name = "username", type = String.class),
8.42 + @Property(name = "password", type = String.class),
8.43 + @Property(name = "gameId", type = String.class),
8.44 + @Property(name = "color", type = Color.class),
8.45 + @Property(name = "from", type = String.class),
8.46 + @Property(name = "to", type = String.class),
8.47 + @Property(name = "observer", type = boolean.class),
8.48 + })
8.49 + static class RequestModel {
8.50 + }
8.51 +
8.52 + @Model(className = "BoardRep", properties = {
8.53 + @Property(name = "whites", type = String.class, array = true),
8.54 + @Property(name = "blacks", type = String.class, array = true),
8.55 + })
8.56 + static class BoardRepModel {
8.57 + }
8.58 +
8.59 + @Model(className = "Response", properties = {
8.60 + @Property(name = "msg", type = String.class),
8.61 + @Property(name = "games", array = true, type = Game.class),
8.62 + @Property(name = "board", type = BoardRep.class),
8.63 + @Property(name = "turn", type = Color.class),
8.64 + @Property(name = "color", type = Color.class),
8.65 + @Property(name = "gameId", type = String.class),
8.66 + @Property(name = "error", type = Err.class),
8.67 + @Property(name = "alert", type = Alert.class),
8.68 + @Property(name = "status", type = String.class),
8.69 + @Property(name = "summary", type = String.class),
8.70 + @Property(name = "moves", type = String.class, array = true),
8.71 + @Property(name = "from", type = String.class),
8.72 + @Property(name = "to", type = String.class),
8.73 + @Property(name = "check", type = CheckResult.class),
8.74 + @Property(name = "whitePlayer", type = String.class),
8.75 + @Property(name = "blackPlayer", type = String.class),
8.76 + })
8.77 + static class ResponseModel {
8.78 + @ComputedProperty static Color nextTurn(Color turn, Alert alert) {
8.79 + if (alert == null || !alert.getType().isTerminal()) {
8.80 + return turn;
8.81 + } else {
8.82 + return null;
8.83 + }
8.84 + }
8.85 + }
8.86 +
8.87 + static enum CheckResult {
8.88 + VALID, INVALID, NOT_REGISTERED
8.89 + };
8.90 +
8.91 + @Model(className = "Err", properties = {
8.92 + @Property(name = "code", type = int.class),
8.93 + @Property(name = "message", type = String.class),
8.94 + })
8.95 + static class ErrorModel {
8.96 + }
8.97 +
8.98 + @Model(className = "Alert", properties = {
8.99 + @Property(name = "type", type = AlertType.class),
8.100 + @Property(name = "message", type = String.class),
8.101 + })
8.102 + static class AlertModel {
8.103 + }
8.104 +
8.105 + static enum AlertType {
8.106 + CHECKMATE, CHECK, DRAW;
8.107 +
8.108 + public boolean isTerminal() {
8.109 + return this == CHECKMATE || this == DRAW;
8.110 + }
8.111 + };
8.112 +
8.113 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/GamesModel.java Tue Sep 24 22:20:24 2013 +0200
9.3 @@ -0,0 +1,86 @@
9.4 +/**
9.5 + * The MIT License (MIT)
9.6 + *
9.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
9.8 + *
9.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
9.10 + * of this software and associated documentation files (the "Software"), to deal
9.11 + * in the Software without restriction, including without limitation the rights
9.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9.13 + * copies of the Software, and to permit persons to whom the Software is
9.14 + * furnished to do so, subject to the following conditions:
9.15 + *
9.16 + * The above copyright notice and this permission notice shall be included in
9.17 + * all copies or substantial portions of the Software.
9.18 + *
9.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
9.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
9.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
9.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
9.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
9.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
9.25 + * THE SOFTWARE.
9.26 + */
9.27 +package com.oracle.chess.client.htmljava;
9.28 +
9.29 +import java.util.List;
9.30 +import net.java.html.json.ComputedProperty;
9.31 +import net.java.html.json.Model;
9.32 +import net.java.html.json.ModelOperation;
9.33 +import net.java.html.json.Property;
9.34 +
9.35 +/**
9.36 + *
9.37 + * @author Jaroslav Tulach <jtulach@netbeans.org>
9.38 + */
9.39 +@Model(className = "Games", properties = {
9.40 + @Property(name = "own", array = true, type = Game.class),
9.41 + @Property(name = "other", array = true, type = Game.class),
9.42 + @Property(name = "selectedColor", type = String.class),
9.43 +})
9.44 +class GamesModel {
9.45 + @Model(className = "Game", properties = {
9.46 + @Property(name = "gameId", type=String.class),
9.47 + @Property(name = "summary", type=String.class),
9.48 + @Property(name = "open", type=boolean.class),
9.49 + @Property(name = "whitePlayer", type=String.class),
9.50 + @Property(name = "blackPlayer", type=String.class)
9.51 + })
9.52 + static class GameImpl {
9.53 + @ComputedProperty static String description(String gameId, String summary) {
9.54 + return summary != null ? summary : gameId;
9.55 + }
9.56 +
9.57 + @ComputedProperty static boolean pendingPlayer(String whitePlayer, String blackPlayer) {
9.58 + return whitePlayer == null || blackPlayer == null;
9.59 + }
9.60 + }
9.61 +
9.62 +
9.63 + @ComputedProperty static boolean anyOwnGame(List<Game> own) {
9.64 + return !own.isEmpty();
9.65 + }
9.66 +
9.67 + @ComputedProperty static boolean anyOtherGame(List<Game> other) {
9.68 + return !other.isEmpty();
9.69 + }
9.70 +
9.71 + @ModelOperation static void listGames(Games g, List<Game> games, String username) {
9.72 + g.getOwn().clear();
9.73 + g.getOther().clear();
9.74 + int cnt = 0;
9.75 + final int maxGames = 30;
9.76 + for (Game game : games) {
9.77 + if (
9.78 + username.equals(game.getWhitePlayer()) ||
9.79 + username.equals(game.getBlackPlayer())
9.80 + ) {
9.81 + g.getOwn().add(game);
9.82 + } else {
9.83 + if (cnt++ < maxGames) {
9.84 + g.getOther().add(game);
9.85 + }
9.86 + }
9.87 + }
9.88 + }
9.89 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/LoadMain.java Tue Sep 24 22:20:24 2013 +0200
10.3 @@ -0,0 +1,41 @@
10.4 +/**
10.5 + * The MIT License (MIT)
10.6 + *
10.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
10.8 + *
10.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
10.10 + * of this software and associated documentation files (the "Software"), to deal
10.11 + * in the Software without restriction, including without limitation the rights
10.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10.13 + * copies of the Software, and to permit persons to whom the Software is
10.14 + * furnished to do so, subject to the following conditions:
10.15 + *
10.16 + * The above copyright notice and this permission notice shall be included in
10.17 + * all copies or substantial portions of the Software.
10.18 + *
10.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
10.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
10.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
10.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
10.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
10.25 + * THE SOFTWARE.
10.26 + */
10.27 +package com.oracle.chess.client.htmljava;
10.28 +
10.29 +
10.30 +public final class LoadMain {
10.31 + private LoadMain() {
10.32 + }
10.33 +
10.34 + /**
10.35 + * Called when the page is ready.
10.36 + */
10.37 + static {
10.38 + try {
10.39 + UIModel.initialize();
10.40 + } catch (Throwable ex) {
10.41 + ex.printStackTrace();
10.42 + }
10.43 + }
10.44 +}
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/Main.java Tue Sep 24 22:20:24 2013 +0200
11.3 @@ -0,0 +1,42 @@
11.4 +/**
11.5 + * The MIT License (MIT)
11.6 + *
11.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
11.8 + *
11.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
11.10 + * of this software and associated documentation files (the "Software"), to deal
11.11 + * in the Software without restriction, including without limitation the rights
11.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11.13 + * copies of the Software, and to permit persons to whom the Software is
11.14 + * furnished to do so, subject to the following conditions:
11.15 + *
11.16 + * The above copyright notice and this permission notice shall be included in
11.17 + * all copies or substantial portions of the Software.
11.18 + *
11.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
11.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
11.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
11.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
11.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
11.25 + * THE SOFTWARE.
11.26 + */
11.27 +package com.oracle.chess.client.htmljava;
11.28 +
11.29 +import net.java.html.boot.BrowserBuilder;
11.30 +import org.apidesign.bck2brwsr.core.JavaScriptOnly;
11.31 +
11.32 +public final class Main {
11.33 + private Main() {
11.34 + }
11.35 +
11.36 + @JavaScriptOnly(name = "main", value = "null")
11.37 + public static void main(String... args) throws Exception {
11.38 + BrowserBuilder.newBrowser().
11.39 + loadPage("pages/index.html").
11.40 + loadClass(UIModel.class).
11.41 + invoke("initialize", args).
11.42 + showAndWait();
11.43 + System.exit(0);
11.44 + }
11.45 +}
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/MsgType.java Tue Sep 24 22:20:24 2013 +0200
12.3 @@ -0,0 +1,40 @@
12.4 +/**
12.5 + * The MIT License (MIT)
12.6 + *
12.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
12.8 + *
12.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
12.10 + * of this software and associated documentation files (the "Software"), to deal
12.11 + * in the Software without restriction, including without limitation the rights
12.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12.13 + * copies of the Software, and to permit persons to whom the Software is
12.14 + * furnished to do so, subject to the following conditions:
12.15 + *
12.16 + * The above copyright notice and this permission notice shall be included in
12.17 + * all copies or substantial portions of the Software.
12.18 + *
12.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
12.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
12.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
12.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
12.25 + * THE SOFTWARE.
12.26 + */
12.27 +package com.oracle.chess.client.htmljava;
12.28 +
12.29 +/**
12.30 + *
12.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
12.32 + */
12.33 + enum MsgType {
12.34 + CreateGame, QueryGames, SendMove, JoinGame, UpdateGame, CheckCredentials;
12.35 +
12.36 + static MsgType forResponse(String msg) {
12.37 + if (msg.endsWith("Rsp")) {
12.38 + msg = msg.substring(0, msg.length() - 3);
12.39 + }
12.40 + return MsgType.valueOf(msg);
12.41 + }
12.42 +
12.43 +}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/Rules.java Tue Sep 24 22:20:24 2013 +0200
13.3 @@ -0,0 +1,314 @@
13.4 +/**
13.5 + * The MIT License (MIT)
13.6 + *
13.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
13.8 + *
13.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
13.10 + * of this software and associated documentation files (the "Software"), to deal
13.11 + * in the Software without restriction, including without limitation the rights
13.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13.13 + * copies of the Software, and to permit persons to whom the Software is
13.14 + * furnished to do so, subject to the following conditions:
13.15 + *
13.16 + * The above copyright notice and this permission notice shall be included in
13.17 + * all copies or substantial portions of the Software.
13.18 + *
13.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
13.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
13.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
13.25 + * THE SOFTWARE.
13.26 + */
13.27 +package com.oracle.chess.client.htmljava;
13.28 +
13.29 +import java.util.ArrayList;
13.30 +import java.util.List;
13.31 +
13.32 +/** Common chess rules.
13.33 + *
13.34 + * @author Jaroslav Tulach <jtulach@netbeans.org>
13.35 + */
13.36 +class Rules {
13.37 + static void computeAccessible(Board b, Square s) {
13.38 + for (Row r : b.getRows()) {
13.39 + for (Square ts : r.getColumns()) {
13.40 + ts.setAccessible(false);
13.41 + }
13.42 + }
13.43 + if (s == null) {
13.44 + return;
13.45 + }
13.46 +
13.47 + switch (s.getPiece()) {
13.48 + case BISHOP:
13.49 + moveBishop(b, s);
13.50 + break;
13.51 + case KING:
13.52 + computeAccessible(b, s, 1, 1, 1);
13.53 + computeAccessible(b, s, 1, -1, 1);
13.54 + computeAccessible(b, s, -1, -1, 1);
13.55 + computeAccessible(b, s, -1, 1, 1);
13.56 + computeAccessible(b, s, 1, 0, 1);
13.57 + computeAccessible(b, s, 0, -1, 1);
13.58 + computeAccessible(b, s, 0, 1, 1);
13.59 + computeAccessible(b, s, -1, 0, 1);
13.60 + checkRochade(b, s);
13.61 + break;
13.62 + case ROCK:
13.63 + moveRock(b, s);
13.64 + break;
13.65 + case QUEEN:
13.66 + moveRock(b, s);
13.67 + moveBishop(b, s);
13.68 + break;
13.69 + case KNIGHT:
13.70 + computeAccessible(b, s, 2, 1, 1);
13.71 + computeAccessible(b, s, 2, -1, 1);
13.72 + computeAccessible(b, s, -2, -1, 1);
13.73 + computeAccessible(b, s, -2, 1, 1);
13.74 + computeAccessible(b, s, 1, 2, 1);
13.75 + computeAccessible(b, s, -1, 2, 1);
13.76 + computeAccessible(b, s, -1, -2, 1);
13.77 + computeAccessible(b, s, 1, -2, 1);
13.78 + break;
13.79 + case PAWN:
13.80 + pawns(b, s);
13.81 + break;
13.82 + }
13.83 + }
13.84 +
13.85 + private static void moveRock(Board b, Square s) {
13.86 + computeAccessible(b, s, 1, 0, 8);
13.87 + computeAccessible(b, s, 0, -1, 8);
13.88 + computeAccessible(b, s, -1, 0, 8);
13.89 + computeAccessible(b, s, 0, 1, 8);
13.90 + }
13.91 +
13.92 + private static void moveBishop(Board b, Square s) {
13.93 + computeAccessible(b, s, 1, 1, 8);
13.94 + computeAccessible(b, s, 1, -1, 8);
13.95 + computeAccessible(b, s, -1, -1, 8);
13.96 + computeAccessible(b, s, -1, 1, 8);
13.97 + }
13.98 +
13.99 + private static void computeAccessible(
13.100 + Board b, Square s, int dx, int dy,
13.101 + int limit
13.102 + ) {
13.103 + int x = s.getX();
13.104 + int y = s.getY();
13.105 +
13.106 + while (limit-- > 0) {
13.107 + x += dx;
13.108 + y += dy;
13.109 + Square next = BoardModel.findSquare(b, (char)x, y);
13.110 + if (next == null) {
13.111 + break;
13.112 + }
13.113 + if (next.getPieceColor() == s.getPieceColor()) {
13.114 + break;
13.115 + }
13.116 + next.setAccessible(true);
13.117 + if (next.getPieceColor() != null) {
13.118 + break;
13.119 + }
13.120 + }
13.121 + }
13.122 +
13.123 + private static void pawns(Board b, Square s) {
13.124 + final boolean white = s.getPieceColor() == Color.W;
13.125 + int dy = white ? 1 : -1;
13.126 + Square step = BoardModel.findSquare(b, (char)s.getX(), s.getY() + dy);
13.127 + if (step != null && step.getPiece() == null) {
13.128 + step.setAccessible(true);
13.129 + if ((s.getY() == 2 && white) || (s.getY() == 7 && !white)) {
13.130 + Square nextSTep = BoardModel.findSquare(b, (char)s.getX(), step.getY() + dy);
13.131 + if (nextSTep != null && step.getPiece() == null && nextSTep.getPiece() == null) {
13.132 + nextSTep.setAccessible(true);
13.133 + }
13.134 + }
13.135 + }
13.136 + Color opposite = white ? Color.B : Color.W;
13.137 + Square takeLeft = BoardModel.findSquare(b, (char)(s.getX() - 1), s.getY() + dy);
13.138 + if (takeLeft != null && takeLeft.getPieceColor() == opposite) {
13.139 + takeLeft.setAccessible(true);
13.140 + }
13.141 + Square takeRight = BoardModel.findSquare(b, (char)(s.getX() + 1), s.getY() + dy);
13.142 + if (takeRight != null && takeRight.getPieceColor() == opposite) {
13.143 + takeRight.setAccessible(true);
13.144 + }
13.145 + if ((white && s.getY() == 5) || (!white && s.getY() == 4)) {
13.146 + int enPassantFrom = white ? 7 : 2;
13.147 + int enPassantTo = white ? 5 : 4;
13.148 + if (!b.getMoves().isEmpty()) {
13.149 + Move last = b.getMoves().get(b.getMoves().size() - 1);
13.150 + if (
13.151 + last.getPiece() == BoardModel.PieceType.PAWN &&
13.152 + last.getFrom().getY() == enPassantFrom &&
13.153 + last.getTo().getY() == enPassantTo
13.154 + ) {
13.155 + if (takeLeft != null && last.getFrom().getX() == s.getX() - 1) {
13.156 + takeLeft.setAccessible(true);
13.157 + }
13.158 + if (takeRight != null && last.getFrom().getX() == s.getX() + 1) {
13.159 + takeRight.setAccessible(true);
13.160 + }
13.161 + }
13.162 + }
13.163 + }
13.164 + }
13.165 +
13.166 + static Board createBoard() {
13.167 + Board b = new Board();
13.168 + initBoardField(b);
13.169 + initBoard(b);
13.170 + return b;
13.171 + }
13.172 +
13.173 + private static void initBoardField(Board b) {
13.174 + List<Row> addRows = new ArrayList<>(8);
13.175 + for (int i = 8; i > 0; i--) {
13.176 + Square[] arr = new Square[8];
13.177 + for (char j = 'A'; j <= 'H'; j++) {
13.178 + arr[j - 'A'] = new Square(
13.179 + new Position(j, i),
13.180 + (i + j) % 2 == 1 ? Color.W : Color.B,
13.181 + null, null, // figure
13.182 + false, false, false
13.183 + );
13.184 + }
13.185 + addRows.add(new Row(arr));
13.186 + }
13.187 + b.getRows().addAll(addRows);
13.188 + }
13.189 +
13.190 + static void initBoard(Board b) {
13.191 + initBoard(b, true);
13.192 + }
13.193 + private static void initBoard(Board b, boolean init) {
13.194 + if (init) {
13.195 + b.setTurn(Color.W);
13.196 + }
13.197 + if (b.getRows().isEmpty()) {
13.198 + for (int i = 8; i > 0; i--) {
13.199 + Row r = b.getRows().get(8 - i);
13.200 + for (char j = 'A'; j <= 'H'; j++) {
13.201 + Square s = r.getColumns().get(j - 'A');
13.202 + s.setAccessible(false);
13.203 + s.setPending(false);
13.204 + r.getColumns().set(j - 'A', s);
13.205 + initialPosition(s, init);
13.206 + }
13.207 + }
13.208 + } else {
13.209 + for (Row r : b.getRows()) {
13.210 + for (Square square : r.getColumns()) {
13.211 + square.setAccessible(false);
13.212 + square.setPending(false);
13.213 + square.setPiece(null);
13.214 + square.setPieceColor(null);
13.215 + square.setSelected(false);
13.216 + initialPosition(square, init);
13.217 + }
13.218 + }
13.219 + }
13.220 + b.setPendingMove(null);
13.221 + }
13.222 +
13.223 + private static void initialPosition(Square s, boolean init) {
13.224 + int row = s.getPosition().getY();
13.225 + char column = s.getPosition().getX();
13.226 + s.setPiece(null);
13.227 + s.setPieceColor(null);
13.228 + if (init) {
13.229 + if (row == 2) {
13.230 + s.setPiece(BoardModel.PieceType.PAWN);
13.231 + s.setPieceColor(Color.W);
13.232 + } else if (row == 7) {
13.233 + s.setPiece(BoardModel.PieceType.PAWN);
13.234 + s.setPieceColor(Color.B);
13.235 + } else if (row == 8 || row == 1) {
13.236 + s.setPieceColor(row == 1 ? Color.W : Color.B);
13.237 + BoardModel.PieceType t;
13.238 + switch (column) {
13.239 + case 'A':
13.240 + case 'H':
13.241 + t = BoardModel.PieceType.ROCK;
13.242 + break;
13.243 + case 'B':
13.244 + case 'G':
13.245 + t = BoardModel.PieceType.KNIGHT;
13.246 + break;
13.247 + case 'C':
13.248 + case 'F':
13.249 + t = BoardModel.PieceType.BISHOP;
13.250 + break;
13.251 + case 'D':
13.252 + t = BoardModel.PieceType.QUEEN;
13.253 + break;
13.254 + default:
13.255 + t = BoardModel.PieceType.KING;
13.256 + break;
13.257 + }
13.258 + s.setPiece(t);
13.259 + }
13.260 + }
13.261 + }
13.262 +
13.263 + static void initBoard(
13.264 + Board board, List<String> whites, List<String> blacks, Color turn
13.265 + ) {
13.266 + initBoard(board, false);
13.267 + for (String w : whites) {
13.268 + assert w.length() == 3 : "Expecting three letter string: '" + w + "'";
13.269 + w = w.toUpperCase();
13.270 + char column = w.charAt(1);
13.271 + int row = (w.charAt(2) - '0');
13.272 +
13.273 + Square s = BoardModel.findSquare(board, column, row);
13.274 + s.setPieceColor(Color.W);
13.275 + s.setPiece(BoardModel.PieceType.fromNotation(w.charAt(0)));
13.276 + }
13.277 + for (String w : blacks) {
13.278 + assert w.length() == 3 : "Expecting three letter string: '" + w + "'";
13.279 + w = w.toUpperCase();
13.280 + char column = w.charAt(1);
13.281 + int row = (w.charAt(2) - '0');
13.282 +
13.283 + Square s = BoardModel.findSquare(board, column, row);
13.284 + s.setPieceColor(Color.B);
13.285 + s.setPiece(BoardModel.PieceType.fromNotation(w.charAt(0)));
13.286 + }
13.287 + board.setTurn(turn);
13.288 + }
13.289 +
13.290 + private static void checkRochade(Board b, Square s) {
13.291 + if (s.getPosition().getX() == 'E') {
13.292 + int y = s.getPosition().getY();
13.293 + final Square gRow = BoardModel.findSquare(b, 'G', y);
13.294 + if (
13.295 + BoardModel.findSquare(b, 'H', y).getPiece() == BoardModel.PieceType.ROCK
13.296 + &&
13.297 + BoardModel.findSquare(b, 'F', y).getPiece() == null
13.298 + &&
13.299 + gRow.getPiece() == null
13.300 + ) {
13.301 + gRow.setAccessible(true);
13.302 + }
13.303 + final Square cRow = BoardModel.findSquare(b, 'C', y);
13.304 + if (
13.305 + BoardModel.findSquare(b, 'A', y).getPiece() == BoardModel.PieceType.ROCK
13.306 + &&
13.307 + BoardModel.findSquare(b, 'B', y).getPiece() == null
13.308 + &&
13.309 + BoardModel.findSquare(b, 'D', y).getPiece() == null
13.310 + &&
13.311 + cRow.getPiece() == null
13.312 + ) {
13.313 + cRow.setAccessible(true);
13.314 + }
13.315 + }
13.316 + }
13.317 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
14.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/SettingsModel.java Tue Sep 24 22:20:24 2013 +0200
14.3 @@ -0,0 +1,82 @@
14.4 +/**
14.5 + * The MIT License (MIT)
14.6 + *
14.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
14.8 + *
14.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
14.10 + * of this software and associated documentation files (the "Software"), to deal
14.11 + * in the Software without restriction, including without limitation the rights
14.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14.13 + * copies of the Software, and to permit persons to whom the Software is
14.14 + * furnished to do so, subject to the following conditions:
14.15 + *
14.16 + * The above copyright notice and this permission notice shall be included in
14.17 + * all copies or substantial portions of the Software.
14.18 + *
14.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
14.25 + * THE SOFTWARE.
14.26 + */
14.27 +package com.oracle.chess.client.htmljava;
14.28 +
14.29 +import java.io.File;
14.30 +import java.io.FileInputStream;
14.31 +import java.io.FileOutputStream;
14.32 +import java.io.IOException;
14.33 +import java.util.Properties;
14.34 +import net.java.html.json.ComputedProperty;
14.35 +import net.java.html.json.Model;
14.36 +import net.java.html.json.ModelOperation;
14.37 +import net.java.html.json.Property;
14.38 +
14.39 +/**
14.40 + *
14.41 + * @author Jaroslav Tulach <jtulach@netbeans.org>
14.42 + */
14.43 +@Model(className = "Settings", properties = {
14.44 + @Property(name = "username", type = String.class),
14.45 + @Property(name = "password", type = String.class),
14.46 + @Property(name = "url", type = String.class),
14.47 +})
14.48 +class SettingsModel {
14.49 + private static final String SETTINGS = ".j1chess/html.properties";
14.50 + private static final String DEFAULT_URL = "ws://localhost:8080/chess/chessserver";
14.51 +
14.52 + @ComputedProperty static boolean validCredentials(String username, String password) {
14.53 + return username != null && password != null && !username.isEmpty() && !password.isEmpty();
14.54 + }
14.55 +
14.56 + @ModelOperation static void read(Settings s) {
14.57 + File prefs = new File(System.getProperty("user.home"), SETTINGS);
14.58 + try (FileInputStream is = new FileInputStream(prefs)) {
14.59 + Properties p = new Properties();
14.60 + p.load(is);
14.61 +
14.62 + s.setUsername(p.getProperty("username", ""));
14.63 + s.setPassword(p.getProperty("password", ""));
14.64 + s.setUrl(p.getProperty("url", DEFAULT_URL));
14.65 + } catch (Throwable ex) {
14.66 + s.setUsername("");
14.67 + s.setPassword("");
14.68 + s.setUrl(DEFAULT_URL);
14.69 + }
14.70 + }
14.71 +
14.72 + @ModelOperation static void write(Settings s, UI ui) {
14.73 + File prefs = new File(System.getProperty("user.home"), SETTINGS);
14.74 + prefs.getParentFile().mkdirs();
14.75 + try (FileOutputStream os = new FileOutputStream(prefs)) {
14.76 + Properties p = new Properties();
14.77 + p.setProperty("username", s.getUsername());
14.78 + p.setProperty("password", s.getPassword());
14.79 + p.setProperty("url", s.getUrl());
14.80 + p.store(os, "Java One Chess Preferences for HTML/Java Client");
14.81 + } catch (Throwable ex) {
14.82 + ui.setStatus("Cannot save preferences: " + ex.getMessage());
14.83 + }
14.84 + }
14.85 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
15.2 +++ b/chess/src/main/java/com/oracle/chess/client/htmljava/UIModel.java Tue Sep 24 22:20:24 2013 +0200
15.3 @@ -0,0 +1,315 @@
15.4 +/**
15.5 + * The MIT License (MIT)
15.6 + *
15.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
15.8 + *
15.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
15.10 + * of this software and associated documentation files (the "Software"), to deal
15.11 + * in the Software without restriction, including without limitation the rights
15.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15.13 + * copies of the Software, and to permit persons to whom the Software is
15.14 + * furnished to do so, subject to the following conditions:
15.15 + *
15.16 + * The above copyright notice and this permission notice shall be included in
15.17 + * all copies or substantial portions of the Software.
15.18 + *
15.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
15.25 + * THE SOFTWARE.
15.26 + */
15.27 +package com.oracle.chess.client.htmljava;
15.28 +
15.29 +import java.io.IOException;
15.30 +import java.net.URISyntaxException;
15.31 +import java.util.HashSet;
15.32 +import java.util.List;
15.33 +import java.util.Set;
15.34 +import java.util.logging.Level;
15.35 +import java.util.logging.Logger;
15.36 +import net.java.html.json.ComputedProperty;
15.37 +import net.java.html.json.Function;
15.38 +import net.java.html.json.Model;
15.39 +import net.java.html.json.ModelOperation;
15.40 +import net.java.html.json.OnPropertyChange;
15.41 +import net.java.html.json.OnReceive;
15.42 +import net.java.html.json.Property;
15.43 +
15.44 +/**
15.45 + *
15.46 + * @author Jaroslav Tulach <jtulach@netbeans.org>
15.47 + */
15.48 +@Model(className = "UI", properties = {
15.49 + @Property(name = "status", type = String.class),
15.50 + @Property(name = "selectedGameId", type = String.class),
15.51 + @Property(name = "boards", type = Board.class, array = true),
15.52 + @Property(name = "viewGames", type = Games.class),
15.53 + @Property(name = "settings", type = Settings.class),
15.54 + @Property(name = "connected", type = boolean.class),
15.55 + @Property(name = "disconnected", type = boolean.class),
15.56 +})
15.57 +public class UIModel {
15.58 + private static final Logger LOG = Logger.getLogger(UIModel.class.getName());
15.59 +
15.60 + @ComputedProperty static boolean settingsActive(String selectedGameId) {
15.61 + return selectedGameId == null;
15.62 + }
15.63 +
15.64 + @ComputedProperty static boolean viewGamesActive(String selectedGameId, boolean connected) {
15.65 + return selectedGameId == null && connected;
15.66 + }
15.67 +
15.68 + @ComputedProperty static Board selectedBoard(String selectedGameId, List<Board> boards) {
15.69 + Board active = null;
15.70 + for (Board b : boards) {
15.71 + b.setActive(false);
15.72 + if (selectedGameId != null && selectedGameId.equals(b.getGameId())) {
15.73 + b.setActive(true);
15.74 + active = b;
15.75 + }
15.76 + }
15.77 + return active;
15.78 + }
15.79 +
15.80 + @Function static void activateGame(UI m, Board data) {
15.81 + m.setSelectedGameId(data.getGameId());
15.82 + }
15.83 +
15.84 + @Function static void activateSettings(UI m) {
15.85 + m.setSelectedGameId(null);
15.86 + refreshGames(m);
15.87 + }
15.88 +
15.89 + @Function static void createGame(UI u) {
15.90 + u.setStatus("Creating new game...");
15.91 + Request r = new Request();
15.92 + r.setMsg(MsgType.CreateGame);
15.93 + r.setColor(Color.valueOf(u.getViewGames().getSelectedColor()));
15.94 + u.sendMsg(r);
15.95 + }
15.96 +
15.97 + @ModelOperation @Function static void refreshGames(UI u) {
15.98 + u.setStatus("Refreshing games...");
15.99 + Request r = new Request();
15.100 + r.setMsg(MsgType.QueryGames);
15.101 + u.sendMsg(r);
15.102 + }
15.103 +
15.104 + @ModelOperation static void sendMsg(UI ui, Request r) {
15.105 + final Settings sttngs = ui.getSettings();
15.106 +
15.107 + String url = sttngs.getUrl();
15.108 + r.setUsername(sttngs.getUsername());
15.109 + r.setPassword(sttngs.getPassword());
15.110 +
15.111 + LOG.log(Level.INFO, "Sending {0} to {1}", new Object[]{r, url});
15.112 + ui.queryServer(url, r);
15.113 + }
15.114 +
15.115 +
15.116 + @OnReceive(data = Request.class, url = "{url}", method = "WebSocket", onError = "wasAnError")
15.117 + static void queryServer(UI ui, Response r) {
15.118 + LOG.log(Level.INFO, "Received {0}", r);
15.119 + if (r == null) {
15.120 + ui.setDisconnected(false);
15.121 + verifyLogin(ui);
15.122 + return;
15.123 + }
15.124 + SWITCH: switch (MsgType.forResponse(r.getMsg())) {
15.125 + case CheckCredentials: {
15.126 + switch (r.getCheck()) {
15.127 + case NOT_REGISTERED:
15.128 + case VALID:
15.129 + ui.setConnected(true);
15.130 + ui.refreshGames();
15.131 + ui.setStatus("Connected.");
15.132 + return;
15.133 + case INVALID:
15.134 + ui.setStatus("Password is invalid");
15.135 + break;
15.136 + }
15.137 + disconnect(ui);
15.138 + }
15.139 +
15.140 + case QueryGames:
15.141 + ui.getViewGames().listGames(r.getGames(), ui.getSettings().getUsername());
15.142 + ui.setStatus("");
15.143 + break;
15.144 + case CreateGame: {
15.145 + ui.setStatus("Game " + r + " created");
15.146 + final Board b = Rules.createBoard();
15.147 + Rules.initBoard(
15.148 + b, r.getBoard().getWhites(),
15.149 + r.getBoard().getBlacks(),
15.150 + r.getTurn()
15.151 + );
15.152 + b.setGameId(r.getGameId());
15.153 + b.setWhitePlayer(r.getWhitePlayer());
15.154 + b.setBlackPlayer(r.getBlackPlayer());
15.155 + b.setPlayer(ui.getSettings().getUsername());
15.156 + b.updateSummary(r.getSummary());
15.157 + ui.getBoards().add(b);
15.158 + ui.setSelectedGameId(r.getGameId());
15.159 + UIModel.refreshGames(ui);
15.160 + break;
15.161 + }
15.162 + case SendMove: {
15.163 + if (r.getBoard() == null) {
15.164 + throw new NullPointerException("No board in " + r);
15.165 + }
15.166 + final Board b = findBoard(ui, r.getGameId());
15.167 + if (b == null) {
15.168 + break;
15.169 + }
15.170 + b.updateSummary(r.getSummary());
15.171 + final String errMsg = r.getError() == null ? null : r.getError().getMessage();
15.172 + final List<String> whites = r.getBoard().getWhites();
15.173 + final List<String> blacks = r.getBoard().getBlacks();
15.174 + final Color turn = r.getNextTurn();
15.175 + BoardModel.moveResponse(b, errMsg, whites, blacks, turn, r.getAlert());
15.176 + break;
15.177 + }
15.178 + case JoinGame: {
15.179 + Board b;
15.180 + if ((b = findBoard(ui, r.getGameId())) != null) {
15.181 + b.setWhitePlayer(r.getWhitePlayer());
15.182 + b.setBlackPlayer(r.getBlackPlayer());
15.183 + b.setPlayer(ui.getSettings().getUsername());
15.184 + b.updateSummary(r.getSummary());
15.185 + ui.setSelectedGameId(r.getGameId());
15.186 + break SWITCH;
15.187 + }
15.188 + ui.setStatus("Joining " + r.getGameId() + " as " + r.getColor());
15.189 + b = Rules.createBoard();
15.190 + Rules.initBoard(
15.191 + b, r.getBoard().getWhites(),
15.192 + r.getBoard().getBlacks(),
15.193 + r.getTurn()
15.194 + );
15.195 + b.setGameId(r.getGameId());
15.196 + b.setWhitePlayer(r.getWhitePlayer());
15.197 + b.setBlackPlayer(r.getBlackPlayer());
15.198 + b.setPlayer(ui.getSettings().getUsername());
15.199 + b.updateSummary(r.getSummary());
15.200 + if (r.getColor() == Color.B) {
15.201 + BoardModel.rotateBoard(b);
15.202 + }
15.203 + if (r.getMoves() != null) {
15.204 + for (String move : r.getMoves()) {
15.205 + Move m = BoardModel.MoveImpl.valueOf(move);
15.206 + b.getMoves().add(m);
15.207 + }
15.208 + } else {
15.209 + b.getMoves().clear();
15.210 + }
15.211 + ui.setSelectedGameId(b.getGameId());
15.212 + ui.getBoards().add(b);
15.213 + break;
15.214 + }
15.215 + case UpdateGame: {
15.216 + final Board b = findBoard(ui, r.getGameId());
15.217 + if (b == null) {
15.218 + break;
15.219 + }
15.220 + b.updateSummary(r.getSummary());
15.221 + final Move move = BoardModel.MoveImpl.valueOf(r.getFrom() + r.getTo());
15.222 + final List<String> whites = r.getBoard().getWhites();
15.223 + final List<String> blacks = r.getBoard().getBlacks();
15.224 + final Color turn = r.getNextTurn();
15.225 + BoardModel.moveUpdate(b, move, whites, blacks, turn, null);
15.226 + }
15.227 + }
15.228 + }
15.229 +
15.230 +
15.231 + private static Board findBoard(UI ui, String gameId) {
15.232 + for (Board tmp : ui.getBoards()) {
15.233 + if (tmp.getGameId().equals(gameId)) {
15.234 + return tmp;
15.235 + }
15.236 + }
15.237 + return null;
15.238 + }
15.239 +
15.240 +
15.241 + static void wasAnError(UI ui, Exception t) {
15.242 + if (t == null) {
15.243 + ui.setConnected(false);
15.244 + ui.setDisconnected(true);
15.245 + ui.setStatus("Disconnected.");
15.246 + } else {
15.247 + ui.setStatus("Error: " + t.getLocalizedMessage());
15.248 + }
15.249 + }
15.250 +
15.251 + @Function static void joinGame(UI u, Game data) {
15.252 + Request r = new Request();
15.253 + r.setMsg(MsgType.JoinGame);
15.254 + r.setObserver(false);
15.255 + r.setGameId(data.getGameId());
15.256 + u.sendMsg(r);
15.257 + }
15.258 +
15.259 + @Function static void observeGame(UI u, Game data) {
15.260 + Request r = new Request();
15.261 + r.setMsg(MsgType.JoinGame);
15.262 + r.setObserver(true);
15.263 + r.setGameId(data.getGameId());
15.264 + u.sendMsg(r);
15.265 + }
15.266 +
15.267 + private static final Set<UI> ACTIVE = new HashSet<>();
15.268 + @OnPropertyChange("connected") static void clearGames(UI m) {
15.269 + if (m.isDisconnected()) {
15.270 + m.getBoards().clear();
15.271 + ACTIVE.remove(m);
15.272 + } else {
15.273 + ACTIVE.add(m);
15.274 + }
15.275 + }
15.276 +
15.277 + static UI findUI(Board b) {
15.278 + for (UI ui : ACTIVE) {
15.279 + if (ui.getBoards().contains(b)) {
15.280 + return ui;
15.281 + }
15.282 + }
15.283 + return null;
15.284 + }
15.285 +
15.286 + @Function static void leave(UI ui, Board data) {
15.287 + ui.getBoards().remove(data);
15.288 + ui.setSelectedGameId(null);
15.289 + }
15.290 +
15.291 + @Function static void disconnect(UI ui) {
15.292 + ui.queryServer(ui.getSettings().getUrl(), null);
15.293 + ui.setStatus("Disconnecting...");
15.294 + }
15.295 +
15.296 + private static void verifyLogin(UI ui) {
15.297 + ui.setStatus("Verifying user credentials...");
15.298 + Request r = new Request();
15.299 + r.setMsg(MsgType.CheckCredentials);
15.300 + ui.sendMsg(r);
15.301 + }
15.302 +
15.303 + @Function static void reconnect(UI ui) {
15.304 + final Settings s = ui.getSettings();
15.305 + ui.setStatus("Connecting to the server...");
15.306 + ui.queryServer(s.getUrl(), null);
15.307 + s.write(ui);
15.308 + }
15.309 +
15.310 + public static void initialize(String... args) throws URISyntaxException, IOException {
15.311 + UI ui = new UI();
15.312 + ui.getSettings().read();
15.313 + ui.setStatus("Ready.");
15.314 + ui.setDisconnected(true);
15.315 + ui.applyBindings();
15.316 + }
15.317 +
15.318 +}
16.1 Binary file chess/src/main/webapp/pages/DukeHTML.png has changed
17.1 --- a/chess/src/main/webapp/pages/css/bootstrap.css Tue Sep 24 21:08:15 2013 +0200
17.2 +++ b/chess/src/main/webapp/pages/css/bootstrap.css Tue Sep 24 22:20:24 2013 +0200
17.3 @@ -1119,7 +1119,7 @@
17.4 input,
17.5 textarea,
17.6 .uneditable-input {
17.7 - width: 206px;
17.8 + width: 300px;
17.9 }
17.10
17.11 textarea {
17.12 @@ -1205,7 +1205,7 @@
17.13 *margin-top: 4px;
17.14 /* For IE7, add top margin to align select with labels */
17.15
17.16 - line-height: 30px;
17.17 + vertical-align: middle;
17.18 }
17.19
17.20 select {
17.21 @@ -1775,6 +1775,7 @@
17.22 -webkit-border-radius: 4px 0 0 4px;
17.23 -moz-border-radius: 4px 0 0 4px;
17.24 border-radius: 4px 0 0 4px;
17.25 + color: black;
17.26 }
17.27
17.28 .input-append input + .btn-group .btn:last-child,
17.29 @@ -3218,7 +3219,7 @@
17.30 line-height: 20px;
17.31 color: #333333;
17.32 text-align: center;
17.33 - text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
17.34 + text-shadow: none;
17.35 vertical-align: middle;
17.36 cursor: pointer;
17.37 background-color: #f5f5f5;
17.38 @@ -3966,7 +3967,7 @@
17.39 }
17.40
17.41 .nav > li > a {
17.42 - display: block;
17.43 + display: inline-block;
17.44 }
17.45
17.46 .nav > li > a:hover,
17.47 @@ -4625,7 +4626,7 @@
17.48
17.49 .navbar .nav > li > a {
17.50 float: none;
17.51 - padding: 10px 15px 10px;
17.52 + padding: 10px 23px 10px;
17.53 color: #777777;
17.54 text-decoration: none;
17.55 text-shadow: 0 1px 0 #ffffff;
17.56 @@ -5646,7 +5647,7 @@
17.57 display: inline-block;
17.58 padding: 2px 4px;
17.59 font-size: 11.844px;
17.60 - font-weight: bold;
17.61 + font-weight: normal;
17.62 line-height: 14px;
17.63 color: #ffffff;
17.64 text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
18.2 +++ b/chess/src/main/webapp/pages/css/chess-phone-large.css Tue Sep 24 22:20:24 2013 +0200
18.3 @@ -0,0 +1,32 @@
18.4 +/**
18.5 + * The MIT License (MIT)
18.6 + *
18.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
18.8 + *
18.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
18.10 + * of this software and associated documentation files (the "Software"), to deal
18.11 + * in the Software without restriction, including without limitation the rights
18.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18.13 + * copies of the Software, and to permit persons to whom the Software is
18.14 + * furnished to do so, subject to the following conditions:
18.15 + *
18.16 + * The above copyright notice and this permission notice shall be included in
18.17 + * all copies or substantial portions of the Software.
18.18 + *
18.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
18.25 + * THE SOFTWARE.
18.26 + */
18.27 +table.board td {
18.28 + padding: 4px;
18.29 + width: 28px;
18.30 + height: 28px;
18.31 + font-size: 2em;
18.32 +}
18.33 +h1 {
18.34 + font-size: 15px;
18.35 +}
18.36 \ No newline at end of file
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
19.2 +++ b/chess/src/main/webapp/pages/css/chess-phone-small.css Tue Sep 24 22:20:24 2013 +0200
19.3 @@ -0,0 +1,32 @@
19.4 +/**
19.5 + * The MIT License (MIT)
19.6 + *
19.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
19.8 + *
19.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
19.10 + * of this software and associated documentation files (the "Software"), to deal
19.11 + * in the Software without restriction, including without limitation the rights
19.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
19.13 + * copies of the Software, and to permit persons to whom the Software is
19.14 + * furnished to do so, subject to the following conditions:
19.15 + *
19.16 + * The above copyright notice and this permission notice shall be included in
19.17 + * all copies or substantial portions of the Software.
19.18 + *
19.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19.25 + * THE SOFTWARE.
19.26 + */
19.27 +table.board td {
19.28 + padding: 4px;
19.29 + width: 24px;
19.30 + height: 24px;
19.31 + font-size: 1.6em;
19.32 +}
19.33 +h1 {
19.34 + font-size: 12px;
19.35 +}
19.36 \ No newline at end of file
20.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
20.2 +++ b/chess/src/main/webapp/pages/css/chess-tablet-large.css Tue Sep 24 22:20:24 2013 +0200
20.3 @@ -0,0 +1,32 @@
20.4 +/**
20.5 + * The MIT License (MIT)
20.6 + *
20.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
20.8 + *
20.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
20.10 + * of this software and associated documentation files (the "Software"), to deal
20.11 + * in the Software without restriction, including without limitation the rights
20.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20.13 + * copies of the Software, and to permit persons to whom the Software is
20.14 + * furnished to do so, subject to the following conditions:
20.15 + *
20.16 + * The above copyright notice and this permission notice shall be included in
20.17 + * all copies or substantial portions of the Software.
20.18 + *
20.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20.25 + * THE SOFTWARE.
20.26 + */
20.27 +table.board td {
20.28 + padding: 8px;
20.29 + width: 42px;
20.30 + height: 42px;
20.31 + font-size: 3em;
20.32 +}
20.33 +h1 {
20.34 + font-size: 22px;
20.35 +}
20.36 \ No newline at end of file
21.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
21.2 +++ b/chess/src/main/webapp/pages/css/chess-tablet-small.css Tue Sep 24 22:20:24 2013 +0200
21.3 @@ -0,0 +1,32 @@
21.4 +/**
21.5 + * The MIT License (MIT)
21.6 + *
21.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
21.8 + *
21.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
21.10 + * of this software and associated documentation files (the "Software"), to deal
21.11 + * in the Software without restriction, including without limitation the rights
21.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21.13 + * copies of the Software, and to permit persons to whom the Software is
21.14 + * furnished to do so, subject to the following conditions:
21.15 + *
21.16 + * The above copyright notice and this permission notice shall be included in
21.17 + * all copies or substantial portions of the Software.
21.18 + *
21.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21.25 + * THE SOFTWARE.
21.26 + */
21.27 +table.board td {
21.28 + padding: 6px;
21.29 + width: 34px;
21.30 + height: 34px;
21.31 + font-size: 2.4em;
21.32 +}
21.33 +h1 {
21.34 + font-size: 18px;
21.35 +}
21.36 \ No newline at end of file
22.1 --- a/chess/src/main/webapp/pages/css/chess.css Tue Sep 24 21:08:15 2013 +0200
22.2 +++ b/chess/src/main/webapp/pages/css/chess.css Tue Sep 24 22:20:24 2013 +0200
22.3 @@ -22,42 +22,103 @@
22.4 * THE SOFTWARE.
22.5 */
22.6 /** main chess style **/
22.7 +#apptitle {
22.8 + font-size: 20px;
22.9 +}
22.10 .log {
22.11 - overflow-x: hidden;
22.12 - overflow-y: scroll;
22.13 - max-height: 450px;
22.14 - border:1px solid #eeeeee;
22.15 - background-color: white;
22.16 + margin-bottom: 10px;
22.17 +}
22.18 +table.board td {
22.19 + border: 1px solid black;
22.20 + padding:10px;
22.21 + width: 56px;
22.22 + height: 56px;
22.23 + vertical-align: middle;
22.24 + text-align: center;
22.25 + font-size:4em;
22.26 +}
22.27 +table.board td.row-label, table.board td.col-label {
22.28 + font-size: 2em;
22.29 + border:none;
22.30 + width:20px;
22.31 +}
22.32 +table.board td.col-label {
22.33 + height:20px;
22.34 }
22.35 .container {
22.36 - margin:10px;
22.37 + margin:10px;
22.38 }
22.39 -stable.board {
22.40 - width: 100%;
22.41 -}
22.42 -table.board {
22.43 - font-size:4em;
22.44 -}
22.45 -table.board td {
22.46 - border: 1px solid black;
22.47 - padding:10px;
22.48 - width:55px;
22.49 - height:55px;
22.50 - vertical-align: middle;
22.51 - text-align: center;
22.52 -}
22.53 +
22.54 table.board td.white {
22.55 - background-color: white;
22.56 + background-color: #D0D0D0;
22.57 }
22.58 table.board td.black {
22.59 - background-color: #B0B0B0;
22.60 + background-color: #A0A0A0;
22.61 }
22.62 table.board td.selected {
22.63 - background-color: #B000B0;
22.64 + background-color: #bce8f1;
22.65 }
22.66 table.board td.accessible {
22.67 - background-color: #00B0B0;
22.68 + background-color: #a9dba9;
22.69 +}
22.70 +table.board td.pending {
22.71 + background-color: #dbc59e;
22.72 }
22.73 .figure {
22.74 - cursor: pointer;
22.75 -}
22.76 \ No newline at end of file
22.77 + cursor: pointer;
22.78 +}
22.79 +.but-orientation {
22.80 + margin-top:20px;
22.81 +}
22.82 +h3.log-h {
22.83 + border-top:1px solid silver;
22.84 +}
22.85 +.badge-status {
22.86 + display:inline-block;
22.87 + margin-left:20px;
22.88 + padding:5px;
22.89 + font-size:1em;
22.90 + text-shadow: none;
22.91 +}
22.92 +.badge-white-turn {
22.93 + font-size: 1em;
22.94 + padding:4px;
22.95 + background-color: white;
22.96 + color:black;
22.97 + text-shadow: none;
22.98 + border:1px solid black;
22.99 + font-weight: normal;
22.100 + display: inline-block;
22.101 + margin-left: 38px;
22.102 +}
22.103 +.badge-black-turn {
22.104 + font-size: 1em;
22.105 + padding:4px;
22.106 + background-color: black;
22.107 + color:white;
22.108 + text-shadow: none;
22.109 + border:1px solid black;
22.110 + font-weight: normal;
22.111 + display: inline-block;
22.112 + margin-left: 38px;
22.113 +}
22.114 +.btn {text-shadow: none;}
22.115 +.select {line-height: inherit;}
22.116 +.uneditable-input {
22.117 + margin-left: 0;
22.118 + color: black;
22.119 +}
22.120 +span.myturn {
22.121 + display: inline-block;
22.122 + position:relative;
22.123 + left:23px;
22.124 + padding:3px;
22.125 +}
22.126 +.whitePiece {
22.127 + text-shadow: -1px -1px 0 #000, 1px -1px 0 #000, -1px 1px 0 #000, 1px 1px 0 #000;
22.128 + color: white;
22.129 +}
22.130 +h1 {
22.131 + font-size: 29px;
22.132 + line-height: initial;
22.133 +}
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
23.2 +++ b/chess/src/main/webapp/pages/css/spinner.css Tue Sep 24 22:20:24 2013 +0200
23.3 @@ -0,0 +1,114 @@
23.4 +/**
23.5 + * The MIT License (MIT)
23.6 + *
23.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
23.8 + *
23.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
23.10 + * of this software and associated documentation files (the "Software"), to deal
23.11 + * in the Software without restriction, including without limitation the rights
23.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
23.13 + * copies of the Software, and to permit persons to whom the Software is
23.14 + * furnished to do so, subject to the following conditions:
23.15 + *
23.16 + * The above copyright notice and this permission notice shall be included in
23.17 + * all copies or substantial portions of the Software.
23.18 + *
23.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23.25 + * THE SOFTWARE.
23.26 + */
23.27 +/** chess cube style **/
23.28 +
23.29 +#chesscube {
23.30 + margin: 1em auto;
23.31 + -webkit-perspective: 1200px;
23.32 + perspective: 1200px;
23.33 + position: fixed;
23.34 + z-index: -100;
23.35 + bottom:100px;
23.36 + right: 100px;
23.37 + width: 160px;
23.38 + height: 160px;
23.39 + transition: opacity 1s;
23.40 +}
23.41 +
23.42 +#spinner div {
23.43 + position: fixed;
23.44 + width: 160px;
23.45 + height: 160px;
23.46 + border: 1px solid #ccc;
23.47 + background: rgba(255,255,155,0.8);
23.48 + text-align: center;
23.49 + line-height: 160px;
23.50 + font-size: 120px;
23.51 + -webkit-box-shadow: inset 0 0 40px rgba(0,0,0,0.4);
23.52 + box-shadow: inset 0 0 40px rgba(0,0,0,0.4);
23.53 +}
23.54 +
23.55 +#spinner div:nth-child(1) {
23.56 + -webkit-transform: translateZ(80px);
23.57 + transform: translateZ(80px);
23.58 +}
23.59 +#spinner div:nth-child(2) {
23.60 + -webkit-transform: rotateY(90deg) translateZ(80px);
23.61 + transform: rotateY(90deg) translateZ(80px);
23.62 +}
23.63 +#spinner div:nth-child(3) {
23.64 + -webkit-transform: rotateY(90deg) rotateX(90deg) translateZ(80px);
23.65 + transform: rotateY(90deg) rotateX(90deg) translateZ(80px);
23.66 +}
23.67 +#spinner div:nth-child(4) {
23.68 + -webkit-transform: rotateY(180deg) rotateZ(90deg) translateZ(80px);
23.69 + transform: rotateY(180deg) rotateZ(90deg) translateZ(80px);
23.70 +}
23.71 +#spinner div:nth-child(5) {
23.72 + -webkit-transform: rotateY(-90deg) rotateZ(90deg) translateZ(80px);
23.73 + transform: rotateY(-90deg) rotateZ(90deg) translateZ(80px);
23.74 +}
23.75 +#spinner div:nth-child(6) {
23.76 + -webkit-transform: rotateX(-90deg) translateZ(80px);
23.77 + transform: rotateX(-90deg) translateZ(80px);
23.78 +}
23.79 +
23.80 +@-webkit-keyframes spincube {
23.81 + from,to { }
23.82 + 16% { -webkit-transform: rotateY(-90deg); }
23.83 + 33% { -webkit-transform: rotateY(-90deg) rotateZ(90deg); }
23.84 + 50% { -webkit-transform: rotateY(180deg) rotateZ(90deg); }
23.85 + 66% { -webkit-transform: rotateY(90deg) rotateX(90deg); }
23.86 + 83% { -webkit-transform: rotateX(90deg); }
23.87 +}
23.88 +
23.89 +@keyframes spincube {
23.90 + from,to { }
23.91 + 16% { transform: rotateY(-90deg); }
23.92 + 33% { transform: rotateY(-90deg) rotateZ(90deg); }
23.93 + 50% { transform: rotateY(180deg) rotateZ(90deg); }
23.94 + 66% { transform: rotateY(90deg) rotateX(90deg); }
23.95 + 83% { transform: rotateX(90deg); }
23.96 +}
23.97 +
23.98 +#spinner {
23.99 + -webkit-animation-name: spincube;
23.100 + -webkit-animation-timing-function: ease-in-out;
23.101 + -webkit-animation-iteration-count: infinite;
23.102 + -webkit-animation-duration: 12s;
23.103 + -webkit-transform-style: preserve-3d;
23.104 + -webkit-transform-origin: 80px 80px 0;
23.105 + animation-name: spincube;
23.106 + animation-timing-function: ease-in-out;
23.107 + animation-iteration-count: infinite;
23.108 + animation-duration: 12s;
23.109 + transform-style: preserve-3d;
23.110 + transform-origin: 80px 80px 0;
23.111 +}
23.112 +
23.113 +@media (max-width: 767px) {
23.114 + #chesscube {
23.115 + opacity: 0;
23.116 + }
23.117 +}
24.1 --- a/chess/src/main/webapp/pages/index.html Tue Sep 24 21:08:15 2013 +0200
24.2 +++ b/chess/src/main/webapp/pages/index.html Tue Sep 24 22:20:24 2013 +0200
24.3 @@ -25,107 +25,186 @@
24.4 -->
24.5 <!DOCTYPE html>
24.6 <html lang="en">
24.7 -<head>
24.8 - <meta charset="utf-8">
24.9 - <title>Chess Client</title>
24.10 - <meta name="viewport" content="width=device-width, initial-scale=1.0">
24.11 - <meta name="description" content="">
24.12 - <meta name="author" content="">
24.13 + <head>
24.14 + <meta charset="utf-8">
24.15 + <title>Chess Client</title>
24.16 + <meta name="viewport" content="width=device-width, initial-scale=1.0">
24.17 + <meta name="description" content="">
24.18 + <meta name="author" content="">
24.19
24.20 - <!-- Le styles -->
24.21 - <link href="./css/bootstrap.css" rel="stylesheet">
24.22 - <link href="./css/bootstrap-responsive.css" rel="stylesheet">
24.23 - <link href="./css/chess.css" rel="stylesheet">
24.24 -</head>
24.25 -<body>
24.26 - <div class="navbar">
24.27 - <div class="navbar-inner">
24.28 - <a class="brand" href="#">Chess Game</a>
24.29 - <ul class="nav">
24.30 - <li class="active"><a href="#">My Game</a></li>
24.31 - <li><a href="#">New game</a></li>
24.32 - <li><a href="#">View games</a></li>
24.33 - <li><a href="#">Blah..</a></li>
24.34 - </ul>
24.35 - <form class="navbar-search pull-right">
24.36 - <input type="text" class="search-query" placeholder="Search">
24.37 - </form>
24.38 - </div>
24.39 - </div>
24.40 - <div class="container-fluid">
24.41 - <div class="row-fluid">
24.42 - <div class="span9">
24.43 - <h1>My game</h1>
24.44 - <div data-bind="visible: blackTurn">Black's turn</div>
24.45 - <table class="board">
24.46 - <tbody data-bind="foreach: rows">
24.47 - <tr >
24.48 - <!-- ko foreach: columns -->
24.49 - <td data-bind="click: $root.selected, css: squareColor" >
24.50 - <span data-bind='html: pieceEntity'></span>
24.51 - </td>
24.52 - <!-- /ko -->
24.53 - </tr>
24.54 - </tbody>
24.55 - </table>
24.56 - <div data-bind="visible: whiteTurn">White's turn</div>
24.57 - </div>
24.58 - <div class="span2 offset1">
24.59 - <h2>Game Log</h2>
24.60 - <div class="log">
24.61 - <table class="table table-striped log-table">
24.62 - <thead>
24.63 - <tr>
24.64 - <th>#</th>
24.65 - <th>Move</th>
24.66 - </tr>
24.67 - </thead>
24.68 - <tbody>
24.69 - <tr>
24.70 - <td>10</td>
24.71 - <td>Move</td>
24.72 - </tr>
24.73 - <tr>
24.74 - <td>9</td>
24.75 - <td>Move</td>
24.76 - </tr>
24.77 - <tr>
24.78 - <td>8</td>
24.79 - <td>Move</td>
24.80 - </tr>
24.81 - <tr>
24.82 - <td>7</td>
24.83 - <td>Move</td>
24.84 - </tr>
24.85 - <tr>
24.86 - <td>6</td>
24.87 - <td>Move</td>
24.88 - </tr>
24.89 - <tr>
24.90 - <td>5</td>
24.91 - <td>Move</td>
24.92 - </tr>
24.93 - <tr>
24.94 - <td>4</td>
24.95 - <td>Move</td>
24.96 - </tr>
24.97 - <tr>
24.98 - <td>3</td>
24.99 - <td>Move</td>
24.100 - </tr>
24.101 - <tr>
24.102 - <td>2</td>
24.103 - <td>Move</td>
24.104 - </tr>
24.105 - <tr>
24.106 - <td>1</td>
24.107 - <td>Move</td>
24.108 - </tr>
24.109 - </tbody>
24.110 - </table>
24.111 - </div>
24.112 - </div>
24.113 - </div>
24.114 - </div>
24.115 -</body>
24.116 -</html>
24.117 \ No newline at end of file
24.118 + <!-- Le styles -->
24.119 + <link href="./css/bootstrap.css" rel="stylesheet">
24.120 + <link href="./css/bootstrap-responsive.css" rel="stylesheet">
24.121 + <link href="./css/chess.css" rel="stylesheet">
24.122 + <!-- Target tablets -->
24.123 + <link href="./css/chess-tablet-large.css" media="(min-width:560px) and (max-width:710px)" rel="stylesheet" />
24.124 + <link href="./css/chess-tablet-small.css" media="(min-width:460px) and (max-width:560px)" rel="stylesheet" />
24.125 + <!-- Target phones -->
24.126 + <link href="./css/chess-phone-large.css" media="(min-width:370px) and (max-width:460px)" rel="stylesheet" />
24.127 + <link href="./css/chess-phone-small.css" media="(max-width:370px)" rel="stylesheet" />
24.128 + <link href="./css/spinner.css" rel="stylesheet">
24.129 + </head>
24.130 + <body>
24.131 + <div class="navbar">
24.132 + <div class="navbar-inner">
24.133 + <a id="apptitle" class="brand" data-bind="css: { active: settingsActive }, click: activateSettings" href="#">JavaOne Chess</a>
24.134 + <ul class="nav" data-bind="foreach: boards">
24.135 + <li data-bind="css: { active: active }, click: $root.activateGame">
24.136 + <span data-bind="visible: myTurn" class="badge badge-warning myturn">↪</span>
24.137 + <span data-bind="visible: justObserving" class="badge myturn">∞</span>
24.138 + <a href="#" data-bind="text: title"></a>
24.139 + </li>
24.140 + </ul>
24.141 + </div>
24.142 + </div>
24.143 + <div data-bind="template: { name: 'render-games', data: viewGames }"></div>
24.144 + <div data-bind="template: { name: 'render-settings', data: settings, if : settingsActive }"></div>
24.145 + <div data-bind="template: { name: 'render-board', data: selectedBoard, if : selectedBoard }"></div>
24.146 +
24.147 + <script type="text/html" id="render-board">
24.148 + <div class="container-fluid">
24.149 + <div class="row-fluid">
24.150 + <div class="span12">
24.151 + <h1><span data-bind="text: status"></span></h1>
24.152 + <p style="position: relative; left: 0px; top: 0px; height: 25px">
24.153 + <span data-bind="visible: blackTurn" class="badge badge-black-turn">Black's turn</span>
24.154 + <span data-bind="visible: whiteTurn" class="badge badge-white-turn">White's turn</span>
24.155 + <span data-bind="text: alertMessage" class="badge badge-warning badge-status"></span>
24.156 + </p>
24.157 + <p>
24.158 + <table class="board">
24.159 + <tbody>
24.160 + <!-- ko foreach: rows -->
24.161 + <tr>
24.162 + <td class="row-label">
24.163 + <span data-bind='text: y'></span>
24.164 + </td>
24.165 + <!-- ko foreach: columns -->
24.166 + <td data-bind="click: $parents[1].selected, css: squareColor" >
24.167 + <span data-bind='html: pieceEntity, css: { blackPiece: pieceColor() === "B", whitePiece: pieceColor() === "W" }' class="figure"></span>
24.168 + </td>
24.169 + <!-- /ko -->
24.170 + </tr>
24.171 + <!-- /ko -->
24.172 + <tr>
24.173 + <td class="col-label"></td>
24.174 + <!-- ko foreach: columnNames -->
24.175 + <td class="row-label">
24.176 + <span data-bind='text: $data'></span>
24.177 + </td>
24.178 + <!-- /ko -->
24.179 + </tr>
24.180 + </tbody>
24.181 + </table>
24.182 + <button data-bind="click: rotateBoard" class="but-orientation">Rotate Board</button>
24.183 + <button data-bind="click: $root.leave" class="but-orientation">Leave Game</button>
24.184 + </p>
24.185 + </div>
24.186 + </div>
24.187 + <div class="row-fluid">
24.188 + <div class="span12 log-div">
24.189 + <h3 class="log-h">Game Log</h3>
24.190 + <div class="log">
24.191 + <div data-bind="foreach: moves">
24.192 + <span>
24.193 + <!-- ko if: whiteMove -->
24.194 + <span data-bind="text: round" class="badge"></span>
24.195 + <!-- /ko -->
24.196 + <a href="#" data-bind="html: html, click: $parent.showPosition"></a>,
24.197 + </span>
24.198 + </div>
24.199 + </div>
24.200 + </div>
24.201 + </div>
24.202 + </div>
24.203 + </script>
24.204 +
24.205 + <script type="text/html" id="render-settings">
24.206 + <div class="container-fluid">
24.207 + <h3>Connection Settings</h3>
24.208 + <p>
24.209 + Status: <span data-bind="text: $root.status"></span>
24.210 + </p>
24.211 + <p>
24.212 + Name:
24.213 + <input type="text" data-bind="value: username, enable: $root.disconnected, valueUpdate: 'afterkeydown'"
24.214 + class="input-small" placeholder="Name"></input>
24.215 + Password:
24.216 + <input type="password" data-bind="value: password, enable: $root.disconnected, valueUpdate: 'afterkeydown'"
24.217 + class="input-small" placeholder="Password"></input>
24.218 + </p>
24.219 + <br/>
24.220 + <p>
24.221 + Chess server URL:
24.222 + <input data-bind="value: url, enable: $root.disconnected" class="inpu-xlarge"></input>
24.223 + </p>
24.224 + <p>
24.225 + <button data-bind="click: $root.reconnect, enable: ($root.disconnected() && validCredentials()) ">Connect</button>
24.226 + <button data-bind="click: $root.disconnect, enable: $root.connected">Disconnect</button>
24.227 + </p>
24.228 + </div>
24.229 + <div id="chesscube">
24.230 + <div id="spinner">
24.231 + <div>♔</div>
24.232 + <div>♛</div>
24.233 + <div>♖</div>
24.234 + <div>♝</div>
24.235 + <div>♘</div>
24.236 + <div>♟</div>
24.237 + </div>
24.238 + </div>
24.239 + </script>
24.240 +
24.241 + <script type="text/html" id="render-games">
24.242 + <div class="container-fluid">
24.243 + <div data-bind="visible: $root.viewGamesActive ">
24.244 + <h3>List of Games</h3>
24.245 + <p>
24.246 + <a href="#" data-bind="click: $root.refreshGames">Refresh</a>
24.247 + </p>
24.248 + <!-- ko if: anyOwnGame -->
24.249 + <h5>Own Games</h5>
24.250 + <div data-bind="foreach: own">
24.251 + <div class="input-append">
24.252 + <input type="text" data-bind="value: description" disabled></input>
24.253 + <button class="btn" data-bind="click: $root.joinGame">
24.254 + <span data-bind="ifnot: pendingPlayer">Show</span>
24.255 + <span data-bind="if: pendingPlayer">Challenge Yourself</span>
24.256 + </button>
24.257 + </div>
24.258 + <br/>
24.259 + </div>
24.260 + <!-- /ko -->
24.261 + <h5>Other Games</h5>
24.262 + <div data-bind="foreach: other">
24.263 + <div class="input-append">
24.264 + <input type="text" data-bind="value: description" disabled></input>
24.265 + <!-- ko if: open -->
24.266 + <button class="btn btn-success" data-bind="click: $root.joinGame">Join</button>
24.267 + <!-- /ko -->
24.268 + <button class="btn" data-bind="click: $root.observeGame">Observe</button>
24.269 + </div>
24.270 + <br/>
24.271 + </div>
24.272 + <h3>New game</h3>
24.273 + <div class="input-append" class="select">
24.274 + <select data-bind="value: selectedColor">
24.275 + <option value="W">White</option>
24.276 + <option value="B">Black</option>
24.277 + </select>
24.278 + <button data-bind="click: $root.createGame" class="btn btn-success" >Create Game!</button>
24.279 + </div>
24.280 + </div>
24.281 + </div>
24.282 + </script>
24.283 + <center data-bind="visible: false">
24.284 + <img src="DukeHTML.png" width="320" height="200" alt="Loading...">
24.285 + <h3>Initializing the virtual machine...</h3>
24.286 + </center>
24.287 + <script type="text/javascript" src="bck2brwsr.js"></script>
24.288 + <script>
24.289 + var vm = bck2brwsr('${project.build.finalName}.jar');
24.290 + vm.loadClass('com.oracle.chess.client.htmljava.LoadMain');
24.291 + </script>
24.292 + </body>
24.293 +</html>
25.1 Binary file chess/src/main/webapp/pages/sounds/check.mp3 has changed
26.1 Binary file chess/src/main/webapp/pages/sounds/checkmate.mp3 has changed
27.1 Binary file chess/src/main/webapp/pages/sounds/move.mp3 has changed
28.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
28.2 +++ b/chess/src/test/java/com/oracle/chess/client/htmljava/BoardModelTest.java Tue Sep 24 22:20:24 2013 +0200
28.3 @@ -0,0 +1,537 @@
28.4 +/**
28.5 + * The MIT License (MIT)
28.6 + *
28.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
28.8 + *
28.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
28.10 + * of this software and associated documentation files (the "Software"), to deal
28.11 + * in the Software without restriction, including without limitation the rights
28.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28.13 + * copies of the Software, and to permit persons to whom the Software is
28.14 + * furnished to do so, subject to the following conditions:
28.15 + *
28.16 + * The above copyright notice and this permission notice shall be included in
28.17 + * all copies or substantial portions of the Software.
28.18 + *
28.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
28.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28.25 + * THE SOFTWARE.
28.26 + */
28.27 +package com.oracle.chess.client.htmljava;
28.28 +
28.29 +import com.oracle.chess.client.htmljava.BoardModel.PieceType;
28.30 +import java.util.Arrays;
28.31 +import java.util.Collections;
28.32 +import java.util.List;
28.33 +import static org.testng.Assert.*;
28.34 +import org.testng.annotations.Test;
28.35 +
28.36 +/**
28.37 + *
28.38 + * @author Jaroslav Tulach <jtulach@netbeans.org>
28.39 + */
28.40 +public class BoardModelTest {
28.41 +
28.42 + public BoardModelTest() {
28.43 + }
28.44 +
28.45 + @Test public void whiteRockLeftBottom() {
28.46 + Board b = Rules.createBoard();
28.47 + Row bottom = b.getRows().get(7);
28.48 + Square left = bottom.getColumns().get(0);
28.49 + assertEquals(left.getPiece(), PieceType.ROCK, "Rock is on bottom left square");
28.50 + assertEquals(left.getPieceColor(), Color.W, "It is white");
28.51 + assertEquals(left.getColor(), Color.B, "Square is black");
28.52 + }
28.53 +
28.54 + @Test public void e2e4e7e6() {
28.55 + Board b = Rules.createBoard();
28.56 + b.setGameId("myId");
28.57 + setPlayer(b, Color.W);
28.58 + assertEquals(b.getTurn(), Color.W);
28.59 +
28.60 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.61 + assertNotNull(e2);
28.62 + BoardModel.selected(b, e2);
28.63 + assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
28.64 +
28.65 + Square e4 = BoardModel.findSquare(b, 'E', 4);
28.66 + assertNotNull(e4);
28.67 +
28.68 + BoardModel.selected(b, e4);
28.69 +
28.70 + assertTrue(e4.isPending(), "e4 marked as pending move");
28.71 + assertNull(e2.getPiece(), "No pawn at e2");
28.72 +
28.73 + // ignore all other figures than the two pawns
28.74 + BoardModel.moveResponse(b, null, Collections.singletonList("Pe4"),
28.75 + Collections.singletonList("Pe7"), Color.B, null
28.76 + );
28.77 +
28.78 + assertFalse(e4.isPending(), "e4 now the move is real");
28.79 + assertNull(e2.getPiece(), "No pawn at e2");
28.80 + assertEquals(e4.getPiece(), BoardModel.PieceType.PAWN, "Pawn moved successfully");
28.81 + assertNull(BoardModel.findSelectedSquare(b), "No square selected");
28.82 +
28.83 + BoardModel.selected(b, e4);
28.84 + assertNull(BoardModel.findSelectedSquare(b), "No square selected, it is blacks turn");
28.85 +
28.86 + List<Move> mvs1 = b.getMoves();
28.87 + assertEquals(1, mvs1.size(), "First move was made: " + mvs1);
28.88 + Move firstMove = mvs1.get(0);
28.89 + assertEquals(firstMove.getPiece(), PieceType.PAWN, "Moving with pawn");
28.90 + assertEquals(firstMove.getRound(), 1, "First round of moves");
28.91 + assertEquals(firstMove.getTurn(), Color.W, "Moved by white");
28.92 + assertTrue(firstMove.isWhiteMove(), "Really moved by white");
28.93 +
28.94 + assertTrue(b.isBlackTurn(), "black's turn");
28.95 +
28.96 +
28.97 + Square e7 = BoardModel.findSquare(b, 'E', 7);
28.98 + BoardModel.selected(b, e7);
28.99 + assertNull(BoardModel.findSelectedSquare(b), "Can't select anything when I am white player");
28.100 +
28.101 + Move blackMv = BoardModel.MoveImpl.valueOf("E7E6");
28.102 + BoardModel.moveUpdate(b, blackMv,
28.103 + Collections.singletonList("PE4"),
28.104 + Collections.singletonList("PE6"),
28.105 + Color.W, null
28.106 + );
28.107 +
28.108 + assertNull(e7.getPiece(), "Piece has been moved");
28.109 +
28.110 + List<Move> mvs = b.getMoves();
28.111 + assertEquals(2, mvs.size(), "There are two moves now: " + mvs);
28.112 + Move secondMove = mvs.get(1);
28.113 + assertEquals(secondMove.getPiece(), PieceType.PAWN, "Moving with pawn");
28.114 + assertEquals(secondMove.getRound(), 1, "Still 1st round of moves");
28.115 + assertEquals(secondMove.getTurn(), Color.B, "Moved by black");
28.116 + assertFalse(secondMove.isWhiteMove(), "Really moved by black");
28.117 + }
28.118 +
28.119 + @Test public void unselect() {
28.120 + Board b = Rules.createBoard();
28.121 + b.setGameId("myId");
28.122 + setPlayer(b, Color.W);
28.123 + assertEquals(b.getTurn(), Color.W);
28.124 +
28.125 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.126 + assertNotNull(e2);
28.127 + BoardModel.selected(b, e2);
28.128 + assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
28.129 +
28.130 + BoardModel.selected(b, e2);
28.131 + assertNull(BoardModel.findSelectedSquare(b), "E2 is unselected");
28.132 +
28.133 + for (Row row : b.getRows()) {
28.134 + for (Square s : row.getColumns()) {
28.135 + assertFalse(s.isAccessible(), "No square is accessible anymore: " + s);
28.136 + }
28.137 + }
28.138 + }
28.139 +
28.140 + @Test public void discaredMove() {
28.141 + Board b = Rules.createBoard();
28.142 + b.setGameId("myId");
28.143 + setPlayer(b, Color.W);
28.144 + assertEquals(b.getTurn(), Color.W);
28.145 +
28.146 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.147 + assertNotNull(e2);
28.148 + BoardModel.selected(b, e2);
28.149 + assertEquals(BoardModel.findSelectedSquare(b), e2, "E2 is selected");
28.150 +
28.151 + Square e4 = BoardModel.findSquare(b, 'E', 4);
28.152 + assertNotNull(e4);
28.153 +
28.154 + BoardModel.selected(b, e4);
28.155 +
28.156 + assertTrue(e4.isPending(), "e4 marked as pending move");
28.157 + assertNull(e2.getPiece(), "No pawn at e2");
28.158 +
28.159 + assertEquals(b.getMoves().size(), 1, "One move recorded");
28.160 + assertEquals(b.getMoves().get(0), b.getPendingMove(), "Pending move is waiting");
28.161 +
28.162 + // ignore all other figures than the two pawns
28.163 + BoardModel.moveResponse(b, "No way, can't play like this", Collections.singletonList("PE2"),
28.164 + Collections.singletonList("Pe7"), Color.W, null
28.165 + );
28.166 +
28.167 + assertEquals(b.getAlertMessage(), "No way, can't play like this");
28.168 + assertNull(e4.getPiece(), "No piece on e4");
28.169 + assertEquals(e2.getPiece(), PieceType.PAWN, "Pawn is back");
28.170 +
28.171 + assertEquals(b.getMoves().size(), 0, "Move was discarded");
28.172 + assertNull(b.getPendingMove(), "No pending moves");
28.173 + }
28.174 +
28.175 + @Test public void cantSelectEmptySquare() {
28.176 + Board b = Rules.createBoard();
28.177 + Square e3 = BoardModel.findSquare(b, 'E', 3);
28.178 + assertNotNull(e3);
28.179 + BoardModel.selected(b, e3);
28.180 + assertNull(BoardModel.findSelectedSquare(b), "No square is selected");
28.181 + }
28.182 +
28.183 + @Test public void cantTakeOwnPiece() {
28.184 + Board b = Rules.createBoard();
28.185 + setPlayer(b, Color.W);
28.186 + Square e1 = BoardModel.findSquare(b, 'E', 1);
28.187 + assertNotNull(e1);
28.188 + BoardModel.selected(b, e1);
28.189 + assertEquals(BoardModel.findSelectedSquare(b), e1, "E1 is selected");
28.190 +
28.191 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.192 + assertNotNull(e2);
28.193 +
28.194 + BoardModel.selected(b, e2);
28.195 +
28.196 + assertNotNull(e1.getPiece(), "King remains at e1");
28.197 + assertEquals(e2.getPiece(), BoardModel.PieceType.PAWN, "Pawn remains");
28.198 + assertEquals(BoardModel.findSelectedSquare(b), e2, "e2 now selected");
28.199 +
28.200 + }
28.201 +
28.202 + @Test public void knightMustMoveToF3() {
28.203 + Board b = Rules.createBoard();
28.204 + setPlayer(b, Color.W);
28.205 + Square g1 = BoardModel.findSquare(b, 'G', 1);
28.206 + BoardModel.selected(b, g1);
28.207 +
28.208 + Square f3 = BoardModel.findSquare(b, 'F', 3);
28.209 + assertTrue(f3.isAccessible(), "This is a field where knight can move");
28.210 +
28.211 + Square g3 = BoardModel.findSquare(b, 'G', 3);
28.212 + assertFalse(g3.isAccessible(), "Not a place for knight");
28.213 +
28.214 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.215 + assertFalse(e2.isAccessible(), "Not a place either, occupied");
28.216 +
28.217 + BoardModel.selected(b, g3);
28.218 +
28.219 + assertNull(g3.getPiece(), "No figure was moved");
28.220 + assertTrue(g1.isSelected(), "Original square still selected");
28.221 +
28.222 + BoardModel.selected(b, f3);
28.223 +
28.224 + assertEquals(f3.getPiece(), PieceType.KNIGHT, "Moved");
28.225 + assertFalse(g3.isSelected(), "No longer selected");
28.226 + }
28.227 +
28.228 + @Test public void pawnCanTakeToSide() {
28.229 + Board b = Rules.createBoard();
28.230 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.231 + Square e4 = BoardModel.findSquare(b, 'E', 4);
28.232 + Square d7 = BoardModel.findSquare(b, 'D', 7);
28.233 + Square d5 = BoardModel.findSquare(b, 'D', 5);
28.234 +
28.235 + BoardModel.selected(b, e2);
28.236 + BoardModel.selected(b, e4);
28.237 +
28.238 + // ignore all other figures than the two pawns
28.239 + BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
28.240 + Collections.singletonList("PD7"), Color.B, null
28.241 + );
28.242 +
28.243 + setPlayer(b, Color.B);
28.244 +
28.245 + BoardModel.selected(b, d7);
28.246 + BoardModel.selected(b, d5);
28.247 +
28.248 + // ignore all other figures than the two pawns
28.249 + BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
28.250 + Collections.singletonList("PD5"), Color.W, null
28.251 + );
28.252 +
28.253 + setPlayer(b, Color.W);
28.254 +
28.255 + BoardModel.selected(b, e4);
28.256 + assertTrue(d5.isAccessible(), "Can take on d5");
28.257 + BoardModel.selected(b, d5);
28.258 + assertNull(e4.getPiece(), "No pawn on e4");
28.259 + assertEquals(d5.getPieceColor(), Color.W, "White Pawn on d5");
28.260 + }
28.261 +
28.262 + @Test public void pawnCanJumpOnAnother() {
28.263 + Board b = Rules.createBoard();
28.264 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.265 + Square e4 = BoardModel.findSquare(b, 'E', 4);
28.266 + Square d7 = BoardModel.findSquare(b, 'D', 7);
28.267 + Square d5 = BoardModel.findSquare(b, 'D', 5);
28.268 + Square e7 = BoardModel.findSquare(b, 'E', 7);
28.269 + Square e6 = BoardModel.findSquare(b, 'E', 6);
28.270 + Square e5 = BoardModel.findSquare(b, 'E', 5);
28.271 +
28.272 + BoardModel.selected(b, e2);
28.273 + BoardModel.selected(b, e4);
28.274 +
28.275 + // ignore all other figures than the three pawns
28.276 + BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
28.277 + Arrays.asList("PD7", "PE7"), Color.B, null
28.278 + );
28.279 +
28.280 + setPlayer(b, Color.B);
28.281 +
28.282 + BoardModel.selected(b, d7);
28.283 + BoardModel.selected(b, d5);
28.284 +
28.285 + // ignore all other figures than the three pawns
28.286 + BoardModel.moveResponse(b, null, Collections.singletonList("PE4"),
28.287 + Arrays.asList("PD5", "PE7"), Color.W, null
28.288 + );
28.289 +
28.290 + setPlayer(b, Color.W);
28.291 +
28.292 + BoardModel.selected(b, e4);
28.293 + BoardModel.selected(b, e5);
28.294 +
28.295 + // ignore all other figures than the three pawns
28.296 + BoardModel.moveResponse(b, null, Collections.singletonList("PE5"),
28.297 + Arrays.asList("PD5", "PE7"), Color.B, null
28.298 + );
28.299 +
28.300 + setPlayer(b, Color.B);
28.301 +
28.302 + BoardModel.selected(b, e7);
28.303 + assertTrue(e6.isAccessible(), "Can move by one piece");
28.304 + assertFalse(e5.isAccessible(), "Can't move where other pawn is");
28.305 + }
28.306 +
28.307 + @Test public void showFirstMove() {
28.308 + Board b = Rules.createBoard();
28.309 + setPlayer(b, Color.W);
28.310 + Square e2 = BoardModel.findSquare(b, 'E', 2);
28.311 + Square e4 = BoardModel.findSquare(b, 'E', 4);
28.312 + Square d7 = BoardModel.findSquare(b, 'D', 7);
28.313 + Square d5 = BoardModel.findSquare(b, 'D', 5);
28.314 +
28.315 + BoardModel.selected(b, e2);
28.316 + BoardModel.selected(b, e4);
28.317 +
28.318 + // ignore all other figures than the two pawns
28.319 + BoardModel.moveResponse(b, null, Collections.singletonList("Pe4"),
28.320 + Collections.singletonList("PD7"), Color.B, null
28.321 + );
28.322 +
28.323 + Move blackMv = BoardModel.MoveImpl.valueOf("D7D5");
28.324 + BoardModel.moveUpdate(b, blackMv,
28.325 + Collections.singletonList("PE4"),
28.326 + Collections.singletonList("PD5"),
28.327 + Color.W, null
28.328 + );
28.329 +
28.330 +
28.331 + assertEquals(b.getMoves().size(), 2, "Two moves");
28.332 + BoardModel.showPosition(b, b.getMoves().get(0));
28.333 +
28.334 + assertEquals(b.getRows().size(), 8, "Still eight rows");
28.335 + assertEquals(b.getRows().get(0).getColumns().size(), 8, "Eight columns");
28.336 +
28.337 + assertNull(e2.getPiece(), "e2 is empty");
28.338 + assertEquals(e4.getPiece(), PieceType.PAWN, "e4 has pawn");
28.339 + assertEquals(d7.getPiece(), PieceType.PAWN, "d7 has pawn");
28.340 + assertNull(d5.getPiece(), "Second move is not made");
28.341 + assertNull(b.getTurn(), "Nobody to make a move");
28.342 + }
28.343 +
28.344 + @Test public void initialPositionReadFromAServer() {
28.345 + List<String> blacks = Arrays.asList(
28.346 + "Pa7",
28.347 + "Pb7",
28.348 + "Pc7",
28.349 + "Pd7",
28.350 + "Pe7",
28.351 + "Pf7",
28.352 + "Pg7",
28.353 + "Ph7",
28.354 + "Ra8",
28.355 + "Nb8",
28.356 + "Bc8",
28.357 + "Qd8",
28.358 + "Ke8",
28.359 + "Bf8",
28.360 + "Ng8",
28.361 + "Rh8"
28.362 + );
28.363 + List<String> whites = Arrays.asList(
28.364 + "Ra1",
28.365 + "Nb1",
28.366 + "Bc1",
28.367 + "Qd1",
28.368 + "Ke1",
28.369 + "Bf1",
28.370 + "Ng1",
28.371 + "Rh1",
28.372 + "Pa2",
28.373 + "Pb2",
28.374 + "Pc2",
28.375 + "Pd2",
28.376 + "Pe2",
28.377 + "Pf2",
28.378 + "Pg2",
28.379 + "Ph2"
28.380 + );
28.381 +
28.382 + Board b = Rules.createBoard();
28.383 + Rules.initBoard(b, whites, blacks, Color.W);
28.384 +
28.385 + Board b2 = Rules.createBoard();
28.386 + Rules.initBoard(b2);
28.387 +
28.388 + for (int i = 0; i < 7; i++) {
28.389 + for (int j = 0; j < 7; j++) {
28.390 + Square s = b.getRows().get(i).getColumns().get(j);
28.391 + Square s2 = b2.getRows().get(i).getColumns().get(j);
28.392 +
28.393 + assertEquals(s.getPiece(), s2.getPiece(), "Same piece at " + i + "/" + j);
28.394 + assertEquals(s.getPieceColor(), s2.getPieceColor(), "Same piece color at " + i + "/" + j);
28.395 + }
28.396 + }
28.397 + }
28.398 +
28.399 + @Test public void allowSmallRochade() {
28.400 + Board b = Rules.createBoard();
28.401 + setPlayer(b, Color.W);
28.402 + Square f1 = BoardModel.findSquare(b, 'F', 1);
28.403 + f1.setPiece(null);
28.404 + f1.setPieceColor(null);
28.405 + Square g1 = BoardModel.findSquare(b, 'G', 1);
28.406 + g1.setPiece(null);
28.407 + g1.setPieceColor(null);
28.408 + Square e1 = BoardModel.findSquare(b, 'E', 1);
28.409 +
28.410 + BoardModel.selected(b, e1);
28.411 + assertTrue(g1.isAccessible(), "Can do 0-0");
28.412 + }
28.413 +
28.414 + @Test public void allowSmallRochadeForBlack() {
28.415 + Board b = Rules.createBoard();
28.416 + setPlayer(b, Color.B);
28.417 + b.setTurn(Color.B);
28.418 + Square f8 = BoardModel.findSquare(b, 'F', 8);
28.419 + f8.setPiece(null);
28.420 + f8.setPieceColor(null);
28.421 + Square g8 = BoardModel.findSquare(b, 'G', 8);
28.422 + g8.setPiece(null);
28.423 + g8.setPieceColor(null);
28.424 + Square e8 = BoardModel.findSquare(b, 'E', 8);
28.425 +
28.426 + BoardModel.selected(b, e8);
28.427 + assertTrue(g8.isAccessible(), "Can do 0-0");
28.428 + }
28.429 +
28.430 + @Test public void disallowSmallRochadeWhenNoRock() {
28.431 + Board b = Rules.createBoard();
28.432 + setPlayer(b, Color.W);
28.433 + Square f1 = BoardModel.findSquare(b, 'F', 1);
28.434 + f1.setPiece(null);
28.435 + f1.setPieceColor(null);
28.436 + Square g1 = BoardModel.findSquare(b, 'G', 1);
28.437 + g1.setPiece(null);
28.438 + g1.setPieceColor(null);
28.439 + Square h1 = BoardModel.findSquare(b, 'H', 1);
28.440 + h1.setPiece(null);
28.441 + h1.setPieceColor(null);
28.442 + Square e1 = BoardModel.findSquare(b, 'E', 1);
28.443 +
28.444 + BoardModel.selected(b, e1);
28.445 + assertFalse(g1.isAccessible(), "Cannot do 0-0 when there is no rock");
28.446 + }
28.447 +
28.448 + @Test public void disallowSmallRochadeWhenBishop() {
28.449 + Board b = Rules.createBoard();
28.450 + setPlayer(b, Color.W);
28.451 + Square g1 = BoardModel.findSquare(b, 'G', 1);
28.452 + g1.setPiece(null);
28.453 + Square e1 = BoardModel.findSquare(b, 'E', 1);
28.454 +
28.455 + BoardModel.selected(b, e1);
28.456 + assertFalse(g1.isAccessible(), "Cannot do 0-0 when there is bishop");
28.457 + }
28.458 +
28.459 + @Test public void disallowSmallRochadeWhenKnight() {
28.460 + Board b = Rules.createBoard();
28.461 + setPlayer(b, Color.W);
28.462 + Square f1 = BoardModel.findSquare(b, 'F', 1);
28.463 + f1.setPiece(null);
28.464 + Square e1 = BoardModel.findSquare(b, 'E', 1);
28.465 +
28.466 + BoardModel.selected(b, e1);
28.467 + assertFalse(f1.isAccessible(), "Cannot do 0-0 when there is knight");
28.468 + }
28.469 +
28.470 + @Test public void allowBigRochadeForBlack() {
28.471 + Board b = Rules.createBoard();
28.472 + setPlayer(b, Color.B);
28.473 + b.setTurn(Color.B);
28.474 + Square b8 = BoardModel.findSquare(b, 'B', 8);
28.475 + b8.setPiece(null);
28.476 + b8.setPieceColor(null);
28.477 + Square c8 = BoardModel.findSquare(b, 'C', 8);
28.478 + c8.setPiece(null);
28.479 + c8.setPieceColor(null);
28.480 + Square d8 = BoardModel.findSquare(b, 'D', 8);
28.481 + d8.setPiece(null);
28.482 + d8.setPieceColor(null);
28.483 + Square e8 = BoardModel.findSquare(b, 'E', 8);
28.484 +
28.485 + BoardModel.selected(b, e8);
28.486 + assertTrue(c8.isAccessible(), "Can do 0-0-0");
28.487 + }
28.488 +
28.489 + @Test public void enPassant() {
28.490 + Board b = Rules.createBoard();
28.491 + setPlayer(b, Color.B);
28.492 + b.setTurn(Color.B);
28.493 +
28.494 + Square e7 = BoardModel.findSquare(b, 'E', 7);
28.495 + Square e4 = BoardModel.findSquare(b, 'E', 4);
28.496 + movePiece(e7, e4);
28.497 +
28.498 + Move move = new Move();
28.499 + move.setFrom(position('D', 2));
28.500 + move.setTo(position('D', 4));
28.501 + move.setPiece(PieceType.PAWN);
28.502 + b.getMoves().add(move);
28.503 +
28.504 + Square d2 = BoardModel.findSquare(b, 'D', 2);
28.505 + Square d4 = BoardModel.findSquare(b, 'D', 4);
28.506 + movePiece(d2, d4);
28.507 +
28.508 + BoardModel.selected(b, e4);
28.509 +
28.510 + Square e3 = BoardModel.findSquare(b, 'E', 3);
28.511 + assertTrue(e3.isAccessible(), "Obviously can move to e3");
28.512 +
28.513 + Square d3 = BoardModel.findSquare(b, 'D', 3);
28.514 + assertTrue(d3.isAccessible(), "Can also take on d3");
28.515 + }
28.516 +
28.517 + private void movePiece(Square from, Square to) {
28.518 + to.setPiece(from.getPiece());
28.519 + to.setPieceColor(from.getPieceColor());
28.520 + from.setPiece(null);
28.521 + from.setPieceColor(null);
28.522 + }
28.523 +
28.524 + private Position position(char c, int i) {
28.525 + Position p = new Position();
28.526 + p.setX(c);
28.527 + p.setY(i);
28.528 + return p;
28.529 + }
28.530 +
28.531 + private static void setPlayer(Board b, Color c) {
28.532 + b.setWhitePlayer("x");
28.533 + b.setBlackPlayer("y");
28.534 + if (c == Color.B) {
28.535 + b.setPlayer("y");
28.536 + } else {
28.537 + b.setPlayer("x");
28.538 + }
28.539 + }
28.540 +}