1.1 --- a/minesweeper/src/main/java/org/apidesign/demo/minesweeper/MinesModel.java Fri Jun 27 15:05:03 2014 +0200
1.2 +++ b/minesweeper/src/main/java/org/apidesign/demo/minesweeper/MinesModel.java Fri Jun 27 15:25:21 2014 +0200
1.3 @@ -41,7 +41,7 @@
1.4 })
1.5 public final class MinesModel {
1.6 enum GameState {
1.7 - IN_PROGRESS, WON, LOST;
1.8 + IN_PROGRESS, MARKING_MINE, WON, LOST;
1.9 }
1.10
1.11 @Model(className = "Row", properties = {
1.12 @@ -62,7 +62,7 @@
1.13
1.14 enum SquareType {
1.15 N_0, N_1, N_2, N_3, N_4, N_5, N_6, N_7, N_8,
1.16 - UNKNOWN, EXPLOSION, DISCOVERED;
1.17 + UNKNOWN, EXPLOSION, DISCOVERED, MARKED;
1.18
1.19 final boolean isVisible() {
1.20 return name().startsWith("N_");
1.21 @@ -100,6 +100,12 @@
1.22 model.setState(GameState.LOST);
1.23 }
1.24
1.25 + @Function static void markMine(Mines model) {
1.26 + if (model.getState() == GameState.IN_PROGRESS) {
1.27 + model.setState(GameState.MARKING_MINE);
1.28 + }
1.29 + }
1.30 +
1.31 @ModelOperation static void init(Mines model, int width, int height, int mines) {
1.32 List<Row> rows = model.getRows();
1.33 if (rows.size() != height || rows.get(0).getColumns().size() != width) {
1.34 @@ -224,9 +230,20 @@
1.35 }
1.36
1.37 @Function static void click(Mines model, Square data) {
1.38 + if (model.getState() == GameState.MARKING_MINE) {
1.39 + if (data.getState() == SquareType.UNKNOWN) {
1.40 + data.setState(SquareType.MARKED);
1.41 + }
1.42 + model.setState(GameState.IN_PROGRESS);
1.43 + return;
1.44 + }
1.45 if (model.getState() != GameState.IN_PROGRESS) {
1.46 return;
1.47 }
1.48 + if (data.getState() == SquareType.MARKED) {
1.49 + data.setState(SquareType.UNKNOWN);
1.50 + return;
1.51 + }
1.52 if (data.getState() != SquareType.UNKNOWN) {
1.53 return;
1.54 }
2.1 --- a/minesweeper/src/main/webapp/pages/index.html Fri Jun 27 15:05:03 2014 +0200
2.2 +++ b/minesweeper/src/main/webapp/pages/index.html Fri Jun 27 15:25:21 2014 +0200
2.3 @@ -61,6 +61,10 @@
2.4 <span>✗</span>
2.5 <span class="hidden-phone">Show Mines!</span>
2.6 </button>
2.7 + <button class="btn btn-default navbar-btn" disabled="true" data-bind="disable: !fieldShowing(), click: markMine">
2.8 + <span>⚠</span>
2.9 + <span class="hidden-phone">Mark Mine!</span>
2.10 + </button>
2.11 </div>
2.12 </div>
2.13
3.1 --- a/minesweeper/src/main/webapp/pages/mines.css Fri Jun 27 15:05:03 2014 +0200
3.2 +++ b/minesweeper/src/main/webapp/pages/mines.css Fri Jun 27 15:25:21 2014 +0200
3.3 @@ -55,6 +55,10 @@
3.4 background-color: #D6E4E1;
3.5 cursor: pointer;
3.6 }
3.7 +table.field td.MARKED {
3.8 + background-color: #D6E4E1;
3.9 + cursor: pointer;
3.10 +}
3.11 table.field td.EXPLOSION {
3.12 background-color: #A31E39;
3.13 }
3.14 @@ -71,6 +75,9 @@
3.15 table.field td.DISCOVERED div::after {
3.16 content: "\002714";
3.17 }
3.18 +table.field td.MARKED div::after {
3.19 + content: "\0026a0";
3.20 +}
3.21 table.field td.N_0 div::after {
3.22 content: " ";
3.23 }
4.1 --- a/minesweeper/src/test/java/org/apidesign/demo/minesweeper/MinesModelTest.java Fri Jun 27 15:05:03 2014 +0200
4.2 +++ b/minesweeper/src/test/java/org/apidesign/demo/minesweeper/MinesModelTest.java Fri Jun 27 15:25:21 2014 +0200
4.3 @@ -45,6 +45,21 @@
4.4 assertEquals(cnt, 10, "Ten mines");
4.5 }
4.6
4.7 + @Test public void clickRemovesMarkedSign() {
4.8 + Mines m = new Mines();
4.9 + m.init(10, 10, 10);
4.10 +
4.11 + final Square sq = m.getRows().get(5).getColumns().get(5);
4.12 + MinesModel.markMine(m);
4.13 + MinesModel.click(m, sq);
4.14 +
4.15 + assertEquals(sq.getState(), SquareType.MARKED, "Changed to marked");
4.16 +
4.17 + MinesModel.click(m, sq);
4.18 +
4.19 + assertEquals(sq.getState(), SquareType.UNKNOWN, "Changed back to unknown");
4.20 + }
4.21 +
4.22 @Test public void bombsSet() {
4.23 Mines m = new Mines();
4.24 m.init(10, 10, 0);