jtulach@63
|
1 |
/**
|
jtulach@63
|
2 |
* The MIT License (MIT)
|
jtulach@63
|
3 |
*
|
jtulach@63
|
4 |
* Copyright (C) 2013 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
|
jtulach@63
|
5 |
*
|
jtulach@63
|
6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
jtulach@63
|
7 |
* of this software and associated documentation files (the "Software"), to deal
|
jtulach@63
|
8 |
* in the Software without restriction, including without limitation the rights
|
jtulach@63
|
9 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
jtulach@63
|
10 |
* copies of the Software, and to permit persons to whom the Software is
|
jtulach@63
|
11 |
* furnished to do so, subject to the following conditions:
|
jtulach@63
|
12 |
*
|
jtulach@63
|
13 |
* The above copyright notice and this permission notice shall be included in
|
jtulach@63
|
14 |
* all copies or substantial portions of the Software.
|
jtulach@63
|
15 |
*
|
jtulach@63
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
jtulach@63
|
17 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
jtulach@63
|
18 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
jtulach@63
|
19 |
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
jtulach@63
|
20 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
jtulach@63
|
21 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
jtulach@63
|
22 |
* THE SOFTWARE.
|
jtulach@63
|
23 |
*/
|
jtulach@63
|
24 |
package org.apidesign.demo.minesweeper;
|
jtulach@63
|
25 |
|
jtulach@63
|
26 |
import java.util.ArrayList;
|
jtulach@63
|
27 |
import java.util.List;
|
jtulach@63
|
28 |
import java.util.Random;
|
jtulach@63
|
29 |
import net.java.html.json.ComputedProperty;
|
jtulach@63
|
30 |
import net.java.html.json.Function;
|
jtulach@63
|
31 |
import net.java.html.json.Model;
|
jtulach@63
|
32 |
import net.java.html.json.ModelOperation;
|
jtulach@63
|
33 |
import net.java.html.json.Property;
|
jtulach@63
|
34 |
|
jtulach@63
|
35 |
/** Model of the mine field.
|
jtulach@63
|
36 |
*/
|
jtulach@63
|
37 |
@Model(className = "Mines", properties = {
|
jtulach@63
|
38 |
@Property(name = "state", type = MinesModel.GameState.class),
|
jtulach@63
|
39 |
@Property(name = "rows", type = Row.class, array = true),
|
jtulach@63
|
40 |
})
|
jtulach@63
|
41 |
final class MinesModel {
|
jtulach@63
|
42 |
enum GameState {
|
jtulach@63
|
43 |
IN_PROGRESS, WON, LOST;
|
jtulach@63
|
44 |
}
|
jtulach@63
|
45 |
|
jtulach@63
|
46 |
@Model(className = "Row", properties = {
|
jtulach@63
|
47 |
@Property(name = "columns", type = Square.class, array = true)
|
jtulach@63
|
48 |
})
|
jtulach@63
|
49 |
static class RowModel {
|
jtulach@63
|
50 |
}
|
jtulach@63
|
51 |
|
jtulach@63
|
52 |
@Model(className = "Square", properties = {
|
jtulach@63
|
53 |
@Property(name = "state", type = SquareType.class),
|
jtulach@63
|
54 |
@Property(name = "mine", type = boolean.class)
|
jtulach@63
|
55 |
})
|
jtulach@63
|
56 |
static class SquareModel {
|
jtulach@63
|
57 |
@ComputedProperty static String text(SquareType state) {
|
jtulach@63
|
58 |
if (state == null) return " ";
|
jtulach@63
|
59 |
switch (state) {
|
jtulach@63
|
60 |
case MINE: return "B";
|
jtulach@63
|
61 |
case UNKNOWN: return "?";
|
jtulach@63
|
62 |
case N_0: return " ";
|
jtulach@63
|
63 |
}
|
jtulach@63
|
64 |
return "" + state.ordinal();
|
jtulach@63
|
65 |
}
|
jtulach@63
|
66 |
}
|
jtulach@63
|
67 |
|
jtulach@63
|
68 |
enum SquareType {
|
jtulach@63
|
69 |
N_0, N_1, N_2, N_3, N_4, N_5, N_6, N_7, N_8,
|
jtulach@63
|
70 |
UNKNOWN, MINE
|
jtulach@63
|
71 |
}
|
jtulach@63
|
72 |
|
jtulach@63
|
73 |
@ModelOperation static void init(Mines model, int width, int height, int mines) {
|
jtulach@63
|
74 |
List<Row> rows = new ArrayList<Row>(height);
|
jtulach@63
|
75 |
for (int y = 0; y < height; y++) {
|
jtulach@63
|
76 |
Square[] columns = new Square[width];
|
jtulach@63
|
77 |
for (int x = 0; x < width; x++) {
|
jtulach@63
|
78 |
columns[x] = new Square(SquareType.UNKNOWN, false);
|
jtulach@63
|
79 |
}
|
jtulach@63
|
80 |
rows.add(new Row(columns));
|
jtulach@63
|
81 |
}
|
jtulach@63
|
82 |
|
jtulach@63
|
83 |
Random r = new Random();
|
jtulach@63
|
84 |
while (mines > 0) {
|
jtulach@63
|
85 |
int x = r.nextInt(width);
|
jtulach@63
|
86 |
int y = r.nextInt(height);
|
jtulach@63
|
87 |
final Square s = rows.get(y).getColumns().get(x);
|
jtulach@63
|
88 |
if (s.isMine()) {
|
jtulach@63
|
89 |
continue;
|
jtulach@63
|
90 |
}
|
jtulach@63
|
91 |
s.setMine(true);
|
jtulach@63
|
92 |
mines--;
|
jtulach@63
|
93 |
}
|
jtulach@63
|
94 |
|
jtulach@63
|
95 |
model.setState(GameState.IN_PROGRESS);
|
jtulach@63
|
96 |
model.getRows().clear();
|
jtulach@63
|
97 |
model.getRows().addAll(rows);
|
jtulach@63
|
98 |
}
|
jtulach@63
|
99 |
|
jtulach@63
|
100 |
static void showAllBombs(Mines model) {
|
jtulach@63
|
101 |
for (Row row : model.getRows()) {
|
jtulach@63
|
102 |
for (Square square : row.getColumns()) {
|
jtulach@63
|
103 |
if (square.isMine()) {
|
jtulach@63
|
104 |
square.setState(SquareType.MINE);
|
jtulach@63
|
105 |
}
|
jtulach@63
|
106 |
}
|
jtulach@63
|
107 |
}
|
jtulach@63
|
108 |
}
|
jtulach@63
|
109 |
|
jtulach@63
|
110 |
@Function static void click(Mines model, Square data) {
|
jtulach@63
|
111 |
if (model.getState() != GameState.IN_PROGRESS) {
|
jtulach@63
|
112 |
return;
|
jtulach@63
|
113 |
}
|
jtulach@63
|
114 |
|
jtulach@63
|
115 |
switch (data.getState()) {
|
jtulach@63
|
116 |
case UNKNOWN:
|
jtulach@63
|
117 |
if (data.isMine()) {
|
jtulach@63
|
118 |
showAllBombs(model);
|
jtulach@63
|
119 |
model.setState(GameState.LOST);
|
jtulach@63
|
120 |
} else {
|
jtulach@63
|
121 |
data.setState(SquareType.N_0);
|
jtulach@63
|
122 |
}
|
jtulach@63
|
123 |
break;
|
jtulach@63
|
124 |
}
|
jtulach@63
|
125 |
}
|
jtulach@63
|
126 |
}
|