jtulach@35
|
1 |
/*
|
jaroslav@264
|
2 |
* Quoridor server and related libraries
|
jaroslav@264
|
3 |
* Copyright (C) 2009-2010 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
|
jtulach@35
|
4 |
*
|
jaroslav@264
|
5 |
* This program is free software: you can redistribute it and/or modify
|
jaroslav@264
|
6 |
* it under the terms of the GNU General Public License as published by
|
jaroslav@264
|
7 |
* the Free Software Foundation, either version 3 of the License.
|
jtulach@35
|
8 |
*
|
jaroslav@264
|
9 |
* This program is distributed in the hope that it will be useful,
|
jaroslav@264
|
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
jaroslav@264
|
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
jaroslav@264
|
12 |
* GNU General Public License for more details.
|
jtulach@35
|
13 |
*
|
jaroslav@264
|
14 |
* You should have received a copy of the GNU General Public License
|
jaroslav@264
|
15 |
* along with this program. Look for COPYING file in the top folder.
|
jaroslav@264
|
16 |
* If not, see http://www.gnu.org/licenses/.
|
jtulach@35
|
17 |
*/
|
jtulach@35
|
18 |
|
jtulach@35
|
19 |
package cz.xelfi.quoridor.webidor;
|
jtulach@35
|
20 |
|
jtulach@35
|
21 |
import cz.xelfi.quoridor.Board;
|
jtulach@35
|
22 |
import cz.xelfi.quoridor.IllegalPositionException;
|
jtulach@35
|
23 |
import cz.xelfi.quoridor.Move;
|
jtulach@35
|
24 |
import cz.xelfi.quoridor.Player;
|
jtulach@37
|
25 |
import java.util.ArrayList;
|
jtulach@78
|
26 |
import java.util.Date;
|
jtulach@37
|
27 |
import java.util.List;
|
jtulach@35
|
28 |
import javax.xml.bind.annotation.XmlAccessType;
|
jtulach@35
|
29 |
import javax.xml.bind.annotation.XmlAccessorType;
|
jtulach@35
|
30 |
import javax.xml.bind.annotation.XmlAttribute;
|
jaroslav@48
|
31 |
import javax.xml.bind.annotation.XmlElement;
|
jaroslav@115
|
32 |
import javax.xml.bind.annotation.XmlElementWrapper;
|
jtulach@35
|
33 |
import javax.xml.bind.annotation.XmlRootElement;
|
jaroslav@48
|
34 |
import javax.xml.bind.annotation.adapters.XmlAdapter;
|
jaroslav@48
|
35 |
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
|
jtulach@35
|
36 |
|
jtulach@35
|
37 |
/**
|
jtulach@35
|
38 |
*
|
jtulach@35
|
39 |
* @author Jaroslav Tulach <jtulach@netbeans.org>
|
jtulach@35
|
40 |
*/
|
jtulach@35
|
41 |
@XmlRootElement
|
jtulach@35
|
42 |
@XmlAccessorType(XmlAccessType.FIELD)
|
jaroslav@48
|
43 |
public final class Game extends Object {
|
jaroslav@48
|
44 |
@XmlElement
|
jaroslav@48
|
45 |
private GameId id;
|
jtulach@54
|
46 |
@XmlElement
|
jaroslav@48
|
47 |
@XmlJavaTypeAdapter(BoardAdapter.class)
|
jaroslav@48
|
48 |
private Board board;
|
jaroslav@115
|
49 |
@XmlElementWrapper(name="moves")
|
jaroslav@115
|
50 |
@XmlElement(name="item")
|
jaroslav@115
|
51 |
private List<CommentedMove> moves;
|
jaroslav@100
|
52 |
private Integer move;
|
jtulach@35
|
53 |
|
jtulach@35
|
54 |
Game() {
|
jtulach@35
|
55 |
}
|
jtulach@35
|
56 |
|
jtulach@35
|
57 |
public Game(String first, String second) {
|
jaroslav@48
|
58 |
this.id = new GameId(first, second);
|
jaroslav@53
|
59 |
this.board = Board.empty();
|
jtulach@37
|
60 |
}
|
jtulach@37
|
61 |
|
jaroslav@48
|
62 |
public Game(GameId id) {
|
jtulach@37
|
63 |
this.id = id;
|
jaroslav@53
|
64 |
this.board = Board.empty();
|
jtulach@35
|
65 |
}
|
jtulach@35
|
66 |
|
jaroslav@48
|
67 |
public GameId getId() {
|
jtulach@35
|
68 |
return id;
|
jtulach@35
|
69 |
}
|
jaroslav@48
|
70 |
|
jtulach@35
|
71 |
public Board getBoard() {
|
jtulach@35
|
72 |
return board;
|
jtulach@35
|
73 |
}
|
jtulach@35
|
74 |
|
jaroslav@55
|
75 |
@XmlAttribute
|
jaroslav@55
|
76 |
final String getCurrentPlayer() {
|
jaroslav@178
|
77 |
Player w = board.getWinner();
|
jaroslav@178
|
78 |
if(w==null){
|
jaroslav@178
|
79 |
if (board.getCurrentPlayer() == board.getPlayers().get(0)) {
|
jaroslav@178
|
80 |
return id.getWhite();
|
jaroslav@178
|
81 |
} else {
|
jaroslav@178
|
82 |
return id.getBlack();
|
jaroslav@178
|
83 |
}
|
jaroslav@178
|
84 |
}else{
|
jaroslav@178
|
85 |
if (w == board.getPlayers().get(0)) {
|
jaroslav@178
|
86 |
return id.getWhite();
|
jaroslav@178
|
87 |
} else {
|
jaroslav@178
|
88 |
return id.getBlack();
|
jaroslav@178
|
89 |
}
|
jaroslav@55
|
90 |
}
|
jaroslav@55
|
91 |
}
|
jaroslav@55
|
92 |
|
jtulach@79
|
93 |
public void apply(String player, Move m, Date when) throws IllegalPositionException {
|
jtulach@35
|
94 |
Player p = null;
|
jaroslav@48
|
95 |
if (id.getWhite().equals(player)) {
|
jtulach@35
|
96 |
p = getBoard().getPlayers().get(0);
|
jtulach@35
|
97 |
} else {
|
jaroslav@48
|
98 |
if (id.getBlack().equals(player)) {
|
jtulach@35
|
99 |
p = getBoard().getPlayers().get(1);
|
jtulach@35
|
100 |
}
|
jtulach@35
|
101 |
}
|
jtulach@35
|
102 |
if (p != getBoard().getCurrentPlayer()) {
|
jtulach@35
|
103 |
throw new IllegalArgumentException("Wrong player: " + player);
|
jtulach@35
|
104 |
}
|
jtulach@35
|
105 |
|
jtulach@35
|
106 |
board = getBoard().apply(m);
|
jtulach@79
|
107 |
if (when == null) {
|
jtulach@79
|
108 |
when = new Date(id.getModified());
|
jtulach@79
|
109 |
}
|
jtulach@164
|
110 |
final GameStatus status = GameStatus.valueOf(board);
|
jaroslav@131
|
111 |
id = new GameId(
|
jaroslav@131
|
112 |
id.getId(), id.getWhite(), id.getBlack(),
|
jtulach@164
|
113 |
new Date(id.getStarted()), when, status,
|
jtulach@164
|
114 |
id.getComments(), !status.isInProgress());
|
jaroslav@115
|
115 |
getMoves().add(new CommentedMove(m, getMoves().size() + 1));
|
jtulach@37
|
116 |
}
|
jtulach@37
|
117 |
|
jaroslav@115
|
118 |
public void comment(String player, String comment, Date date) {
|
jaroslav@115
|
119 |
Note n = new Note(comment, date, player);
|
jaroslav@131
|
120 |
id = new GameId(
|
jaroslav@131
|
121 |
id.getId(), id.getWhite(), id.getBlack(),
|
jaroslav@131
|
122 |
new Date(id.getStarted()), new Date(id.getModified()),
|
jtulach@164
|
123 |
GameStatus.valueOf(board), id.getComments() + 1, id.isFinished()
|
jaroslav@131
|
124 |
);
|
jaroslav@115
|
125 |
getMoves().get(getMoves().size() - 1).addNote(n);
|
jaroslav@115
|
126 |
}
|
jaroslav@115
|
127 |
|
jaroslav@115
|
128 |
|
jaroslav@115
|
129 |
public List<CommentedMove> getMoves() {
|
jtulach@37
|
130 |
if (moves == null) {
|
jaroslav@115
|
131 |
moves = new ArrayList<CommentedMove>();
|
jtulach@37
|
132 |
}
|
jtulach@37
|
133 |
return moves;
|
jtulach@35
|
134 |
}
|
jaroslav@48
|
135 |
|
jaroslav@100
|
136 |
@XmlAttribute
|
jaroslav@100
|
137 |
public int getCurrentMove() {
|
jaroslav@100
|
138 |
return move == null ? getMoves().size() : move;
|
jaroslav@100
|
139 |
}
|
jaroslav@100
|
140 |
|
jaroslav@100
|
141 |
public Game snapshot(int move) throws IllegalPositionException {
|
jaroslav@100
|
142 |
Board b = Board.empty();
|
jaroslav@100
|
143 |
int cnt = 0;
|
jaroslav@115
|
144 |
for (CommentedMove m : getMoves()) {
|
jaroslav@100
|
145 |
if (move-- <= 0) {
|
jaroslav@100
|
146 |
break;
|
jaroslav@100
|
147 |
}
|
jaroslav@115
|
148 |
b = b.apply(m.getMove());
|
jaroslav@100
|
149 |
cnt++;
|
jaroslav@100
|
150 |
}
|
jaroslav@100
|
151 |
|
jaroslav@100
|
152 |
Game g = new Game(
|
jaroslav@100
|
153 |
new GameId(
|
jaroslav@100
|
154 |
id.getId(), id.getWhite(), id.getBlack(),
|
jaroslav@100
|
155 |
new Date(id.getStarted()), new Date(id.getModified()),
|
jtulach@164
|
156 |
GameStatus.history, id.getComments(), id.isFinished()
|
jaroslav@100
|
157 |
)
|
jaroslav@100
|
158 |
);
|
jaroslav@100
|
159 |
g.board = b;
|
jaroslav@100
|
160 |
g.move = cnt;
|
jaroslav@115
|
161 |
g.moves = new ArrayList<CommentedMove>(getMoves());
|
jaroslav@100
|
162 |
return g;
|
jaroslav@100
|
163 |
}
|
jaroslav@115
|
164 |
/*
|
jaroslav@115
|
165 |
private static final class MoveAdapter extends XmlAdapter<CommentedMove[],List<Move>> {
|
jaroslav@48
|
166 |
@Override
|
jaroslav@115
|
167 |
public List<Move> unmarshal(CommentedMove[] arr) throws Exception {
|
jaroslav@48
|
168 |
List<Move> res = new ArrayList<Move>();
|
jaroslav@52
|
169 |
if (arr != null) {
|
jaroslav@115
|
170 |
for (CommentedMove v : arr) {
|
jaroslav@60
|
171 |
res.add(Move.valueOf(v.move));
|
jaroslav@52
|
172 |
}
|
jaroslav@48
|
173 |
}
|
jaroslav@48
|
174 |
return res;
|
jaroslav@48
|
175 |
}
|
jaroslav@48
|
176 |
|
jaroslav@48
|
177 |
@Override
|
jaroslav@115
|
178 |
public CommentedMove[] marshal(List<Move> arr) throws Exception {
|
jaroslav@115
|
179 |
List<CommentedMove> res = new ArrayList<CommentedMove>();
|
jaroslav@52
|
180 |
if (arr != null) {
|
jaroslav@60
|
181 |
int index = 0;
|
jaroslav@52
|
182 |
for (Move m : arr) {
|
jaroslav@115
|
183 |
res.add(new CommentedMove(m.toString(), ++index));
|
jaroslav@52
|
184 |
}
|
jaroslav@48
|
185 |
}
|
jaroslav@115
|
186 |
return res.toArray(new CommentedMove[0]);
|
jaroslav@48
|
187 |
}
|
jaroslav@48
|
188 |
} // end of MoveAdapter
|
jaroslav@115
|
189 |
*/
|
jaroslav@48
|
190 |
private static final class BoardAdapter extends XmlAdapter<String,Board> {
|
jaroslav@48
|
191 |
|
jaroslav@48
|
192 |
@Override
|
jaroslav@48
|
193 |
public Board unmarshal(String v) throws Exception {
|
jaroslav@52
|
194 |
return v == null ? null : Board.valueOf(v);
|
jaroslav@178
|
195 |
// return v == null ? null : new Board(v);
|
jaroslav@48
|
196 |
}
|
jaroslav@48
|
197 |
|
jaroslav@48
|
198 |
@Override
|
jaroslav@48
|
199 |
public String marshal(Board v) throws Exception {
|
jaroslav@52
|
200 |
return v == null ? null : v.toString();
|
jaroslav@178
|
201 |
// return v == null ? null : Board.board2HashCode(v);
|
jaroslav@48
|
202 |
}
|
jaroslav@48
|
203 |
|
jaroslav@48
|
204 |
}
|
jtulach@35
|
205 |
}
|