1.1 --- a/chess/src/main/java/org/apidesign/html/demo/chess/BoardModel.java Fri Jul 26 17:13:08 2013 +0200
1.2 +++ b/chess/src/main/java/org/apidesign/html/demo/chess/BoardModel.java Fri Jul 26 17:14:25 2013 +0200
1.3 @@ -39,19 +39,24 @@
1.4 if (previoslySelected == null) {
1.5 if (data.getPiece() != null && data.getPieceColor() == b.getTurn()) {
1.6 data.setSelected(true);
1.7 + Rules.computeAccessible(b, data);
1.8 }
1.9 } else {
1.10 - previoslySelected.setSelected(false);
1.11 if (data.getPiece() != null && data.getPieceColor() == previoslySelected.getPieceColor()) {
1.12 previoslySelected.setSelected(false);
1.13 data.setSelected(true);
1.14 + Rules.computeAccessible(b, data);
1.15 return;
1.16 }
1.17 - data.setPieceColor(previoslySelected.getPieceColor());
1.18 - data.setPiece(previoslySelected.getPiece());
1.19 - b.setTurn(b.getTurn() == ColorType.WHITE ? ColorType.BLACK : ColorType.WHITE);
1.20 - previoslySelected.setPiece(null);
1.21 - previoslySelected.setPieceColor(null);
1.22 + if (data.isAccessible()) {
1.23 + previoslySelected.setSelected(false);
1.24 + data.setPieceColor(previoslySelected.getPieceColor());
1.25 + data.setPiece(previoslySelected.getPiece());
1.26 + b.setTurn(b.getTurn() == ColorType.WHITE ? ColorType.BLACK : ColorType.WHITE);
1.27 + previoslySelected.setPiece(null);
1.28 + previoslySelected.setPieceColor(null);
1.29 + Rules.computeAccessible(b, null);
1.30 + }
1.31 }
1.32 }
1.33
1.34 @@ -124,7 +129,8 @@
1.35 @Property(name = "color", type = ColorType.class),
1.36 @Property(name = "x", type = int.class),
1.37 @Property(name = "y", type = int.class),
1.38 - @Property(name = "selected", type = boolean.class)
1.39 + @Property(name = "selected", type = boolean.class),
1.40 + @Property(name = "accessible", type = boolean.class),
1.41 })
1.42 static class PieceImpl {
1.43 @ComputedProperty static String pieceEntity(
1.44 @@ -136,10 +142,15 @@
1.45 return piece.computeEntity(pieceColor);
1.46 }
1.47
1.48 - @ComputedProperty static String squareColor(ColorType color, boolean selected) {
1.49 + @ComputedProperty static String squareColor(
1.50 + ColorType color, boolean selected, boolean accessible
1.51 + ) {
1.52 if (selected) {
1.53 return "selected";
1.54 }
1.55 + if (accessible) {
1.56 + return "accessible";
1.57 + }
1.58
1.59 if (color == null) {
1.60 return "";
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/chess/src/main/java/org/apidesign/html/demo/chess/Rules.java Fri Jul 26 17:14:25 2013 +0200
2.3 @@ -0,0 +1,130 @@
2.4 +/**
2.5 + * The MIT License (MIT)
2.6 + *
2.7 + * Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
2.8 + *
2.9 + * Permission is hereby granted, free of charge, to any person obtaining a copy
2.10 + * of this software and associated documentation files (the "Software"), to deal
2.11 + * in the Software without restriction, including without limitation the rights
2.12 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2.13 + * copies of the Software, and to permit persons to whom the Software is
2.14 + * furnished to do so, subject to the following conditions:
2.15 + *
2.16 + * The above copyright notice and this permission notice shall be included in
2.17 + * all copies or substantial portions of the Software.
2.18 + *
2.19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2.20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2.21 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2.22 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2.23 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2.24 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2.25 + * THE SOFTWARE.
2.26 + */
2.27 +package org.apidesign.html.demo.chess;
2.28 +
2.29 +/** Common chess rules.
2.30 + *
2.31 + * @author Jaroslav Tulach <jtulach@netbeans.org>
2.32 + */
2.33 +class Rules {
2.34 + static void computeAccessible(Board b, Square s) {
2.35 + for (Row r : b.getRows()) {
2.36 + for (Square ts : r.getColumns()) {
2.37 + ts.setAccessible(false);
2.38 + }
2.39 + }
2.40 + if (s == null) {
2.41 + return;
2.42 + }
2.43 +
2.44 + switch (s.getPiece()) {
2.45 + case BISHOP:
2.46 + moveBishop(b, s);
2.47 + break;
2.48 + case KING:
2.49 + computeAccessible(b, s, 1, 1, 1);
2.50 + computeAccessible(b, s, 1, -1, 1);
2.51 + computeAccessible(b, s, -1, -1, 1);
2.52 + computeAccessible(b, s, -1, 1, 1);
2.53 + computeAccessible(b, s, 1, 0, 1);
2.54 + computeAccessible(b, s, 0, -1, 1);
2.55 + computeAccessible(b, s, 0, 1, 1);
2.56 + computeAccessible(b, s, -1, 0, 1);
2.57 + break;
2.58 + case ROCK:
2.59 + moveRock(b, s);
2.60 + break;
2.61 + case QUEEN:
2.62 + moveRock(b, s);
2.63 + moveBishop(b, s);
2.64 + break;
2.65 + case KNIGHT:
2.66 + computeAccessible(b, s, 2, 1, 1);
2.67 + computeAccessible(b, s, 2, -1, 1);
2.68 + computeAccessible(b, s, -2, -1, 1);
2.69 + computeAccessible(b, s, -2, 1, 1);
2.70 + computeAccessible(b, s, 1, 2, 1);
2.71 + computeAccessible(b, s, -1, 2, 1);
2.72 + computeAccessible(b, s, -1, -2, 1);
2.73 + computeAccessible(b, s, 1, -2, 1);
2.74 + break;
2.75 + case PAWN:
2.76 + pawns(b, s);
2.77 + break;
2.78 + }
2.79 + }
2.80 +
2.81 + private static void moveRock(Board b, Square s) {
2.82 + computeAccessible(b, s, 1, 0, 8);
2.83 + computeAccessible(b, s, 0, -1, 8);
2.84 + computeAccessible(b, s, -1, 0, 8);
2.85 + computeAccessible(b, s, 0, 1, 8);
2.86 + }
2.87 +
2.88 + private static void moveBishop(Board b, Square s) {
2.89 + computeAccessible(b, s, 1, 1, 8);
2.90 + computeAccessible(b, s, 1, -1, 8);
2.91 + computeAccessible(b, s, -1, -1, 8);
2.92 + computeAccessible(b, s, -1, 1, 8);
2.93 + }
2.94 +
2.95 + private static void computeAccessible(
2.96 + Board b, Square s, int dx, int dy,
2.97 + int limit
2.98 + ) {
2.99 + int x = s.getX();
2.100 + int y = s.getY();
2.101 +
2.102 + while (limit-- > 0) {
2.103 + x += dx;
2.104 + y += dy;
2.105 + Square next = BoardModel.findSquare(b, (char)x, y);
2.106 + if (next == null) {
2.107 + break;
2.108 + }
2.109 + if (next.getPieceColor() == s.getPieceColor()) {
2.110 + break;
2.111 + }
2.112 + next.setAccessible(true);
2.113 + if (next.getPieceColor() != null) {
2.114 + break;
2.115 + }
2.116 + }
2.117 + }
2.118 +
2.119 + private static void pawns(Board b, Square s) {
2.120 + final boolean white = s.getPieceColor() == BoardModel.ColorType.WHITE;
2.121 + int dy = white ? 1 : -1;
2.122 + Square step = BoardModel.findSquare(b, (char)s.getX(), s.getY() + dy);
2.123 + if (step != null && step.getPiece() == null) {
2.124 + step.setAccessible(true);
2.125 + if ((s.getY() == 2 && white) || (s.getY() == 7 && !white)) {
2.126 + Square nextSTep = BoardModel.findSquare(b, (char)s.getX(), step.getY() + dy);
2.127 + if (nextSTep != null && step.getPiece() == null) {
2.128 + nextSTep.setAccessible(true);
2.129 + }
2.130 + }
2.131 + }
2.132 + }
2.133 +}
3.1 --- a/chess/src/main/webapp/pages/css/chess.css Fri Jul 26 17:13:08 2013 +0200
3.2 +++ b/chess/src/main/webapp/pages/css/chess.css Fri Jul 26 17:14:25 2013 +0200
3.3 @@ -55,6 +55,9 @@
3.4 table.board td.selected {
3.5 background-color: #B000B0;
3.6 }
3.7 +table.board td.accessible {
3.8 + background-color: #00B0B0;
3.9 +}
3.10 .figure {
3.11 cursor: pointer;
3.12 }
3.13 \ No newline at end of file
4.1 --- a/chess/src/test/java/org/apidesign/html/demo/chess/BoardModelTest.java Fri Jul 26 17:13:08 2013 +0200
4.2 +++ b/chess/src/test/java/org/apidesign/html/demo/chess/BoardModelTest.java Fri Jul 26 17:14:25 2013 +0200
4.3 @@ -24,6 +24,7 @@
4.4 package org.apidesign.html.demo.chess;
4.5
4.6 import org.apidesign.html.demo.chess.BoardModel.ColorType;
4.7 +import org.apidesign.html.demo.chess.BoardModel.PieceType;
4.8 import static org.testng.Assert.*;
4.9 import org.testng.annotations.Test;
4.10
4.11 @@ -95,4 +96,28 @@
4.12
4.13 }
4.14
4.15 + @Test public void knightMustMoveToF3() {
4.16 + Board b = BoardModel.createBoard();
4.17 + Square g1 = BoardModel.findSquare(b, 'G', 1);
4.18 + BoardModel.selected(b, g1);
4.19 +
4.20 + Square f3 = BoardModel.findSquare(b, 'F', 3);
4.21 + assertTrue(f3.isAccessible(), "This is a field where knight can move");
4.22 +
4.23 + Square g3 = BoardModel.findSquare(b, 'G', 3);
4.24 + assertFalse(g3.isAccessible(), "Not a place for knight");
4.25 +
4.26 + Square e2 = BoardModel.findSquare(b, 'E', 2);
4.27 + assertFalse(e2.isAccessible(), "Not a place either, occupied");
4.28 +
4.29 + BoardModel.selected(b, g3);
4.30 +
4.31 + assertNull(g3.getPiece(), "No figure was moved");
4.32 + assertTrue(g1.isSelected(), "Original square still selected");
4.33 +
4.34 + BoardModel.selected(b, f3);
4.35 +
4.36 + assertEquals(f3.getPiece(), PieceType.KNIGHT, "Moved");
4.37 + assertFalse(g3.isSelected(), "No longer selected");
4.38 + }
4.39 }